Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/branches/2-1-caching/activerecord/test/associations_test.rb

Revision 8365, 74.3 kB (checked in by bitsweat, 1 year ago)

Ruby 1.9 compat: File.exists\? -> File.exist\? en masse. References #1689 [Pratik Naik]

  • Property svn:executable set to *
Line 
1 require 'abstract_unit'
2 require 'fixtures/developer'
3 require 'fixtures/project'
4 require 'fixtures/company'
5 require 'fixtures/topic'
6 require 'fixtures/reply'
7 require 'fixtures/computer'
8 require 'fixtures/customer'
9 require 'fixtures/order'
10 require 'fixtures/categorization'
11 require 'fixtures/category'
12 require 'fixtures/post'
13 require 'fixtures/author'
14 require 'fixtures/comment'
15 require 'fixtures/tag'
16 require 'fixtures/tagging'
17 require 'fixtures/person'
18 require 'fixtures/reader'
19
20 class AssociationsTest < Test::Unit::TestCase
21   fixtures :accounts, :companies, :developers, :projects, :developers_projects,
22            :computers
23
24   def test_bad_collection_keys
25     assert_raise(ArgumentError, 'ActiveRecord should have barked on bad collection keys') do
26       Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels')
27     end
28   end
29  
30   def test_should_construct_new_finder_sql_after_create
31     person = Person.new
32     assert_equal [], person.readers.find(:all)
33     person.save!
34     reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar")
35     assert_equal [reader], person.readers.find(:all)
36   end
37
38   def test_force_reload
39     firm = Firm.new("name" => "A New Firm, Inc")
40     firm.save
41     firm.clients.each {|c|} # forcing to load all clients
42     assert firm.clients.empty?, "New firm shouldn't have client objects"
43     assert_equal 0, firm.clients.size, "New firm should have 0 clients"
44
45     client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
46     client.save
47
48     assert firm.clients.empty?, "New firm should have cached no client objects"
49     assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"
50
51     assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
52     assert_equal 1, firm.clients(true).size, "New firm should have reloaded clients count"
53   end
54
55   def test_storing_in_pstore
56     require "tmpdir"
57     store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
58     File.delete(store_filename) if File.exist?(store_filename)
59     require "pstore"
60     apple = Firm.create("name" => "Apple")
61     natural = Client.new("name" => "Natural Company")
62     apple.clients << natural
63
64     db = PStore.new(store_filename)
65     db.transaction do
66       db["apple"] = apple
67     end
68
69     db = PStore.new(store_filename)
70     db.transaction do
71       assert_equal "Natural Company", db["apple"].clients.first.name
72     end
73   end
74 end
75
76 class AssociationProxyTest < Test::Unit::TestCase
77   fixtures :authors, :posts, :categorizations, :categories, :developers, :projects, :developers_projects
78
79   def test_proxy_accessors
80     welcome = posts(:welcome)
81     assert_equal  welcome, welcome.author.proxy_owner
82     assert_equal  welcome.class.reflect_on_association(:author), welcome.author.proxy_reflection
83     welcome.author.class  # force load target
84     assert_equal  welcome.author, welcome.author.proxy_target
85
86     david = authors(:david)
87     assert_equal  david, david.posts.proxy_owner
88     assert_equal  david.class.reflect_on_association(:posts), david.posts.proxy_reflection
89     david.posts.first   # force load target
90     assert_equal  david.posts, david.posts.proxy_target
91
92     assert_equal  david, david.posts_with_extension.testing_proxy_owner
93     assert_equal  david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
94     david.posts_with_extension.first   # force load target
95     assert_equal  david.posts_with_extension, david.posts_with_extension.testing_proxy_target
96   end
97
98   def test_push_does_not_load_target
99     david = authors(:david)
100
101     david.categories << categories(:technology)
102     assert !david.categories.loaded?
103     assert david.categories.include?(categories(:technology))
104   end
105
106   def test_push_does_not_lose_additions_to_new_record
107     josh = Author.new(:name => "Josh")
108     josh.posts << Post.new(:title => "New on Edge", :body => "More cool stuff!")
109     assert josh.posts.loaded?
110     assert_equal 1, josh.posts.size
111   end
112
113   def test_save_on_parent_does_not_load_target
114     david = developers(:david)
115
116     assert !david.projects.loaded?
117     david.update_attribute(:created_at, Time.now)
118     assert !david.projects.loaded?
119   end
120
121   def test_save_on_parent_saves_children
122     developer = Developer.create :name => "Bryan", :salary => 50_000
123     assert_equal 1, developer.reload.audit_logs.size
124   end
125
126   def test_failed_reload_returns_nil
127     p = setup_dangling_association
128     assert_nil p.author.reload
129   end
130
131   def test_failed_reset_returns_nil
132     p = setup_dangling_association
133     assert_nil p.author.reset
134   end
135
136   def test_reload_returns_assocition
137     david = developers(:david)
138     assert_nothing_raised do
139       assert_equal david.projects, david.projects.reload.reload
140     end
141   end
142
143   def setup_dangling_association
144     josh = Author.create(:name => "Josh")
145     p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
146     josh.destroy
147     p
148   end
149 end
150
151 class HasOneAssociationsTest < Test::Unit::TestCase
152   fixtures :accounts, :companies, :developers, :projects, :developers_projects
153
154   def setup
155     Account.destroyed_account_ids.clear
156   end
157
158   def test_has_one
159     assert_equal companies(:first_firm).account, Account.find(1)
160     assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
161   end
162
163   def test_has_one_cache_nils
164     firm = companies(:another_firm)
165     assert_queries(1) { assert_nil firm.account }
166     assert_queries(0) { assert_nil firm.account }
167
168     firms = Firm.find(:all, :include => :account)
169     assert_queries(0) { firms.each(&:account) }
170   end
171
172   def test_can_marshal_has_one_association_with_nil_target
173     firm = Firm.new
174     assert_nothing_raised do
175       assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
176     end
177
178     firm.account
179     assert_nothing_raised do
180       assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
181     end
182   end
183
184   def test_proxy_assignment
185     company = companies(:first_firm)
186     assert_nothing_raised { company.account = company.account }
187   end
188
189   def test_triple_equality
190     assert Account === companies(:first_firm).account
191     assert companies(:first_firm).account === Account
192   end
193
194   def test_type_mismatch
195     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
196     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
197   end
198
199   def test_natural_assignment
200     apple = Firm.create("name" => "Apple")
201     citibank = Account.create("credit_limit" => 10)
202     apple.account = citibank
203     assert_equal apple.id, citibank.firm_id
204   end
205
206   def test_natural_assignment_to_nil
207     old_account_id = companies(:first_firm).account.id
208     companies(:first_firm).account = nil
209     companies(:first_firm).save
210     assert_nil companies(:first_firm).account
211     # account is dependent, therefore is destroyed when reference to owner is lost
212     assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
213   end
214
215   def test_assignment_without_replacement
216     apple = Firm.create("name" => "Apple")
217     citibank = Account.create("credit_limit" => 10)
218     apple.account = citibank
219     assert_equal apple.id, citibank.firm_id
220
221     hsbc = apple.build_account({ :credit_limit => 20}, false)
222     assert_equal apple.id, hsbc.firm_id
223     hsbc.save
224     assert_equal apple.id, citibank.firm_id
225
226     nykredit = apple.create_account({ :credit_limit => 30}, false)
227     assert_equal apple.id, nykredit.firm_id
228     assert_equal apple.id, citibank.firm_id
229     assert_equal apple.id, hsbc.firm_id
230   end
231
232   def test_assignment_without_replacement_on_create
233     apple = Firm.create("name" => "Apple")
234     citibank = Account.create("credit_limit" => 10)
235     apple.account = citibank
236     assert_equal apple.id, citibank.firm_id
237
238     hsbc = apple.create_account({:credit_limit => 10}, false)
239     assert_equal apple.id, hsbc.firm_id
240     hsbc.save
241     assert_equal apple.id, citibank.firm_id
242   end
243
244   def test_dependence
245     num_accounts = Account.count
246
247     firm = Firm.find(1)
248     assert !firm.account.nil?
249     account_id = firm.account.id
250     assert_equal [], Account.destroyed_account_ids[firm.id]
251
252     firm.destroy
253     assert_equal num_accounts - 1, Account.count
254     assert_equal [account_id], Account.destroyed_account_ids[firm.id]
255   end
256
257   def test_exclusive_dependence
258     num_accounts = Account.count
259
260     firm = ExclusivelyDependentFirm.find(9)
261     assert !firm.account.nil?
262     account_id = firm.account.id
263     assert_equal [], Account.destroyed_account_ids[firm.id]
264
265     firm.destroy
266     assert_equal num_accounts - 1, Account.count
267     assert_equal [], Account.destroyed_account_ids[firm.id]
268   end
269
270   def test_dependence_with_nil_associate
271     firm = DependentFirm.new(:name => 'nullify')
272     firm.save!
273     assert_nothing_raised { firm.destroy }
274   end
275
276   def test_succesful_build_association
277     firm = Firm.new("name" => "GlobalMegaCorp")
278     firm.save
279
280     account = firm.build_account("credit_limit" => 1000)
281     assert account.save
282     assert_equal account, firm.account
283   end
284
285   def test_failing_build_association
286     firm = Firm.new("name" => "GlobalMegaCorp")
287     firm.save
288
289     account = firm.build_account
290     assert !account.save
291     assert_equal "can't be empty", account.errors.on("credit_limit")
292   end
293
294   def test_build_association_twice_without_saving_affects_nothing
295     count_of_account = Account.count
296     firm = Firm.find(:first)
297     account1 = firm.build_account("credit_limit" => 1000)
298     account2 = firm.build_account("credit_limit" => 2000)
299
300     assert_equal count_of_account, Account.count
301   end
302
303   def test_create_association
304     firm = Firm.create(:name => "GlobalMegaCorp")
305     account = firm.create_account(:credit_limit => 1000)
306     assert_equal account, firm.reload.account
307   end
308
309   def test_build
310     firm = Firm.new("name" => "GlobalMegaCorp")
311     firm.save
312
313     firm.account = account = Account.new("credit_limit" => 1000)
314     assert_equal account, firm.account
315     assert account.save
316     assert_equal account, firm.account
317   end
318
319   def test_build_before_child_saved
320     firm = Firm.find(1)
321
322     account = firm.account.build("credit_limit" => 1000)
323     assert_equal account, firm.account
324     assert account.new_record?
325     assert firm.save
326     assert_equal account, firm.account
327     assert !account.new_record?
328   end
329
330   def test_build_before_either_saved
331     firm = Firm.new("name" => "GlobalMegaCorp")
332
333     firm.account = account = Account.new("credit_limit" => 1000)
334     assert_equal account, firm.account
335     assert account.new_record?
336     assert firm.save
337     assert_equal account, firm.account
338     assert !account.new_record?
339   end
340
341   def test_failing_build_association
342     firm = Firm.new("name" => "GlobalMegaCorp")
343     firm.save
344
345     firm.account = account = Account.new
346     assert_equal account, firm.account
347     assert !account.save
348     assert_equal account, firm.account
349     assert_equal "can't be empty", account.errors.on("credit_limit")
350   end
351
352   def test_create
353     firm = Firm.new("name" => "GlobalMegaCorp")
354     firm.save
355     firm.account = account = Account.create("credit_limit" => 1000)
356     assert_equal account, firm.account
357   end
358
359   def test_create_before_save
360     firm = Firm.new("name" => "GlobalMegaCorp")
361     firm.account = account = Account.create("credit_limit" => 1000)
362     assert_equal account, firm.account
363   end
364
365   def test_dependence_with_missing_association
366     Account.destroy_all
367     firm = Firm.find(1)
368     assert firm.account.nil?
369     firm.destroy
370   end
371
372   def test_dependence_with_missing_association_and_nullify
373     Account.destroy_all
374     firm = DependentFirm.find(:first)
375     assert firm.account.nil?
376     firm.destroy
377   end
378
379   def test_assignment_before_parent_saved
380     firm = Firm.new("name" => "GlobalMegaCorp")
381     firm.account = a = Account.find(1)
382     assert firm.new_record?
383     assert_equal a, firm.account
384     assert firm.save
385     assert_equal a, firm.account
386     assert_equal a, firm.account(true)
387   end
388
389   def test_finding_with_interpolated_condition
390     firm = Firm.find(:first)
391     superior = firm.clients.create(:name => 'SuperiorCo')
392     superior.rating = 10
393     superior.save
394     assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
395   end
396
397   def test_assignment_before_child_saved
398     firm = Firm.find(1)
399     firm.account = a = Account.new("credit_limit" => 1000)
400     assert !a.new_record?
401     assert_equal a, firm.account
402     assert_equal a, firm.account
403     assert_equal a, firm.account(true)
404   end
405
406   def test_assignment_before_either_saved
407     firm = Firm.new("name" => "GlobalMegaCorp")
408     firm.account = a = Account.new("credit_limit" => 1000)
409     assert firm.new_record?
410     assert a.new_record?
411     assert_equal a, firm.account
412     assert firm.save
413     assert !firm.new_record?
414     assert !a.new_record?
415     assert_equal a, firm.account
416     assert_equal a, firm.account(true)
417   end
418
419   def test_not_resaved_when_unchanged
420     firm = Firm.find(:first, :include => :account)
421     assert_queries(1) { firm.save! }
422
423     firm = Firm.find(:first)
424     firm.account = Account.find(:first)
425     assert_queries(1) { firm.save! }
426
427     firm = Firm.find(:first).clone
428     firm.account = Account.find(:first)
429     assert_queries(2) { firm.save! }
430
431     firm = Firm.find(:first).clone
432     firm.account = Account.find(:first).clone
433     assert_queries(2) { firm.save! }
434   end
435
436   def test_save_still_works_after_accessing_nil_has_one
437     jp = Company.new :name => 'Jaded Pixel'
438     jp.dummy_account.nil?
439
440     assert_nothing_raised do
441       jp.save!
442     end
443   end
444
445 end
446
447
448 class HasManyAssociationsTest < Test::Unit::TestCase
449   fixtures :accounts, :companies, :developers, :projects,
450            :developers_projects, :topics, :authors, :comments
451
452   def setup
453     Client.destroyed_client_ids.clear
454   end
455
456   def force_signal37_to_load_all_clients_of_firm
457     companies(:first_firm).clients_of_firm.each {|f| }
458   end
459
460   def test_counting_with_counter_sql
461     assert_equal 2, Firm.find(:first).clients.count
462   end
463
464   def test_counting
465     assert_equal 2, Firm.find(:first).plain_clients.count
466   end
467
468   def test_counting_with_single_conditions
469     assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
470   end
471
472   def test_counting_with_single_hash
473     assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
474   end
475
476   def test_counting_with_column_name_and_hash
477     assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
478   end
479
480   def test_finding
481     assert_equal 2, Firm.find(:first).clients.length
482   end
483
484   def test_find_many_with_merged_options
485     assert_equal 1, companies(:first_firm).limited_clients.size
486     assert_equal 1, companies(:first_firm).limited_clients.find(:all).size
487