Add the has_many_polymorphs plugin
[cs356-p2-videostore.git] / vendor / plugins / has_many_polymorphs / test / unit / polymorph_test.rb
1 require File.dirname(__FILE__) + '/../test_helper'
2
3 require 'dog'
4 require 'wild_boar'
5 require 'frog'
6 require 'cat'
7 require 'kitten'
8 require 'aquatic/whale'
9 require 'aquatic/fish'
10 require 'aquatic/pupils_whale'
11 require 'beautiful_fight_relationship' 
12
13 class PolymorphTest < Test::Unit::TestCase
14   
15   set_fixture_class :bow_wows => Dog
16   set_fixture_class :keep_your_enemies_close => BeautifulFightRelationship
17   set_fixture_class :whales => Aquatic::Whale
18   set_fixture_class :fish => Aquatic::Fish
19   set_fixture_class :little_whale_pupils => Aquatic::PupilsWhale
20   
21   fixtures :cats, :bow_wows, :frogs, :wild_boars, :eaters_foodstuffs, :petfoods,
22               :fish, :whales, :little_whale_pupils, :keep_your_enemies_close, :people   
23         
24   def setup
25    @association_error = ActiveRecord::Associations::PolymorphicError
26    @kibbles = Petfood.find(1)
27    @bits = Petfood.find(2) 
28    @shamu = Aquatic::Whale.find(1)
29    @swimmy = Aquatic::Fish.find(1)
30    @rover = Dog.find(1)
31    @spot = Dog.find(2)
32    @puma  = WildBoar.find(1)
33    @chloe = Kitten.find(1)
34    @alice = Kitten.find(2)
35    @toby = Tabby.find(3)
36    @froggy = Frog.find(1)
37
38    @join_count = EatersFoodstuff.count    
39    @kibbles_eaters_count = @kibbles.eaters.size
40    @bits_eaters_count = @bits.eaters.size
41
42    @double_join_count = BeautifulFightRelationship.count
43    @alice_enemies_count = @alice.enemies.size
44   end  
45   
46   def test_all_relationship_validities
47     # q = []
48     # ObjectSpace.each_object(Class){|c| q << c if c.ancestors.include? ActiveRecord::Base }
49     # q.each{|c| puts "#{c.name}.reflect_on_all_associations.map &:check_validity! "}
50     Petfood.reflect_on_all_associations.map &:check_validity! 
51     Tabby.reflect_on_all_associations.map &:check_validity! 
52     Kitten.reflect_on_all_associations.map &:check_validity! 
53     Dog.reflect_on_all_associations.map &:check_validity! 
54     Canine.reflect_on_all_associations.map &:check_validity! 
55     Aquatic::Fish.reflect_on_all_associations.map &:check_validity! 
56     EatersFoodstuff.reflect_on_all_associations.map &:check_validity! 
57     WildBoar.reflect_on_all_associations.map &:check_validity! 
58     Frog.reflect_on_all_associations.map &:check_validity! 
59     Cat.reflect_on_all_associations.map &:check_validity! 
60     BeautifulFightRelationship.reflect_on_all_associations.map &:check_validity! 
61     Person.reflect_on_all_associations.map &:check_validity! 
62     Parentship.reflect_on_all_associations.map &:check_validity! 
63     Aquatic::Whale.reflect_on_all_associations.map &:check_validity! 
64     Aquatic::PupilsWhale.reflect_on_all_associations.map &:check_validity! 
65   end
66   
67   def test_assignment     
68     assert @kibbles.eaters.blank?
69     assert @kibbles.eaters.push(Cat.find_by_name('Chloe'))
70     assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
71
72     @kibbles.reload
73     assert_equal @kibbles_eaters_count, @kibbles.eaters.count    
74   end
75   
76   def test_duplicate_assignment
77     # try to add a duplicate item when :ignore_duplicates is false
78     @kibbles.eaters.push(@alice)
79     assert @kibbles.eaters.include?(@alice)
80     @kibbles.eaters.push(@alice)
81     assert_equal @kibbles_eaters_count + 2, @kibbles.eaters.count
82     assert_equal @join_count + 2, EatersFoodstuff.count
83   end
84   
85   def test_create_and_push
86     assert @kibbles.eaters.push(@spot)  
87     assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
88     assert @kibbles.eaters << @rover
89     assert @kibbles.eaters << Kitten.create(:name => "Miranda")
90     assert_equal @kibbles_eaters_count += 2, @kibbles.eaters.length
91
92     @kibbles.reload
93     assert_equal @kibbles_eaters_count, @kibbles.eaters.length   
94     
95     # test that ids and new flags were set appropriately
96     assert_not_nil @kibbles.eaters[0].id
97     assert !@kibbles.eaters[1].new_record?
98   end
99  
100   def test_reload
101     assert @kibbles.reload
102     assert @kibbles.eaters.reload
103   end
104  
105   def test_add_join_record
106     assert_equal Kitten, @chloe.class
107     assert join = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @chloe.id, :eater_type => @chloe.class.name ) 
108     assert join.save!
109     assert join.id
110     assert_equal @join_count + 1, EatersFoodstuff.count
111
112     #assert_equal @bits_eaters_count, @bits.eaters.size # Doesn't behave this way on latest edge anymore
113     assert_equal @bits_eaters_count + 1, @bits.eaters.count # SQL
114
115     # reload; is the new association there?
116     assert @bits.eaters.reload
117     assert @bits.eaters.include?(@chloe)
118   end
119
120   def test_build_join_record_on_association
121     assert_equal Kitten, @chloe.class
122     assert join = @chloe.eaters_foodstuffs.build(:foodstuff => @bits)
123     # assert_equal join.eater_type, @chloe.class.name # will be STI parent type
124     assert join.save!
125     assert join.id
126     assert_equal @join_count + 1, EatersFoodstuff.count
127
128     assert @bits.eaters.reload
129     assert @bits.eaters.include?(@chloe)
130   end
131
132 #  not supporting this, since has_many :through doesn't support it either  
133 #  def test_add_unsaved   
134 #    # add an unsaved item
135 #    assert @bits.eaters << Kitten.new(:name => "Bridget")
136 #    assert_nil Kitten.find_by_name("Bridget")
137 #    assert_equal @bits_eaters_count + 1, @bits.eaters.count
138 #
139 #    assert @bits.save
140 #    @bits.reload
141 #    assert_equal @bits_eaters_count + 1, @bits.eaters.count
142 #    
143 #  end
144   
145   def test_self_reference
146     assert @kibbles.eaters << @bits
147     assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
148     assert @kibbles.eaters.include?(@bits)
149     @kibbles.reload
150     assert @kibbles.foodstuffs_of_eaters.blank?
151     
152     @bits.reload
153     assert @bits.foodstuffs_of_eaters.include?(@kibbles)
154     assert_equal [@kibbles], @bits.foodstuffs_of_eaters
155   end
156
157   def test_remove
158     assert @kibbles.eaters << @chloe
159     @kibbles.reload
160     assert @kibbles.eaters.delete(@kibbles.eaters[0])
161     assert_equal @kibbles_eaters_count, @kibbles.eaters.count
162   end
163   
164   def test_destroy
165     assert @kibbles.eaters.push(@chloe)
166     @kibbles.reload
167     assert @kibbles.eaters.length > 0
168     assert @kibbles.eaters[0].destroy
169     @kibbles.reload
170     assert_equal @kibbles_eaters_count, @kibbles.eaters.count
171   end
172
173   def test_clear
174     @kibbles.eaters << [@chloe, @spot, @rover]
175     @kibbles.reload
176     assert @kibbles.eaters.clear.blank?    
177     assert @kibbles.eaters.blank?    
178     @kibbles.reload    
179     assert @kibbles.eaters.blank?    
180   end
181     
182   def test_individual_collections
183     assert @kibbles.eaters.push(@chloe)
184     # check if individual collections work
185     assert_equal @kibbles.eater_kittens.length, 1
186     assert @kibbles.eater_dogs 
187     assert 1, @rover.eaters_foodstuffs.count
188   end
189   
190   def test_individual_collections_push
191     assert_equal [@chloe], (@kibbles.eater_kittens << @chloe)
192     @kibbles.reload
193     assert @kibbles.eaters.include?(@chloe)
194     assert @kibbles.eater_kittens.include?(@chloe)
195     assert !@kibbles.eater_dogs.include?(@chloe)
196   end
197
198   def test_individual_collections_delete
199     @kibbles.eaters << [@chloe, @spot, @rover]
200     @kibbles.reload
201     assert_equal [@chloe], @kibbles.eater_kittens.delete(@chloe)
202     assert @kibbles.eater_kittens.empty?
203     @kibbles.eater_kittens.delete(@chloe) # what should this return?
204     
205     @kibbles.reload    
206     assert @kibbles.eater_kittens.empty?
207     assert @kibbles.eater_dogs.include?(@spot)
208   end
209   
210   def test_individual_collections_clear
211     @kibbles.eaters << [@chloe, @spot, @rover]
212     @kibbles.reload
213
214     assert_equal [], @kibbles.eater_kittens.clear
215     assert @kibbles.eater_kittens.empty?    
216     assert_equal 2, @kibbles.eaters.size
217
218     assert @kibbles.eater_kittens.empty?    
219     assert_equal 2, @kibbles.eaters.size
220     assert !@kibbles.eater_kittens.include?(@chloe)
221     assert !@kibbles.eaters.include?(@chloe)
222
223     @kibbles.reload    
224     assert @kibbles.eater_kittens.empty?    
225     assert_equal 2, @kibbles.eaters.size
226     assert !@kibbles.eater_kittens.include?(@chloe)
227     assert !@kibbles.eaters.include?(@chloe)
228   end
229   
230   def test_childrens_individual_collections
231     assert Cat.find_by_name('Chloe').eaters_foodstuffs
232     assert @kibbles.eaters_foodstuffs
233   end
234   
235   def test_self_referential_join_tables
236     # check that the self-reference join tables go the right ways
237     assert_equal @kibbles_eaters_count, @kibbles.eaters_foodstuffs.count
238     assert_equal @kibbles.eaters_foodstuffs.count, @kibbles.eaters_foodstuffs_as_child.count
239   end
240
241   def test_dependent
242     assert @kibbles.eaters << @chloe
243     @kibbles.reload
244  
245     # delete ourself and see if :dependent was obeyed
246     dependent_rows = @kibbles.eaters_foodstuffs
247     assert_equal dependent_rows.length, @kibbles.eaters.count
248     @join_count = EatersFoodstuff.count
249     
250     @kibbles.destroy
251     assert_equal @join_count - dependent_rows.length, EatersFoodstuff.count
252     assert_equal 0, EatersFoodstuff.find(:all, :conditions => ['foodstuff_id = ?', 1] ).length
253   end
254   
255   def test_normal_callbacks
256     assert @rover.respond_to?(:after_initialize)
257     assert @rover.respond_to?(:after_find)    
258     assert @rover.after_initialize_test
259     assert @rover.after_find_test
260   end    
261   
262   def test_model_callbacks_not_overridden_by_plugin_callbacks
263     assert 0, @bits.eaters.count
264     assert @bits.eaters.push(@rover)
265     @bits.save
266     @bits2 = Petfood.find_by_name("Bits")
267     @bits.reload
268     assert rover = @bits2.eaters.select { |x| x.name == "Rover" }[0]
269     assert rover.after_initialize_test
270     assert rover.after_find_test
271   end
272
273   def test_number_of_join_records
274     assert EatersFoodstuff.create(:foodstuff_id => 1, :eater_id => 1, :eater_type => "Cat")
275     @join_count = EatersFoodstuff.count    
276     assert @join_count > 0
277   end
278   
279   def test_number_of_regular_records
280     dogs = Dog.count
281     assert Dog.new(:name => "Auggie").save!
282     assert dogs + 1, Dog.count
283   end
284
285   def test_attributes_come_through_when_child_has_underscore_in_table_name
286     join = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id =>  @puma.id, :eater_type => @puma.class.name) 
287     join.save!
288     
289     @bits.eaters.reload
290
291     assert_equal "Puma", @puma.name
292     assert_equal "Puma", @bits.eaters.first.name
293   end
294   
295   
296   def test_before_save_on_join_table_is_not_clobbered_by_sti_base_class_fix
297     assert @kibbles.eaters << @chloe
298     assert_equal 3, @kibbles.eaters_foodstuffs.first.some_attribute
299   end
300   
301   def test_sti_type_counts_are_correct
302     @kibbles.eaters << [@chloe, @alice, @toby]
303     assert_equal 2, @kibbles.eater_kittens.count
304     assert_equal 1, @kibbles.eater_tabbies.count
305     assert !@kibbles.respond_to?(:eater_cats)
306   end
307   
308     
309   def test_creating_namespaced_relationship
310     assert @shamu.aquatic_pupils.empty?
311     @shamu.aquatic_pupils << @swimmy
312     assert_equal 1, @shamu.aquatic_pupils.length
313     @shamu.reload
314     assert_equal 1, @shamu.aquatic_pupils.length
315   end  
316
317   def test_namespaced_polymorphic_collection
318     @shamu.aquatic_pupils << @swimmy
319     assert @shamu.aquatic_pupils.include?(@swimmy)
320     @shamu.reload
321     assert @shamu.aquatic_pupils.include?(@swimmy)
322
323     @shamu.aquatic_pupils << @spot
324     assert @shamu.dogs.include?(@spot)
325     assert @shamu.aquatic_pupils.include?(@swimmy)
326     assert_equal @swimmy, @shamu.aquatic_fish.first
327     assert_equal 10, @shamu.aquatic_fish.first.speed
328   end
329   
330   def test_deleting_namespaced_relationship    
331     @shamu.aquatic_pupils << @swimmy
332     @shamu.aquatic_pupils << @spot
333     
334     @shamu.reload
335     @shamu.aquatic_pupils.delete @spot
336     assert !@shamu.dogs.include?(@spot)
337     assert !@shamu.aquatic_pupils.include?(@spot)
338     assert_equal 1, @shamu.aquatic_pupils.length
339   end
340   
341   def test_unrenamed_parent_of_namespaced_child
342     @shamu.aquatic_pupils << @swimmy
343     assert_equal [@shamu], @swimmy.whales
344   end
345   
346   def test_empty_double_collections
347     assert @puma.enemies.empty?
348     assert @froggy.protectors.empty?
349     assert @alice.enemies.empty?
350     assert @spot.protectors.empty?
351     assert @alice.beautiful_fight_relationships_as_enemy.empty?
352     assert @alice.beautiful_fight_relationships_as_protector.empty?
353     assert @alice.beautiful_fight_relationships.empty?    
354   end
355   
356   def test_double_collection_assignment
357     @alice.enemies << @spot
358     @alice.reload
359     @spot.reload
360     assert @spot.protectors.include?(@alice)
361     assert @alice.enemies.include?(@spot)
362     assert !@alice.protectors.include?(@alice)
363     assert_equal 1, @alice.beautiful_fight_relationships_as_protector.size
364     assert_equal 0, @alice.beautiful_fight_relationships_as_enemy.size
365     assert_equal 1, @alice.beautiful_fight_relationships.size
366     
367     # self reference
368     assert_equal 1, @alice.enemies.length
369     @alice.enemies.push @alice
370     assert @alice.enemies.include?(@alice)
371     assert_equal 2, @alice.enemies.length    
372     @alice.reload
373     assert_equal 2, @alice.beautiful_fight_relationships_as_protector.size
374     assert_equal 1, @alice.beautiful_fight_relationships_as_enemy.size
375     assert_equal 3, @alice.beautiful_fight_relationships.size
376   end
377   
378   def test_double_collection_build_join_record_on_association
379     
380     join = @alice.beautiful_fight_relationships_as_protector.build(:enemy => @spot)
381     
382     assert_equal @alice.class.base_class.name, join.protector_type
383     assert_nothing_raised { join.save! }
384
385     assert join.id
386     assert_equal @double_join_count + 1, BeautifulFightRelationship.count
387
388     assert @alice.enemies.reload
389     assert @alice.enemies.include?(@spot)
390   end
391   
392   def test_double_dependency_injection
393 #    breakpoint
394   end
395   
396   def test_double_collection_deletion
397     @alice.enemies << @spot
398     @alice.reload
399     assert @alice.enemies.include?(@spot)
400     @alice.enemies.delete(@spot)
401     assert !@alice.enemies.include?(@spot)
402     assert @alice.enemies.empty?
403     @alice.reload
404     assert !@alice.enemies.include?(@spot)
405     assert @alice.enemies.empty?
406     assert_equal 0, @alice.beautiful_fight_relationships.size
407   end
408  
409   def test_double_collection_deletion_from_opposite_side
410     @alice.protectors << @puma
411     @alice.reload
412     assert @alice.protectors.include?(@puma)
413     @alice.protectors.delete(@puma)
414     assert !@alice.protectors.include?(@puma)
415     assert @alice.protectors.empty?
416     @alice.reload
417     assert !@alice.protectors.include?(@puma)
418     assert @alice.protectors.empty?
419     assert_equal 0, @alice.beautiful_fight_relationships.size
420   end
421  
422   def test_individual_collections_created_for_double_relationship
423     assert @alice.dogs.empty?
424     @alice.enemies << @spot
425
426     assert @alice.enemies.include?(@spot)
427     assert !@alice.kittens.include?(@alice)    
428
429     assert !@alice.dogs.include?(@spot)    
430     @alice.reload
431     assert @alice.dogs.include?(@spot)    
432     assert !WildBoar.find(@alice.id).dogs.include?(@spot) # make sure the parent type is checked
433   end
434
435   def test_individual_collections_created_for_double_relationship_from_opposite_side
436     assert @alice.wild_boars.empty?
437     @alice.protectors << @puma
438
439     assert @alice.protectors.include?(@puma)
440     assert !@alice.wild_boars.include?(@puma)    
441     @alice.reload
442     assert @alice.wild_boars.include?(@puma)    
443     
444     assert !Dog.find(@alice.id).wild_boars.include?(@puma) # make sure the parent type is checked
445   end
446   
447   def test_self_referential_individual_collections_created_for_double_relationship
448     @alice.enemies << @alice
449     @alice.reload
450     assert @alice.enemy_kittens.include?(@alice)
451     assert @alice.protector_kittens.include?(@alice)
452     assert @alice.kittens.include?(@alice)
453     assert_equal 2, @alice.kittens.size
454
455     @alice.enemies << (@chloe =  Kitten.find_by_name('Chloe'))
456     @alice.reload
457     assert @alice.enemy_kittens.include?(@chloe)
458     assert !@alice.protector_kittens.include?(@chloe)
459     assert @alice.kittens.include?(@chloe)
460     assert_equal 3, @alice.kittens.size    
461   end
462     
463   def test_child_of_polymorphic_join_can_reach_parent
464     @alice.enemies << @spot    
465     @alice.reload
466     assert @spot.protectors.include?(@alice)
467   end
468   
469   def test_double_collection_deletion_from_child_polymorphic_join
470     @alice.enemies << @spot
471     @spot.protectors.delete(@alice)
472     assert !@spot.protectors.include?(@alice)
473     @alice.reload
474     assert !@alice.enemies.include?(@spot)
475     BeautifulFightRelationship.create(:protector_id => 2, :protector_type => "Dog", :enemy_id => @spot.id, :enemy_type => @spot.class.name)
476     @alice.enemies << @spot
477     @spot.protectors.delete(@alice)
478     assert !@spot.protectors.include?(@alice)
479   end
480
481   def test_collection_query_on_unsaved_record
482     assert Dog.new.enemies.empty?
483     assert Dog.new.foodstuffs_of_eaters.empty?
484   end
485  
486   def test_double_individual_collections_push
487     assert_equal [@chloe], (@spot.protector_kittens << @chloe)
488     @spot.reload
489     assert @spot.protectors.include?(@chloe)
490     assert @spot.protector_kittens.include?(@chloe)
491     assert !@spot.protector_dogs.include?(@chloe)
492  
493     assert_equal [@froggy], (@spot.frogs << @froggy)
494     @spot.reload
495     assert @spot.enemies.include?(@froggy)
496     assert @spot.frogs.include?(@froggy)
497     assert !@spot.enemy_dogs.include?(@froggy)
498   end
499
500   def test_double_individual_collections_delete
501     @spot.protectors << [@chloe, @puma]
502     @spot.reload
503     assert_equal [@chloe], @spot.protector_kittens.delete(@chloe)
504     assert @spot.protector_kittens.empty?
505     @spot.protector_kittens.delete(@chloe) # again, unclear what .delete should return
506     
507     @spot.reload    
508     assert @spot.protector_kittens.empty?
509     assert @spot.wild_boars.include?(@puma)
510   end
511   
512   def test_double_individual_collections_clear
513     @spot.protectors << [@chloe, @puma, @alice]
514     @spot.reload
515     assert_equal [], @spot.protector_kittens.clear
516     assert @spot.protector_kittens.empty?    
517     assert_equal 1, @spot.protectors.size
518     @spot.reload    
519     assert @spot.protector_kittens.empty?    
520     assert_equal 1, @spot.protectors.size
521     assert !@spot.protector_kittens.include?(@chloe)
522     assert !@spot.protectors.include?(@chloe)
523     assert !@spot.protector_kittens.include?(@alice)
524     assert !@spot.protectors.include?(@alice)
525     assert @spot.protectors.include?(@puma)
526     assert @spot.wild_boars.include?(@puma)
527   end 
528
529   def test_single_extensions
530     assert_equal :correct_block_result, @shamu.aquatic_pupils.a_method
531     @kibbles.eaters.push(@alice)
532     @kibbles.eaters.push(@spot)
533     assert_equal :correct_join_result, @kibbles.eaters_foodstuffs.a_method
534     assert_equal :correct_module_result, @kibbles.eaters.a_method
535     assert_equal :correct_other_module_result, @kibbles.eaters.another_method
536     @kibbles.eaters.each do |eater| 
537       assert_equal :correct_join_result, eater.eaters_foodstuffs.a_method
538     end
539     assert_equal :correct_parent_proc_result, @kibbles.foodstuffs_of_eaters.a_method
540     assert_equal :correct_parent_proc_result, @kibbles.eaters.first.foodstuffs_of_eaters.a_method
541   end
542
543   def test_double_extensions
544     assert_equal :correct_proc_result, @spot.protectors.a_method 
545     assert_equal :correct_module_result, @spot.enemies.a_method 
546     assert_equal :correct_join_result, @spot.beautiful_fight_relationships_as_enemy.a_method
547     assert_equal :correct_join_result, @spot.beautiful_fight_relationships_as_protector.a_method
548     assert_equal :correct_join_result, @froggy.beautiful_fight_relationships.a_method
549     assert_equal :correct_join_result, @froggy.beautiful_fight_relationships_as_enemy.a_method    
550     assert_raises(NoMethodError) {@froggy.beautiful_fight_relationships_as_protector.a_method}    
551   end
552   
553   def test_pluralization_checks    
554     assert_raises(@association_error) {
555       eval "class SomeModel < ActiveRecord::Base
556         has_many_polymorphs :polymorphs, :from => [:dog, :cats]
557       end" }
558     assert_raises(@association_error) {
559       eval "class SomeModel < ActiveRecord::Base
560         has_many_polymorphs :polymorph, :from => [:dogs, :cats]
561       end" }
562     assert_raises(@association_error) {
563       eval "class SomeModel < ActiveRecord::Base
564         acts_as_double_polymorphic_join :polymorph => [:dogs, :cats], :unimorphs => [:dogs, :cats]
565       end" }    
566   end
567   
568   def test_error_message_on_namespaced_targets
569     assert_raises(@association_error) {
570       eval "class SomeModel < ActiveRecord::Base
571         has_many_polymorphs :polymorphs, :from => [:fish]
572       end" }
573   end
574
575   def test_single_custom_finders
576     [@kibbles, @alice, @puma, @spot, @bits].each {|record| @kibbles.eaters << record; sleep 1} # XXX yeah i know
577     assert_equal @kibbles.eaters, @kibbles.eaters.find(:all, :order => "eaters_foodstuffs.created_at ASC") 
578     assert_equal @kibbles.eaters.reverse, @kibbles.eaters.find(:all, :order => "eaters_foodstuffs.created_at DESC") 
579     if (ActiveRecord::Base.connection.is_a? ActiveRecord::ConnectionAdapters::MysqlAdapter rescue false)
580       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") 
581     end
582     assert_equal @kibbles.eaters.select{|x| x.is_a? Petfood}, @kibbles.eater_petfoods.find(:all, :order => "eaters_foodstuffs.created_at ASC") 
583   end
584  
585   def test_double_custom_finders
586     @spot.protectors << [@chloe, @puma, @alice]
587     assert_equal [@chloe], @spot.protectors.find(:all, :conditions => ["cats.name = ?", @chloe.name], :limit => 1)
588     assert_equal [], @spot.protectors.find(:all, :conditions => ["cats.name = ?", @chloe.name], :limit => 1, :offset => 1)
589     assert_equal 2, @spot.protectors.find(:all, :limit => 100, :offset => 1).size
590   end
591   
592   def test_single_custom_finder_parameters_carry_to_individual_relationships
593    # XXX test nullout here
594   end
595
596   def test_double_custom_finder_parameters_carry_to_individual_relationships
597    # XXX test nullout here
598   end
599   
600   def test_include_doesnt_fail
601     assert_nothing_raised do
602       @spot.protectors.find(:all, :include => :wild_boars)
603     end
604   end
605
606   def test_abstract_method
607     assert_equal :correct_abstract_method_response, @spot.an_abstract_method
608   end
609   
610   def test_missing_target_should_raise
611     @kibbles.eaters << [@kibbles, @alice, @puma, @spot, @bits]
612     @spot.destroy_without_callbacks
613     assert_raises(@association_error) { @kibbles.eaters.reload }
614 #    assert_raises(@association_error) { @kibbles.eater_dogs.reload }  # bah AR
615   end
616   
617   def test_lazy_loading_is_lazy
618     # XXX
619   end
620   
621   def test_push_with_skip_duplicates_false_doesnt_load_target
622     # Loading kibbles locally again because setup calls .size which loads target
623     kibbles = Petfood.find(1)
624     assert !kibbles.eaters.loaded?
625     assert !(kibbles.eater_dogs << Dog.create!(:name => "Mongy")).loaded?
626     assert !kibbles.eaters.loaded?
627   end
628   
629   def test_association_foreign_key_is_sane
630     assert_equal "eater_id", Petfood.reflect_on_association(:eaters).association_foreign_key
631   end
632
633   def test_reflection_instance_methods_are_sane
634     assert_equal EatersFoodstuff, Petfood.reflect_on_association(:eaters).klass
635     assert_equal EatersFoodstuff.name, Petfood.reflect_on_association(:eaters).class_name
636   end
637   
638   def test_parent_order
639     @alice.foodstuffs_of_eaters << Petfood.find(:all, :order => "the_petfood_primary_key ASC")
640     @alice.reload #not necessary
641     assert_equal [2,1], @alice.foodstuffs_of_eaters.map(&:id)  
642   end
643
644   def test_parent_conditions
645     @kibbles.eaters << @alice
646     assert_equal [@alice], @kibbles.eaters
647
648     @snausages = Petfood.create(:name => 'Snausages')
649     @snausages.eaters << @alice    
650     assert_equal [@alice], @snausages.eaters
651     
652     assert_equal [@kibbles], @alice.foodstuffs_of_eaters
653   end        
654   
655   def test_self_referential_hmp_with_conditions
656     p = Person.find(:first)
657     kid = Person.create(:name => "Tim", :age => 3)
658     p.kids << kid
659
660     kid.reload; p.reload
661
662   # assert_equal [p], kid.parents 
663   # assert Rails.has_one? Bug
664   # non-standard foreign_type key is not set properly when you are the polymorphic interface of a has_many going to a :through
665
666     assert_equal [kid], p.kids
667     assert_equal [kid], p.people
668   end
669
670 #  def test_polymorphic_include
671 #    @kibbles.eaters << [@kibbles, @alice, @puma, @spot, @bits]
672 #    assert @kibbles.eaters.include?(@kibbles.eaters_foodstuffs.find(:all, :include => :eater).first.eater)
673 #  end
674 #
675 #  def test_double_polymorphic_include
676 #  end
677 #
678 #  def test_single_child_include  
679 #  end
680 #  
681 #  def test_double_child_include  
682 #  end
683 #  
684 #  def test_single_include_from_parent  
685 #  end
686 #
687 #  def test_double_include_from_parent  
688 #  end
689 #
690 #  def test_meta_referential_single_include  
691 #  end
692 #
693 #  def test_meta_referential_double_include  
694 #  end
695 #  
696 #  def test_meta_referential_single_include  
697 #  end
698 #
699 #  def test_meta_referential_single_double_multi_include  
700 #  end  
701 #  
702 #  def test_dont_ignore_duplicates  
703 #  end
704 #
705 #  def test_ignore_duplicates  
706 #  end
707 #    
708 #  def test_tagging_system_generator  
709 #  end
710 #
711 #  def test_tagging_system_library  
712 #  end
713
714 end