--- /dev/null
+require File.dirname(__FILE__) + '/../test_helper'
+
+require 'dog'
+require 'wild_boar'
+require 'frog'
+require 'cat'
+require 'kitten'
+require 'aquatic/whale'
+require 'aquatic/fish'
+require 'aquatic/pupils_whale'
+require 'beautiful_fight_relationship'
+
+class PolymorphTest < Test::Unit::TestCase
+
+ set_fixture_class :bow_wows => Dog
+ set_fixture_class :keep_your_enemies_close => BeautifulFightRelationship
+ set_fixture_class :whales => Aquatic::Whale
+ set_fixture_class :fish => Aquatic::Fish
+ set_fixture_class :little_whale_pupils => Aquatic::PupilsWhale
+
+ fixtures :cats, :bow_wows, :frogs, :wild_boars, :eaters_foodstuffs, :petfoods,
+ :fish, :whales, :little_whale_pupils, :keep_your_enemies_close, :people
+
+ def setup
+ @association_error = ActiveRecord::Associations::PolymorphicError
+ @kibbles = Petfood.find(1)
+ @bits = Petfood.find(2)
+ @shamu = Aquatic::Whale.find(1)
+ @swimmy = Aquatic::Fish.find(1)
+ @rover = Dog.find(1)
+ @spot = Dog.find(2)
+ @puma = WildBoar.find(1)
+ @chloe = Kitten.find(1)
+ @alice = Kitten.find(2)
+ @toby = Tabby.find(3)
+ @froggy = Frog.find(1)
+
+ @join_count = EatersFoodstuff.count
+ @kibbles_eaters_count = @kibbles.eaters.size
+ @bits_eaters_count = @bits.eaters.size
+
+ @double_join_count = BeautifulFightRelationship.count
+ @alice_enemies_count = @alice.enemies.size
+ end
+
+ def test_all_relationship_validities
+ # q = []
+ # ObjectSpace.each_object(Class){|c| q << c if c.ancestors.include? ActiveRecord::Base }
+ # q.each{|c| puts "#{c.name}.reflect_on_all_associations.map &:check_validity! "}
+ Petfood.reflect_on_all_associations.map &:check_validity!
+ Tabby.reflect_on_all_associations.map &:check_validity!
+ Kitten.reflect_on_all_associations.map &:check_validity!
+ Dog.reflect_on_all_associations.map &:check_validity!
+ Canine.reflect_on_all_associations.map &:check_validity!
+ Aquatic::Fish.reflect_on_all_associations.map &:check_validity!
+ EatersFoodstuff.reflect_on_all_associations.map &:check_validity!
+ WildBoar.reflect_on_all_associations.map &:check_validity!
+ Frog.reflect_on_all_associations.map &:check_validity!
+ Cat.reflect_on_all_associations.map &:check_validity!
+ BeautifulFightRelationship.reflect_on_all_associations.map &:check_validity!
+ Person.reflect_on_all_associations.map &:check_validity!
+ Parentship.reflect_on_all_associations.map &:check_validity!
+ Aquatic::Whale.reflect_on_all_associations.map &:check_validity!
+ Aquatic::PupilsWhale.reflect_on_all_associations.map &:check_validity!
+ end
+
+ def test_assignment
+ assert @kibbles.eaters.blank?
+ assert @kibbles.eaters.push(Cat.find_by_name('Chloe'))
+ assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
+
+ @kibbles.reload
+ assert_equal @kibbles_eaters_count, @kibbles.eaters.count
+ end
+
+ def test_duplicate_assignment
+ # try to add a duplicate item when :ignore_duplicates is false
+ @kibbles.eaters.push(@alice)
+ assert @kibbles.eaters.include?(@alice)
+ @kibbles.eaters.push(@alice)
+ assert_equal @kibbles_eaters_count + 2, @kibbles.eaters.count
+ assert_equal @join_count + 2, EatersFoodstuff.count
+ end
+
+ def test_create_and_push
+ assert @kibbles.eaters.push(@spot)
+ assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
+ assert @kibbles.eaters << @rover
+ assert @kibbles.eaters << Kitten.create(:name => "Miranda")
+ assert_equal @kibbles_eaters_count += 2, @kibbles.eaters.length
+
+ @kibbles.reload
+ assert_equal @kibbles_eaters_count, @kibbles.eaters.length
+
+ # test that ids and new flags were set appropriately
+ assert_not_nil @kibbles.eaters[0].id
+ assert !@kibbles.eaters[1].new_record?
+ end
+
+ def test_reload
+ assert @kibbles.reload
+ assert @kibbles.eaters.reload
+ end
+
+ def test_add_join_record
+ assert_equal Kitten, @chloe.class
+ assert join = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @chloe.id, :eater_type => @chloe.class.name )
+ assert join.save!
+ assert join.id
+ assert_equal @join_count + 1, EatersFoodstuff.count
+
+ #assert_equal @bits_eaters_count, @bits.eaters.size # Doesn't behave this way on latest edge anymore
+ assert_equal @bits_eaters_count + 1, @bits.eaters.count # SQL
+
+ # reload; is the new association there?
+ assert @bits.eaters.reload
+ assert @bits.eaters.include?(@chloe)
+ end
+
+ def test_build_join_record_on_association
+ assert_equal Kitten, @chloe.class
+ assert join = @chloe.eaters_foodstuffs.build(:foodstuff => @bits)
+ # assert_equal join.eater_type, @chloe.class.name # will be STI parent type
+ assert join.save!
+ assert join.id
+ assert_equal @join_count + 1, EatersFoodstuff.count
+
+ assert @bits.eaters.reload
+ assert @bits.eaters.include?(@chloe)
+ end
+
+# not supporting this, since has_many :through doesn't support it either
+# def test_add_unsaved
+# # add an unsaved item
+# assert @bits.eaters << Kitten.new(:name => "Bridget")
+# assert_nil Kitten.find_by_name("Bridget")
+# assert_equal @bits_eaters_count + 1, @bits.eaters.count
+#
+# assert @bits.save
+# @bits.reload
+# assert_equal @bits_eaters_count + 1, @bits.eaters.count
+#
+# end
+
+ def test_self_reference
+ assert @kibbles.eaters << @bits
+ assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
+ assert @kibbles.eaters.include?(@bits)
+ @kibbles.reload
+ assert @kibbles.foodstuffs_of_eaters.blank?
+
+ @bits.reload
+ assert @bits.foodstuffs_of_eaters.include?(@kibbles)
+ assert_equal [@kibbles], @bits.foodstuffs_of_eaters
+ end
+
+ def test_remove
+ assert @kibbles.eaters << @chloe
+ @kibbles.reload
+ assert @kibbles.eaters.delete(@kibbles.eaters[0])
+ assert_equal @kibbles_eaters_count, @kibbles.eaters.count
+ end
+
+ def test_destroy
+ assert @kibbles.eaters.push(@chloe)
+ @kibbles.reload
+ assert @kibbles.eaters.length > 0
+ assert @kibbles.eaters[0].destroy
+ @kibbles.reload
+ assert_equal @kibbles_eaters_count, @kibbles.eaters.count
+ end
+
+ def test_clear
+ @kibbles.eaters << [@chloe, @spot, @rover]
+ @kibbles.reload
+ assert @kibbles.eaters.clear.blank?
+ assert @kibbles.eaters.blank?
+ @kibbles.reload
+ assert @kibbles.eaters.blank?
+ end
+
+ def test_individual_collections
+ assert @kibbles.eaters.push(@chloe)
+ # check if individual collections work
+ assert_equal @kibbles.eater_kittens.length, 1
+ assert @kibbles.eater_dogs
+ assert 1, @rover.eaters_foodstuffs.count
+ end
+
+ def test_individual_collections_push
+ assert_equal [@chloe], (@kibbles.eater_kittens << @chloe)
+ @kibbles.reload
+ assert @kibbles.eaters.include?(@chloe)
+ assert @kibbles.eater_kittens.include?(@chloe)
+ assert !@kibbles.eater_dogs.include?(@chloe)
+ end
+
+ def test_individual_collections_delete
+ @kibbles.eaters << [@chloe, @spot, @rover]
+ @kibbles.reload
+ assert_equal [@chloe], @kibbles.eater_kittens.delete(@chloe)
+ assert @kibbles.eater_kittens.empty?
+ @kibbles.eater_kittens.delete(@chloe) # what should this return?
+
+ @kibbles.reload
+ assert @kibbles.eater_kittens.empty?
+ assert @kibbles.eater_dogs.include?(@spot)
+ end
+
+ def test_individual_collections_clear
+ @kibbles.eaters << [@chloe, @spot, @rover]
+ @kibbles.reload
+
+ assert_equal [], @kibbles.eater_kittens.clear
+ assert @kibbles.eater_kittens.empty?
+ assert_equal 2, @kibbles.eaters.size
+
+ assert @kibbles.eater_kittens.empty?
+ assert_equal 2, @kibbles.eaters.size
+ assert !@kibbles.eater_kittens.include?(@chloe)
+ assert !@kibbles.eaters.include?(@chloe)
+
+ @kibbles.reload
+ assert @kibbles.eater_kittens.empty?
+ assert_equal 2, @kibbles.eaters.size
+ assert !@kibbles.eater_kittens.include?(@chloe)
+ assert !@kibbles.eaters.include?(@chloe)
+ end
+
+ def test_childrens_individual_collections
+ assert Cat.find_by_name('Chloe').eaters_foodstuffs
+ assert @kibbles.eaters_foodstuffs
+ end
+
+ def test_self_referential_join_tables
+ # check that the self-reference join tables go the right ways
+ assert_equal @kibbles_eaters_count, @kibbles.eaters_foodstuffs.count
+ assert_equal @kibbles.eaters_foodstuffs.count, @kibbles.eaters_foodstuffs_as_child.count
+ end
+
+ def test_dependent
+ assert @kibbles.eaters << @chloe
+ @kibbles.reload
+
+ # delete ourself and see if :dependent was obeyed
+ dependent_rows = @kibbles.eaters_foodstuffs
+ assert_equal dependent_rows.length, @kibbles.eaters.count
+ @join_count = EatersFoodstuff.count
+
+ @kibbles.destroy
+ assert_equal @join_count - dependent_rows.length, EatersFoodstuff.count
+ assert_equal 0, EatersFoodstuff.find(:all, :conditions => ['foodstuff_id = ?', 1] ).length
+ end
+
+ def test_normal_callbacks
+ assert @rover.respond_to?(:after_initialize)
+ assert @rover.respond_to?(:after_find)
+ assert @rover.after_initialize_test
+ assert @rover.after_find_test
+ end
+
+ def test_model_callbacks_not_overridden_by_plugin_callbacks
+ assert 0, @bits.eaters.count
+ assert @bits.eaters.push(@rover)
+ @bits.save
+ @bits2 = Petfood.find_by_name("Bits")
+ @bits.reload
+ assert rover = @bits2.eaters.select { |x| x.name == "Rover" }[0]
+ assert rover.after_initialize_test
+ assert rover.after_find_test
+ end
+
+ def test_number_of_join_records
+ assert EatersFoodstuff.create(:foodstuff_id => 1, :eater_id => 1, :eater_type => "Cat")
+ @join_count = EatersFoodstuff.count
+ assert @join_count > 0
+ end
+
+ def test_number_of_regular_records
+ dogs = Dog.count
+ assert Dog.new(:name => "Auggie").save!
+ assert dogs + 1, Dog.count
+ end
+
+ def test_attributes_come_through_when_child_has_underscore_in_table_name
+ join = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @puma.id, :eater_type => @puma.class.name)
+ join.save!
+
+ @bits.eaters.reload
+
+ assert_equal "Puma", @puma.name
+ assert_equal "Puma", @bits.eaters.first.name
+ end
+
+
+ def test_before_save_on_join_table_is_not_clobbered_by_sti_base_class_fix
+ assert @kibbles.eaters << @chloe
+ assert_equal 3, @kibbles.eaters_foodstuffs.first.some_attribute
+ end
+
+ def test_sti_type_counts_are_correct
+ @kibbles.eaters << [@chloe, @alice, @toby]
+ assert_equal 2, @kibbles.eater_kittens.count
+ assert_equal 1, @kibbles.eater_tabbies.count
+ assert !@kibbles.respond_to?(:eater_cats)
+ end
+
+
+ def test_creating_namespaced_relationship
+ assert @shamu.aquatic_pupils.empty?
+ @shamu.aquatic_pupils << @swimmy
+ assert_equal 1, @shamu.aquatic_pupils.length
+ @shamu.reload
+ assert_equal 1, @shamu.aquatic_pupils.length
+ end
+
+ def test_namespaced_polymorphic_collection
+ @shamu.aquatic_pupils << @swimmy
+ assert @shamu.aquatic_pupils.include?(@swimmy)
+ @shamu.reload
+ assert @shamu.aquatic_pupils.include?(@swimmy)
+
+ @shamu.aquatic_pupils << @spot
+ assert @shamu.dogs.include?(@spot)
+ assert @shamu.aquatic_pupils.include?(@swimmy)
+ assert_equal @swimmy, @shamu.aquatic_fish.first
+ assert_equal 10, @shamu.aquatic_fish.first.speed
+ end
+
+ def test_deleting_namespaced_relationship
+ @shamu.aquatic_pupils << @swimmy
+ @shamu.aquatic_pupils << @spot
+
+ @shamu.reload
+ @shamu.aquatic_pupils.delete @spot
+ assert !@shamu.dogs.include?(@spot)
+ assert !@shamu.aquatic_pupils.include?(@spot)
+ assert_equal 1, @shamu.aquatic_pupils.length
+ end
+
+ def test_unrenamed_parent_of_namespaced_child
+ @shamu.aquatic_pupils << @swimmy
+ assert_equal [@shamu], @swimmy.whales
+ end
+
+ def test_empty_double_collections
+ assert @puma.enemies.empty?
+ assert @froggy.protectors.empty?
+ assert @alice.enemies.empty?
+ assert @spot.protectors.empty?
+ assert @alice.beautiful_fight_relationships_as_enemy.empty?
+ assert @alice.beautiful_fight_relationships_as_protector.empty?
+ assert @alice.beautiful_fight_relationships.empty?
+ end
+
+ def test_double_collection_assignment
+ @alice.enemies << @spot
+ @alice.reload
+ @spot.reload
+ assert @spot.protectors.include?(@alice)
+ assert @alice.enemies.include?(@spot)
+ assert !@alice.protectors.include?(@alice)
+ assert_equal 1, @alice.beautiful_fight_relationships_as_protector.size
+ assert_equal 0, @alice.beautiful_fight_relationships_as_enemy.size
+ assert_equal 1, @alice.beautiful_fight_relationships.size
+
+ # self reference
+ assert_equal 1, @alice.enemies.length
+ @alice.enemies.push @alice
+ assert @alice.enemies.include?(@alice)
+ assert_equal 2, @alice.enemies.length
+ @alice.reload
+ assert_equal 2, @alice.beautiful_fight_relationships_as_protector.size
+ assert_equal 1, @alice.beautiful_fight_relationships_as_enemy.size
+ assert_equal 3, @alice.beautiful_fight_relationships.size
+ end
+
+ def test_double_collection_build_join_record_on_association
+
+ join = @alice.beautiful_fight_relationships_as_protector.build(:enemy => @spot)
+
+ assert_equal @alice.class.base_class.name, join.protector_type
+ assert_nothing_raised { join.save! }
+
+ assert join.id
+ assert_equal @double_join_count + 1, BeautifulFightRelationship.count
+
+ assert @alice.enemies.reload
+ assert @alice.enemies.include?(@spot)
+ end
+
+ def test_double_dependency_injection
+# breakpoint
+ end
+
+ def test_double_collection_deletion
+ @alice.enemies << @spot
+ @alice.reload
+ assert @alice.enemies.include?(@spot)
+ @alice.enemies.delete(@spot)
+ assert !@alice.enemies.include?(@spot)
+ assert @alice.enemies.empty?
+ @alice.reload
+ assert !@alice.enemies.include?(@spot)
+ assert @alice.enemies.empty?
+ assert_equal 0, @alice.beautiful_fight_relationships.size
+ end
+
+ def test_double_collection_deletion_from_opposite_side
+ @alice.protectors << @puma
+ @alice.reload
+ assert @alice.protectors.include?(@puma)
+ @alice.protectors.delete(@puma)
+ assert !@alice.protectors.include?(@puma)
+ assert @alice.protectors.empty?
+ @alice.reload
+ assert !@alice.protectors.include?(@puma)
+ assert @alice.protectors.empty?
+ assert_equal 0, @alice.beautiful_fight_relationships.size
+ end
+
+ def test_individual_collections_created_for_double_relationship
+ assert @alice.dogs.empty?
+ @alice.enemies << @spot
+
+ assert @alice.enemies.include?(@spot)
+ assert !@alice.kittens.include?(@alice)
+
+ assert !@alice.dogs.include?(@spot)
+ @alice.reload
+ assert @alice.dogs.include?(@spot)
+ assert !WildBoar.find(@alice.id).dogs.include?(@spot) # make sure the parent type is checked
+ end
+
+ def test_individual_collections_created_for_double_relationship_from_opposite_side
+ assert @alice.wild_boars.empty?
+ @alice.protectors << @puma
+
+ assert @alice.protectors.include?(@puma)
+ assert !@alice.wild_boars.include?(@puma)
+ @alice.reload
+ assert @alice.wild_boars.include?(@puma)
+
+ assert !Dog.find(@alice.id).wild_boars.include?(@puma) # make sure the parent type is checked
+ end
+
+ def test_self_referential_individual_collections_created_for_double_relationship
+ @alice.enemies << @alice
+ @alice.reload
+ assert @alice.enemy_kittens.include?(@alice)
+ assert @alice.protector_kittens.include?(@alice)
+ assert @alice.kittens.include?(@alice)
+ assert_equal 2, @alice.kittens.size
+
+ @alice.enemies << (@chloe = Kitten.find_by_name('Chloe'))
+ @alice.reload
+ assert @alice.enemy_kittens.include?(@chloe)
+ assert !@alice.protector_kittens.include?(@chloe)
+ assert @alice.kittens.include?(@chloe)
+ assert_equal 3, @alice.kittens.size
+ end
+
+ def test_child_of_polymorphic_join_can_reach_parent
+ @alice.enemies << @spot
+ @alice.reload
+ assert @spot.protectors.include?(@alice)
+ end
+
+ def test_double_collection_deletion_from_child_polymorphic_join
+ @alice.enemies << @spot
+ @spot.protectors.delete(@alice)
+ assert !@spot.protectors.include?(@alice)
+ @alice.reload
+ assert !@alice.enemies.include?(@spot)
+ BeautifulFightRelationship.create(:protector_id => 2, :protector_type => "Dog", :enemy_id => @spot.id, :enemy_type => @spot.class.name)
+ @alice.enemies << @spot
+ @spot.protectors.delete(@alice)
+ assert !@spot.protectors.include?(@alice)
+ end
+
+ def test_collection_query_on_unsaved_record
+ assert Dog.new.enemies.empty?
+ assert Dog.new.foodstuffs_of_eaters.empty?
+ end
+
+ def test_double_individual_collections_push
+ assert_equal [@chloe], (@spot.protector_kittens << @chloe)
+ @spot.reload
+ assert @spot.protectors.include?(@chloe)
+ assert @spot.protector_kittens.include?(@chloe)
+ assert !@spot.protector_dogs.include?(@chloe)
+
+ assert_equal [@froggy], (@spot.frogs << @froggy)
+ @spot.reload
+ assert @spot.enemies.include?(@froggy)
+ assert @spot.frogs.include?(@froggy)
+ assert !@spot.enemy_dogs.include?(@froggy)
+ end
+
+ def test_double_individual_collections_delete
+ @spot.protectors << [@chloe, @puma]
+ @spot.reload
+ assert_equal [@chloe], @spot.protector_kittens.delete(@chloe)
+ assert @spot.protector_kittens.empty?
+ @spot.protector_kittens.delete(@chloe) # again, unclear what .delete should return
+
+ @spot.reload
+ assert @spot.protector_kittens.empty?
+ assert @spot.wild_boars.include?(@puma)
+ end
+
+ def test_double_individual_collections_clear
+ @spot.protectors << [@chloe, @puma, @alice]
+ @spot.reload
+ assert_equal [], @spot.protector_kittens.clear
+ assert @spot.protector_kittens.empty?
+ assert_equal 1, @spot.protectors.size
+ @spot.reload
+ assert @spot.protector_kittens.empty?
+ assert_equal 1, @spot.protectors.size
+ assert !@spot.protector_kittens.include?(@chloe)
+ assert !@spot.protectors.include?(@chloe)
+ assert !@spot.protector_kittens.include?(@alice)
+ assert !@spot.protectors.include?(@alice)
+ assert @spot.protectors.include?(@puma)
+ assert @spot.wild_boars.include?(@puma)
+ end
+
+ def test_single_extensions
+ assert_equal :correct_block_result, @shamu.aquatic_pupils.a_method
+ @kibbles.eaters.push(@alice)
+ @kibbles.eaters.push(@spot)
+ assert_equal :correct_join_result, @kibbles.eaters_foodstuffs.a_method
+ assert_equal :correct_module_result, @kibbles.eaters.a_method
+ assert_equal :correct_other_module_result, @kibbles.eaters.another_method
+ @kibbles.eaters.each do |eater|
+ assert_equal :correct_join_result, eater.eaters_foodstuffs.a_method
+ end
+ assert_equal :correct_parent_proc_result, @kibbles.foodstuffs_of_eaters.a_method
+ assert_equal :correct_parent_proc_result, @kibbles.eaters.first.foodstuffs_of_eaters.a_method
+ end
+
+ def test_double_extensions
+ assert_equal :correct_proc_result, @spot.protectors.a_method
+ assert_equal :correct_module_result, @spot.enemies.a_method
+ assert_equal :correct_join_result, @spot.beautiful_fight_relationships_as_enemy.a_method
+ assert_equal :correct_join_result, @spot.beautiful_fight_relationships_as_protector.a_method
+ assert_equal :correct_join_result, @froggy.beautiful_fight_relationships.a_method
+ assert_equal :correct_join_result, @froggy.beautiful_fight_relationships_as_enemy.a_method
+ assert_raises(NoMethodError) {@froggy.beautiful_fight_relationships_as_protector.a_method}
+ end
+
+ def test_pluralization_checks
+ assert_raises(@association_error) {
+ eval "class SomeModel < ActiveRecord::Base
+ has_many_polymorphs :polymorphs, :from => [:dog, :cats]
+ end" }
+ assert_raises(@association_error) {
+ eval "class SomeModel < ActiveRecord::Base
+ has_many_polymorphs :polymorph, :from => [:dogs, :cats]
+ end" }
+ assert_raises(@association_error) {
+ eval "class SomeModel < ActiveRecord::Base
+ acts_as_double_polymorphic_join :polymorph => [:dogs, :cats], :unimorphs => [:dogs, :cats]
+ end" }
+ end
+
+ def test_error_message_on_namespaced_targets
+ assert_raises(@association_error) {
+ eval "class SomeModel < ActiveRecord::Base
+ has_many_polymorphs :polymorphs, :from => [:fish]
+ end" }
+ end
+
+ def test_single_custom_finders
+ [@kibbles, @alice, @puma, @spot, @bits].each {|record| @kibbles.eaters << record; sleep 1} # XXX yeah i know
+ assert_equal @kibbles.eaters, @kibbles.eaters.find(:all, :order => "eaters_foodstuffs.created_at ASC")
+ assert_equal @kibbles.eaters.reverse, @kibbles.eaters.find(:all, :order => "eaters_foodstuffs.created_at DESC")
+ if (ActiveRecord::Base.connection.is_a? ActiveRecord::ConnectionAdapters::MysqlAdapter rescue false)
+ assert_equal @kibbles.eaters.sort_by(&:created_at), @kibbles.eaters.find(:all, :order => "IFNULL(bow_wows.created_at,(IFNULL(petfoods.created_at,(IFNULL(wild_boars.created_at,(IFNULL(cats.created_at,fish.created_at))))))) ASC")
+ end
+ assert_equal @kibbles.eaters.select{|x| x.is_a? Petfood}, @kibbles.eater_petfoods.find(:all, :order => "eaters_foodstuffs.created_at ASC")
+ end
+
+ def test_double_custom_finders
+ @spot.protectors << [@chloe, @puma, @alice]
+ assert_equal [@chloe], @spot.protectors.find(:all, :conditions => ["cats.name = ?", @chloe.name], :limit => 1)
+ assert_equal [], @spot.protectors.find(:all, :conditions => ["cats.name = ?", @chloe.name], :limit => 1, :offset => 1)
+ assert_equal 2, @spot.protectors.find(:all, :limit => 100, :offset => 1).size
+ end
+
+ def test_single_custom_finder_parameters_carry_to_individual_relationships
+ # XXX test nullout here
+ end
+
+ def test_double_custom_finder_parameters_carry_to_individual_relationships
+ # XXX test nullout here
+ end
+
+ def test_include_doesnt_fail
+ assert_nothing_raised do
+ @spot.protectors.find(:all, :include => :wild_boars)
+ end
+ end
+
+ def test_abstract_method
+ assert_equal :correct_abstract_method_response, @spot.an_abstract_method
+ end
+
+ def test_missing_target_should_raise
+ @kibbles.eaters << [@kibbles, @alice, @puma, @spot, @bits]
+ @spot.destroy_without_callbacks
+ assert_raises(@association_error) { @kibbles.eaters.reload }
+# assert_raises(@association_error) { @kibbles.eater_dogs.reload } # bah AR
+ end
+
+ def test_lazy_loading_is_lazy
+ # XXX
+ end
+
+ def test_push_with_skip_duplicates_false_doesnt_load_target
+ # Loading kibbles locally again because setup calls .size which loads target
+ kibbles = Petfood.find(1)
+ assert !kibbles.eaters.loaded?
+ assert !(kibbles.eater_dogs << Dog.create!(:name => "Mongy")).loaded?
+ assert !kibbles.eaters.loaded?
+ end
+
+ def test_association_foreign_key_is_sane
+ assert_equal "eater_id", Petfood.reflect_on_association(:eaters).association_foreign_key
+ end
+
+ def test_reflection_instance_methods_are_sane
+ assert_equal EatersFoodstuff, Petfood.reflect_on_association(:eaters).klass
+ assert_equal EatersFoodstuff.name, Petfood.reflect_on_association(:eaters).class_name
+ end
+
+ def test_parent_order
+ @alice.foodstuffs_of_eaters << Petfood.find(:all, :order => "the_petfood_primary_key ASC")
+ @alice.reload #not necessary
+ assert_equal [2,1], @alice.foodstuffs_of_eaters.map(&:id)
+ end
+
+ def test_parent_conditions
+ @kibbles.eaters << @alice
+ assert_equal [@alice], @kibbles.eaters
+
+ @snausages = Petfood.create(:name => 'Snausages')
+ @snausages.eaters << @alice
+ assert_equal [@alice], @snausages.eaters
+
+ assert_equal [@kibbles], @alice.foodstuffs_of_eaters
+ end
+
+ def test_self_referential_hmp_with_conditions
+ p = Person.find(:first)
+ kid = Person.create(:name => "Tim", :age => 3)
+ p.kids << kid
+
+ kid.reload; p.reload
+
+ # assert_equal [p], kid.parents
+ # assert Rails.has_one? Bug
+ # non-standard foreign_type key is not set properly when you are the polymorphic interface of a has_many going to a :through
+
+ assert_equal [kid], p.kids
+ assert_equal [kid], p.people
+ end
+
+# def test_polymorphic_include
+# @kibbles.eaters << [@kibbles, @alice, @puma, @spot, @bits]
+# assert @kibbles.eaters.include?(@kibbles.eaters_foodstuffs.find(:all, :include => :eater).first.eater)
+# end
+#
+# def test_double_polymorphic_include
+# end
+#
+# def test_single_child_include
+# end
+#
+# def test_double_child_include
+# end
+#
+# def test_single_include_from_parent
+# end
+#
+# def test_double_include_from_parent
+# end
+#
+# def test_meta_referential_single_include
+# end
+#
+# def test_meta_referential_double_include
+# end
+#
+# def test_meta_referential_single_include
+# end
+#
+# def test_meta_referential_single_double_multi_include
+# end
+#
+# def test_dont_ignore_duplicates
+# end
+#
+# def test_ignore_duplicates
+# end
+#
+# def test_tagging_system_generator
+# end
+#
+# def test_tagging_system_library
+# end
+
+end