ibm_db 2.5.5 → 2.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  require "cases/helper"
2
+ require 'models/post'
2
3
  require 'models/author'
3
4
  require 'models/topic'
4
5
  require 'models/reply'
@@ -9,15 +10,17 @@ require 'models/developer'
9
10
  require 'models/project'
10
11
  require 'models/default'
11
12
  require 'models/auto_id'
13
+ require 'models/boolean'
12
14
  require 'models/column_name'
13
15
  require 'models/subscriber'
14
16
  require 'models/keyboard'
15
- require 'models/post'
16
17
  require 'models/comment'
17
18
  require 'models/minimalistic'
18
19
  require 'models/warehouse_thing'
19
20
  require 'models/parrot'
21
+ require 'models/loose_person'
20
22
  require 'rexml/document'
23
+ require 'active_support/core_ext/exception'
21
24
 
22
25
  class Category < ActiveRecord::Base; end
23
26
  class Categorization < ActiveRecord::Base; end
@@ -36,45 +39,11 @@ class Computer < ActiveRecord::Base; end
36
39
  class NonExistentTable < ActiveRecord::Base; end
37
40
  class TestOracleDefault < ActiveRecord::Base; end
38
41
 
39
- class LoosePerson < ActiveRecord::Base
40
- self.table_name = 'people'
41
- self.abstract_class = true
42
- attr_protected :credit_rating, :administrator
43
- end
44
-
45
- class LooseDescendant < LoosePerson
46
- attr_protected :phone_number
47
- end
48
-
49
- class LooseDescendantSecond< LoosePerson
50
- attr_protected :phone_number
51
- attr_protected :name
52
- end
53
-
54
- class TightPerson < ActiveRecord::Base
55
- self.table_name = 'people'
56
- attr_accessible :name, :address
57
- end
58
-
59
- class TightDescendant < TightPerson
60
- attr_accessible :phone_number
61
- end
62
-
63
42
  class ReadonlyTitlePost < Post
64
43
  attr_readonly :title
65
44
  end
66
45
 
67
- class Booleantest < ActiveRecord::Base; end
68
-
69
- class Task < ActiveRecord::Base
70
- attr_protected :starting
71
- end
72
-
73
- class TopicWithProtectedContentAndAccessibleAuthorName < ActiveRecord::Base
74
- self.table_name = 'topics'
75
- attr_accessible :author_name
76
- attr_protected :content
77
- end
46
+ class Boolean < ActiveRecord::Base; end
78
47
 
79
48
  class BasicsTest < ActiveRecord::TestCase
80
49
  fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, :warehouse_things, :authors, :categorizations, :categories, :posts
@@ -83,424 +52,129 @@ class BasicsTest < ActiveRecord::TestCase
83
52
  assert !NonExistentTable.table_exists?
84
53
  assert Topic.table_exists?
85
54
  end
86
-
87
- def test_set_attributes
88
- topic = Topic.find(1)
89
- topic.attributes = { "title" => "Budget", "author_name" => "Jason" }
90
- topic.save
91
- assert_equal("Budget", topic.title)
92
- assert_equal("Jason", topic.author_name)
93
- assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address)
94
- end
95
-
96
- def test_integers_as_nil
97
- test = AutoId.create('value' => '')
98
- assert_nil AutoId.find(test.id).value
99
- end
100
-
101
- def test_set_attributes_with_block
102
- topic = Topic.new do |t|
103
- t.title = "Budget"
104
- t.author_name = "Jason"
105
- end
106
-
107
- assert_equal("Budget", topic.title)
108
- assert_equal("Jason", topic.author_name)
109
- end
110
-
111
- def test_respond_to?
112
- topic = Topic.find(1)
113
- assert topic.respond_to?("title")
114
- assert topic.respond_to?("title?")
115
- assert topic.respond_to?("title=")
116
- assert topic.respond_to?(:title)
117
- assert topic.respond_to?(:title?)
118
- assert topic.respond_to?(:title=)
119
- assert topic.respond_to?("author_name")
120
- assert topic.respond_to?("attribute_names")
121
- assert !topic.respond_to?("nothingness")
122
- assert !topic.respond_to?(:nothingness)
123
- end
124
-
125
- def test_array_content
126
- topic = Topic.new
127
- topic.content = %w( one two three )
128
- topic.save
129
-
130
- assert_equal(%w( one two three ), Topic.find(topic.id).content)
131
- end
132
-
133
- def test_read_attributes_before_type_cast
134
- category = Category.new({:name=>"Test categoty", :type => nil})
135
- category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil}
136
- assert_equal category_attrs , category.attributes_before_type_cast
137
- end
138
-
139
- if current_adapter?(:MysqlAdapter)
140
- def test_read_attributes_before_type_cast_on_boolean
141
- bool = Booleantest.create({ "value" => false })
142
- assert_equal "0", bool.reload.attributes_before_type_cast["value"]
143
- end
144
- end
145
-
146
- def test_read_attributes_before_type_cast_on_datetime
147
- developer = Developer.find(:first)
148
- assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"]
149
- end
150
-
151
- def test_hash_content
152
- topic = Topic.new
153
- topic.content = { "one" => 1, "two" => 2 }
154
- topic.save
155
-
156
- assert_equal 2, Topic.find(topic.id).content["two"]
157
-
158
- topic.content_will_change!
159
- topic.content["three"] = 3
160
- topic.save
161
-
162
- assert_equal 3, Topic.find(topic.id).content["three"]
163
- end
164
-
165
- def test_update_array_content
166
- topic = Topic.new
167
- topic.content = %w( one two three )
168
-
169
- topic.content.push "four"
170
- assert_equal(%w( one two three four ), topic.content)
171
-
172
- topic.save
173
-
174
- topic = Topic.find(topic.id)
175
- topic.content << "five"
176
- assert_equal(%w( one two three four five ), topic.content)
177
- end
178
-
179
- def test_case_sensitive_attributes_hash
180
- # DB2 is not case-sensitive
181
- return true if current_adapter?(:DB2Adapter, :IBM_DBAdapter)
182
-
183
- assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.find(:first).attributes
184
- end
185
-
186
- def test_create
187
- topic = Topic.new
188
- topic.title = "New Topic"
189
- topic.save
190
- topic_reloaded = Topic.find(topic.id)
191
- assert_equal("New Topic", topic_reloaded.title)
192
- end
193
-
194
- def test_save!
195
- topic = Topic.new(:title => "New Topic")
196
- assert topic.save!
197
-
198
- reply = Reply.new
199
- assert_raise(ActiveRecord::RecordInvalid) { reply.save! }
200
- end
201
-
202
- def test_save_null_string_attributes
203
- topic = Topic.find(1)
204
- topic.attributes = { "title" => "null", "author_name" => "null" }
205
- topic.save!
206
- topic.reload
207
- assert_equal("null", topic.title)
208
- assert_equal("null", topic.author_name)
209
- end
210
-
211
- def test_save_nil_string_attributes
212
- topic = Topic.find(1)
213
- topic.title = nil
214
- topic.save!
215
- topic.reload
216
- assert_nil topic.title
217
- end
218
-
219
- def test_save_for_record_with_only_primary_key
220
- minimalistic = Minimalistic.new
221
- assert_nothing_raised { minimalistic.save }
222
- end
223
-
224
- def test_save_for_record_with_only_primary_key_that_is_provided
225
- assert_nothing_raised { Minimalistic.create!(:id => 2) }
226
- end
227
-
228
- def test_hashes_not_mangled
229
- new_topic = { :title => "New Topic" }
230
- new_topic_values = { :title => "AnotherTopic" }
231
-
232
- topic = Topic.new(new_topic)
233
- assert_equal new_topic[:title], topic.title
234
-
235
- topic.attributes= new_topic_values
236
- assert_equal new_topic_values[:title], topic.title
237
- end
238
-
239
- def test_create_many
240
- topics = Topic.create([ { "title" => "first" }, { "title" => "second" }])
241
- assert_equal 2, topics.size
242
- assert_equal "first", topics.first.title
243
- end
244
-
245
- def test_create_columns_not_equal_attributes
246
- topic = Topic.new
247
- topic.title = 'Another New Topic'
248
- topic.send :write_attribute, 'does_not_exist', 'test'
249
- assert_nothing_raised { topic.save }
250
- end
251
-
252
- def test_create_through_factory
253
- topic = Topic.create("title" => "New Topic")
254
- topicReloaded = Topic.find(topic.id)
255
- assert_equal(topic, topicReloaded)
256
- end
257
-
258
- def test_create_through_factory_with_block
259
- topic = Topic.create("title" => "New Topic") do |t|
260
- t.author_name = "David"
261
- end
262
- topicReloaded = Topic.find(topic.id)
263
- assert_equal("New Topic", topic.title)
264
- assert_equal("David", topic.author_name)
265
- end
266
-
267
- def test_create_many_through_factory_with_block
268
- topics = Topic.create([ { "title" => "first" }, { "title" => "second" }]) do |t|
269
- t.author_name = "David"
270
- end
271
- assert_equal 2, topics.size
272
- topic1, topic2 = Topic.find(topics[0].id), Topic.find(topics[1].id)
273
- assert_equal "first", topic1.title
274
- assert_equal "David", topic1.author_name
275
- assert_equal "second", topic2.title
276
- assert_equal "David", topic2.author_name
277
- end
278
-
279
- def test_update
280
- topic = Topic.new
281
- topic.title = "Another New Topic"
282
- topic.written_on = "2003-12-12 23:23:00"
283
- topic.save
284
- topicReloaded = Topic.find(topic.id)
285
- assert_equal("Another New Topic", topicReloaded.title)
286
-
287
- topicReloaded.title = "Updated topic"
288
- topicReloaded.save
289
-
290
- topicReloadedAgain = Topic.find(topic.id)
291
-
292
- assert_equal("Updated topic", topicReloadedAgain.title)
293
- end
294
-
295
- def test_update_columns_not_equal_attributes
296
- topic = Topic.new
297
- topic.title = "Still another topic"
298
- topic.save
299
-
300
- topicReloaded = Topic.find(topic.id)
301
- topicReloaded.title = "A New Topic"
302
- topicReloaded.send :write_attribute, 'does_not_exist', 'test'
303
- assert_nothing_raised { topicReloaded.save }
304
- end
305
-
306
- def test_update_for_record_with_only_primary_key
307
- minimalistic = minimalistics(:first)
308
- assert_nothing_raised { minimalistic.save }
309
- end
310
-
311
- def test_write_attribute
312
- topic = Topic.new
313
- topic.send(:write_attribute, :title, "Still another topic")
314
- assert_equal "Still another topic", topic.title
315
-
316
- topic.send(:write_attribute, "title", "Still another topic: part 2")
317
- assert_equal "Still another topic: part 2", topic.title
318
- end
319
-
320
- def test_read_attribute
321
- topic = Topic.new
322
- topic.title = "Don't change the topic"
323
- assert_equal "Don't change the topic", topic.send(:read_attribute, "title")
324
- assert_equal "Don't change the topic", topic["title"]
325
-
326
- assert_equal "Don't change the topic", topic.send(:read_attribute, :title)
327
- assert_equal "Don't change the topic", topic[:title]
328
- end
329
-
330
- def test_read_attribute_when_false
331
- topic = topics(:first)
332
- topic.approved = false
333
- assert !topic.approved?, "approved should be false"
334
- topic.approved = "false"
335
- assert !topic.approved?, "approved should be false"
336
- end
337
-
338
- def test_read_attribute_when_true
339
- topic = topics(:first)
340
- topic.approved = true
341
- assert topic.approved?, "approved should be true"
342
- topic.approved = "true"
343
- assert topic.approved?, "approved should be true"
344
- end
345
-
346
- def test_read_write_boolean_attribute
347
- topic = Topic.new
348
- # puts ""
349
- # puts "New Topic"
350
- # puts topic.inspect
351
- topic.approved = "false"
352
- # puts "Expecting false"
353
- # puts topic.inspect
354
- assert !topic.approved?, "approved should be false"
355
- topic.approved = "false"
356
- # puts "Expecting false"
357
- # puts topic.inspect
358
- assert !topic.approved?, "approved should be false"
359
- topic.approved = "true"
360
- # puts "Expecting true"
361
- # puts topic.inspect
362
- assert topic.approved?, "approved should be true"
363
- topic.approved = "true"
364
- # puts "Expecting true"
365
- # puts topic.inspect
366
- assert topic.approved?, "approved should be true"
367
- # puts ""
368
- end
369
-
370
- def test_query_attribute_string
371
- [nil, "", " "].each do |value|
372
- assert_equal false, Topic.new(:author_name => value).author_name?
373
- end
374
-
375
- assert_equal true, Topic.new(:author_name => "Name").author_name?
376
- end
377
-
378
- def test_query_attribute_number
379
- [nil, 0, "0"].each do |value|
380
- assert_equal false, Developer.new(:salary => value).salary?
381
- end
382
-
383
- assert_equal true, Developer.new(:salary => 1).salary?
384
- assert_equal true, Developer.new(:salary => "1").salary?
385
- end
386
-
387
- def test_query_attribute_boolean
388
- [nil, "", false, "false", "f", 0].each do |value|
389
- assert_equal false, Topic.new(:approved => value).approved?
390
- end
391
-
392
- [true, "true", "1", 1].each do |value|
393
- assert_equal true, Topic.new(:approved => value).approved?
394
- end
395
- end
396
-
397
- def test_query_attribute_with_custom_fields
398
- object = Company.find_by_sql(<<-SQL).first
399
- SELECT c1.*, c2.ruby_type as string_value, c2.rating as int_value
400
- FROM companies c1, companies c2
401
- WHERE c1.firm_id = c2.id
402
- AND c1.id = 2
403
- SQL
404
-
405
- assert_equal "Firm", object.string_value
406
- assert object.string_value?
407
-
408
- object.string_value = " "
409
- assert !object.string_value?
410
-
411
- assert_equal 1, object.int_value.to_i
412
- assert object.int_value?
413
-
414
- object.int_value = "0"
415
- assert !object.int_value?
416
- end
417
-
418
-
419
- def test_reader_for_invalid_column_names
420
- Topic.send(:define_read_method, "mumub-jumbo".to_sym, "mumub-jumbo", nil)
421
- assert !Topic.generated_methods.include?("mumub-jumbo")
422
- end
423
-
424
- def test_non_attribute_access_and_assignment
425
- topic = Topic.new
426
- assert !topic.respond_to?("mumbo")
427
- assert_raise(NoMethodError) { topic.mumbo }
428
- assert_raise(NoMethodError) { topic.mumbo = 5 }
429
- end
430
-
55
+
431
56
  def test_preserving_date_objects
432
- if current_adapter?(:SybaseAdapter, :OracleAdapter)
57
+ if current_adapter?(:SybaseAdapter)
433
58
  # Sybase ctlib does not (yet?) support the date type; use datetime instead.
434
- # Oracle treats all dates/times as Time.
435
59
  assert_kind_of(
436
60
  Time, Topic.find(1).last_read,
437
61
  "The last_read attribute should be of the Time class"
438
62
  )
439
63
  else
64
+ # Oracle enhanced adapter allows to define Date attributes in model class (see topic.rb)
440
65
  assert_kind_of(
441
66
  Date, Topic.find(1).last_read,
442
67
  "The last_read attribute should be of the Date class"
443
68
  )
444
69
  end
445
70
  end
446
-
71
+
72
+ def test_use_table_engine_for_quoting_where
73
+ relation = Topic.where(Topic.arel_table[:id].eq(1))
74
+ engine = relation.table.engine
75
+
76
+ fakepool = Class.new(Struct.new(:spec)) {
77
+ def with_connection; yield self; end
78
+ def connection_pool; self; end
79
+ def quote_table_name(*args); raise "lol quote_table_name"; end
80
+ }
81
+
82
+ relation.table.engine = fakepool.new(engine.connection_pool.spec)
83
+
84
+ error = assert_raises(RuntimeError) { relation.to_a }
85
+ assert_match('lol', error.message)
86
+ ensure
87
+ relation.table.engine = engine
88
+ end
89
+
447
90
  def test_preserving_time_objects
448
91
  assert_kind_of(
449
92
  Time, Topic.find(1).bonus_time,
450
93
  "The bonus_time attribute should be of the Time class"
451
94
  )
452
-
95
+
453
96
  assert_kind_of(
454
97
  Time, Topic.find(1).written_on,
455
98
  "The written_on attribute should be of the Time class"
456
99
  )
457
-
100
+
458
101
  # For adapters which support microsecond resolution.
459
- if current_adapter?(:PostgreSQLAdapter)
102
+ if current_adapter?(:PostgreSQLAdapter) || current_adapter?(:SQLiteAdapter)
460
103
  assert_equal 11, Topic.find(1).written_on.sec
461
104
  assert_equal 223300, Topic.find(1).written_on.usec
462
105
  assert_equal 9900, Topic.find(2).written_on.usec
463
106
  end
464
107
  end
465
-
466
- def test_custom_mutator
467
- topic = Topic.find(1)
468
- # This mutator is protected in the class definition
469
- topic.send(:approved=, true)
470
- assert topic.instance_variable_get("@custom_approved")
108
+
109
+ def test_preserving_time_objects_with_local_time_conversion_to_default_timezone_utc
110
+ with_env_tz 'America/New_York' do
111
+ with_active_record_default_timezone :utc do
112
+ time = Time.local(2000)
113
+ topic = Topic.create('written_on' => time)
114
+ saved_time = Topic.find(topic.id).written_on
115
+ assert_equal time, saved_time
116
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "EST"], time.to_a
117
+ assert_equal [0, 0, 5, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a
118
+ end
119
+ end
471
120
  end
472
121
 
473
- def test_delete
474
- topic = Topic.find(1)
475
- assert_equal topic, topic.delete, 'topic.delete did not return self'
476
- assert topic.frozen?, 'topic not frozen after delete'
477
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
122
+ def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_utc
123
+ with_env_tz 'America/New_York' do
124
+ with_active_record_default_timezone :utc do
125
+ Time.use_zone 'Central Time (US & Canada)' do
126
+ time = Time.zone.local(2000)
127
+ topic = Topic.create('written_on' => time)
128
+ saved_time = Topic.find(topic.id).written_on
129
+ assert_equal time, saved_time
130
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a
131
+ assert_equal [0, 0, 6, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a
132
+ end
133
+ end
134
+ end
478
135
  end
479
136
 
480
- def test_delete_doesnt_run_callbacks
481
- Topic.find(1).delete
482
- assert_not_nil Topic.find(2)
137
+ def test_preserving_time_objects_with_utc_time_conversion_to_default_timezone_local
138
+ with_env_tz 'America/New_York' do
139
+ time = Time.utc(2000)
140
+ topic = Topic.create('written_on' => time)
141
+ saved_time = Topic.find(topic.id).written_on
142
+ assert_equal time, saved_time
143
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], time.to_a
144
+ assert_equal [0, 0, 19, 31, 12, 1999, 5, 365, false, "EST"], saved_time.to_a
145
+ end
483
146
  end
484
147
 
485
- def test_destroy
486
- topic = Topic.find(1)
487
- assert_equal topic, topic.destroy, 'topic.destroy did not return self'
488
- assert topic.frozen?, 'topic not frozen after destroy'
489
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
148
+ def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_local
149
+ with_env_tz 'America/New_York' do
150
+ with_active_record_default_timezone :local do
151
+ Time.use_zone 'Central Time (US & Canada)' do
152
+ time = Time.zone.local(2000)
153
+ topic = Topic.create('written_on' => time)
154
+ saved_time = Topic.find(topic.id).written_on
155
+ assert_equal time, saved_time
156
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a
157
+ assert_equal [0, 0, 1, 1, 1, 2000, 6, 1, false, "EST"], saved_time.to_a
158
+ end
159
+ end
160
+ end
490
161
  end
491
-
492
- def test_record_not_found_exception
493
- assert_raise(ActiveRecord::RecordNotFound) { topicReloaded = Topic.find(99999) }
162
+
163
+ def test_custom_mutator
164
+ topic = Topic.find(1)
165
+ # This mutator is protected in the class definition
166
+ topic.send(:approved=, true)
167
+ assert topic.instance_variable_get("@custom_approved")
494
168
  end
495
-
169
+
496
170
  def test_initialize_with_attributes
497
171
  topic = Topic.new({
498
172
  "title" => "initialized from attributes", "written_on" => "2003-12-12 23:23"
499
173
  })
500
-
174
+
501
175
  assert_equal("initialized from attributes", topic.title)
502
176
  end
503
-
177
+
504
178
  def test_initialize_with_invalid_attribute
505
179
  begin
506
180
  topic = Topic.new({ "title" => "test",
@@ -510,25 +184,25 @@ class BasicsTest < ActiveRecord::TestCase
510
184
  assert_equal("last_read", ex.errors[0].attribute)
511
185
  end
512
186
  end
513
-
187
+
514
188
  def test_load
515
189
  topics = Topic.find(:all, :order => 'id')
516
190
  assert_equal(4, topics.size)
517
191
  assert_equal(topics(:first).title, topics.first.title)
518
192
  end
519
-
193
+
520
194
  def test_load_with_condition
521
195
  topics = Topic.find(:all, :conditions => "author_name = 'Mary'")
522
-
196
+
523
197
  assert_equal(1, topics.size)
524
198
  assert_equal(topics(:second).title, topics.first.title)
525
199
  end
526
-
200
+
201
+ GUESSED_CLASSES = [Category, Smarts, CreditCard, CreditCard::PinNumber, CreditCard::PinNumber::CvvCode, CreditCard::SubPinNumber, CreditCard::Brand, MasterCreditCard]
202
+
527
203
  def test_table_name_guesses
528
- classes = [Category, Smarts, CreditCard, CreditCard::PinNumber, CreditCard::PinNumber::CvvCode, CreditCard::SubPinNumber, CreditCard::Brand, MasterCreditCard]
529
-
530
204
  assert_equal "topics", Topic.table_name
531
-
205
+
532
206
  assert_equal "categories", Category.table_name
533
207
  assert_equal "smarts", Smarts.table_name
534
208
  assert_equal "credit_cards", CreditCard.table_name
@@ -537,10 +211,14 @@ class BasicsTest < ActiveRecord::TestCase
537
211
  assert_equal "credit_card_pin_numbers", CreditCard::SubPinNumber.table_name
538
212
  assert_equal "categories", CreditCard::Brand.table_name
539
213
  assert_equal "master_credit_cards", MasterCreditCard.table_name
540
-
214
+ ensure
215
+ GUESSED_CLASSES.each(&:reset_table_name)
216
+ end
217
+
218
+ def test_singular_table_name_guesses
541
219
  ActiveRecord::Base.pluralize_table_names = false
542
- classes.each(&:reset_table_name)
543
-
220
+ GUESSED_CLASSES.each(&:reset_table_name)
221
+
544
222
  assert_equal "category", Category.table_name
545
223
  assert_equal "smarts", Smarts.table_name
546
224
  assert_equal "credit_card", CreditCard.table_name
@@ -549,10 +227,12 @@ class BasicsTest < ActiveRecord::TestCase
549
227
  assert_equal "credit_card_pin_number", CreditCard::SubPinNumber.table_name
550
228
  assert_equal "category", CreditCard::Brand.table_name
551
229
  assert_equal "master_credit_card", MasterCreditCard.table_name
552
-
230
+ ensure
553
231
  ActiveRecord::Base.pluralize_table_names = true
554
- classes.each(&:reset_table_name)
555
-
232
+ GUESSED_CLASSES.each(&:reset_table_name)
233
+ end
234
+
235
+ def test_table_name_guesses_with_prefixes_and_suffixes
556
236
  ActiveRecord::Base.table_name_prefix = "test_"
557
237
  Category.reset_table_name
558
238
  assert_equal "test_categories", Category.table_name
@@ -565,8 +245,15 @@ class BasicsTest < ActiveRecord::TestCase
565
245
  ActiveRecord::Base.table_name_suffix = ""
566
246
  Category.reset_table_name
567
247
  assert_equal "categories", Category.table_name
568
-
248
+ ensure
249
+ ActiveRecord::Base.table_name_prefix = ""
250
+ ActiveRecord::Base.table_name_suffix = ""
251
+ GUESSED_CLASSES.each(&:reset_table_name)
252
+ end
253
+
254
+ def test_singular_table_name_guesses_with_prefixes_and_suffixes
569
255
  ActiveRecord::Base.pluralize_table_names = false
256
+
570
257
  ActiveRecord::Base.table_name_prefix = "test_"
571
258
  Category.reset_table_name
572
259
  assert_equal "test_category", Category.table_name
@@ -579,199 +266,67 @@ class BasicsTest < ActiveRecord::TestCase
579
266
  ActiveRecord::Base.table_name_suffix = ""
580
267
  Category.reset_table_name
581
268
  assert_equal "category", Category.table_name
582
-
269
+ ensure
583
270
  ActiveRecord::Base.pluralize_table_names = true
584
- classes.each(&:reset_table_name)
585
- end
586
-
587
- def test_destroy_all
588
- original_count = Topic.count
589
- topics_by_mary = Topic.count(:conditions => mary = "author_name = 'Mary'")
590
-
591
- Topic.destroy_all mary
592
- assert_equal original_count - topics_by_mary, Topic.count
593
- end
594
-
595
- def test_destroy_many
596
- assert_equal 3, Client.count
597
- Client.destroy([2, 3])
598
- assert_equal 1, Client.count
599
- end
600
-
601
- def test_delete_many
602
- original_count = Topic.count
603
- Topic.delete(deleting = [1, 2])
604
- assert_equal original_count - deleting.size, Topic.count
605
- end
606
-
607
- def test_boolean_attributes
608
- assert ! Topic.find(1).approved?
609
- assert Topic.find(2).approved?
610
- end
611
-
612
- def test_increment_counter
613
- Topic.increment_counter("replies_count", 1)
614
- assert_equal 2, Topic.find(1).replies_count
615
-
616
- Topic.increment_counter("replies_count", 1)
617
- assert_equal 3, Topic.find(1).replies_count
618
- end
619
-
620
- def test_decrement_counter
621
- Topic.decrement_counter("replies_count", 2)
622
- assert_equal -1, Topic.find(2).replies_count
623
-
624
- Topic.decrement_counter("replies_count", 2)
625
- assert_equal -2, Topic.find(2).replies_count
626
- end
627
-
628
- def test_update_counter
629
- category = categories(:general)
630
- assert_nil category.categorizations_count
631
- assert_equal 2, category.categorizations.count
632
-
633
- Category.update_counters(category.id, "categorizations_count" => category.categorizations.count)
634
- category.reload
635
- assert_not_nil category.categorizations_count
636
- assert_equal 2, category.categorizations_count
637
-
638
- Category.update_counters(category.id, "categorizations_count" => category.categorizations.count)
639
- category.reload
640
- assert_not_nil category.categorizations_count
641
- assert_equal 4, category.categorizations_count
642
-
643
- category_2 = categories(:technology)
644
- count_1, count_2 = (category.categorizations_count || 0), (category_2.categorizations_count || 0)
645
- Category.update_counters([category.id, category_2.id], "categorizations_count" => 2)
646
- category.reload; category_2.reload
647
- assert_equal count_1 + 2, category.categorizations_count
648
- assert_equal count_2 + 2, category_2.categorizations_count
649
- end
650
-
651
- def test_update_all
652
- assert_equal Topic.count, Topic.update_all("content = 'bulk updated!'")
653
- assert_equal "bulk updated!", Topic.find(1).content
654
- assert_equal "bulk updated!", Topic.find(2).content
655
-
656
- assert_equal Topic.count, Topic.update_all(['content = ?', 'bulk updated again!'])
657
- assert_equal "bulk updated again!", Topic.find(1).content
658
- assert_equal "bulk updated again!", Topic.find(2).content
659
-
660
- assert_equal Topic.count, Topic.update_all(['content = ?', nil])
661
- assert_nil Topic.find(1).content
662
- end
663
-
664
- def test_update_all_with_hash
665
- assert_not_nil Topic.find(1).last_read
666
- assert_equal Topic.count, Topic.update_all(:content => 'bulk updated with hash!', :last_read => nil)
667
- assert_equal "bulk updated with hash!", Topic.find(1).content
668
- assert_equal "bulk updated with hash!", Topic.find(2).content
669
- assert_nil Topic.find(1).last_read
670
- assert_nil Topic.find(2).last_read
671
- end
672
-
673
- def test_update_all_with_non_standard_table_name
674
- assert_equal 1, WarehouseThing.update_all(['value = ?', 0], ['id = ?', 1])
675
- assert_equal 0, WarehouseThing.find(1).value
676
- end
677
-
678
- if current_adapter?(:MysqlAdapter)
679
- def test_update_all_with_order_and_limit
680
- assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC')
681
- end
271
+ ActiveRecord::Base.table_name_prefix = ""
272
+ ActiveRecord::Base.table_name_suffix = ""
273
+ GUESSED_CLASSES.each(&:reset_table_name)
682
274
  end
683
275
 
684
- def test_update_all_ignores_order_without_limit_from_association
685
- author = authors(:david)
686
- assert_nothing_raised do
687
- assert_equal author.posts_with_comments_and_categories.length, author.posts_with_comments_and_categories.update_all([ "body = ?", "bulk update!" ])
688
- end
276
+ def test_table_name_guesses_with_inherited_prefixes_and_suffixes
277
+ GUESSED_CLASSES.each(&:reset_table_name)
278
+
279
+ CreditCard.table_name_prefix = "test_"
280
+ CreditCard.reset_table_name
281
+ Category.reset_table_name
282
+ assert_equal "test_credit_cards", CreditCard.table_name
283
+ assert_equal "categories", Category.table_name
284
+ CreditCard.table_name_suffix = "_test"
285
+ CreditCard.reset_table_name
286
+ Category.reset_table_name
287
+ assert_equal "test_credit_cards_test", CreditCard.table_name
288
+ assert_equal "categories", Category.table_name
289
+ CreditCard.table_name_prefix = ""
290
+ CreditCard.reset_table_name
291
+ Category.reset_table_name
292
+ assert_equal "credit_cards_test", CreditCard.table_name
293
+ assert_equal "categories", Category.table_name
294
+ CreditCard.table_name_suffix = ""
295
+ CreditCard.reset_table_name
296
+ Category.reset_table_name
297
+ assert_equal "credit_cards", CreditCard.table_name
298
+ assert_equal "categories", Category.table_name
299
+ ensure
300
+ CreditCard.table_name_prefix = ""
301
+ CreditCard.table_name_suffix = ""
302
+ GUESSED_CLASSES.each(&:reset_table_name)
689
303
  end
690
304
 
691
- def test_update_all_with_order_and_limit_updates_subset_only
692
- author = authors(:david)
693
- assert_nothing_raised do
694
- assert_equal 1, author.posts_sorted_by_id_limited.size
695
- assert_equal 2, author.posts_sorted_by_id_limited.find(:all, :limit => 2).size
696
- assert_equal 1, author.posts_sorted_by_id_limited.update_all([ "body = ?", "bulk update!" ])
697
- assert_equal "bulk update!", posts(:welcome).body
698
- assert_not_equal "bulk update!", posts(:thinking).body
305
+
306
+ if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
307
+ def test_update_all_with_order_and_limit
308
+ assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC')
699
309
  end
700
310
  end
701
-
702
- def test_update_many
703
- topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
704
- updated = Topic.update(topic_data.keys, topic_data.values)
705
-
706
- assert_equal 2, updated.size
707
- assert_equal "1 updated", Topic.find(1).content
708
- assert_equal "2 updated", Topic.find(2).content
709
- end
710
-
711
- def test_delete_all
712
- assert Topic.count > 0
713
-
714
- assert_equal Topic.count, Topic.delete_all
715
- end
716
-
717
- def test_update_by_condition
718
- Topic.update_all "content = 'bulk updated!'", ["approved = ?", true]
719
- assert_equal "Have a nice day", Topic.find(1).content
720
- assert_equal "bulk updated!", Topic.find(2).content
721
- end
722
-
723
- def test_attribute_present
724
- t = Topic.new
725
- t.title = "hello there!"
726
- t.written_on = Time.now
727
- assert t.attribute_present?("title")
728
- assert t.attribute_present?("written_on")
729
- assert !t.attribute_present?("content")
730
- end
731
-
732
- def test_attribute_keys_on_new_instance
733
- t = Topic.new
734
- assert_equal nil, t.title, "The topics table has a title column, so it should be nil"
735
- assert_raise(NoMethodError) { t.title2 }
736
- end
737
-
738
- def test_class_name
739
- assert_equal "Firm", ActiveRecord::Base.class_name("firms")
740
- assert_equal "Category", ActiveRecord::Base.class_name("categories")
741
- assert_equal "AccountHolder", ActiveRecord::Base.class_name("account_holder")
742
-
743
- ActiveRecord::Base.pluralize_table_names = false
744
- assert_equal "Firms", ActiveRecord::Base.class_name( "firms" )
745
- ActiveRecord::Base.pluralize_table_names = true
746
-
747
- ActiveRecord::Base.table_name_prefix = "test_"
748
- assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms" )
749
- ActiveRecord::Base.table_name_suffix = "_tests"
750
- assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms_tests" )
751
- ActiveRecord::Base.table_name_prefix = ""
752
- assert_equal "Firm", ActiveRecord::Base.class_name( "firms_tests" )
753
- ActiveRecord::Base.table_name_suffix = ""
754
- assert_equal "Firm", ActiveRecord::Base.class_name( "firms" )
755
- end
756
-
311
+
757
312
  def test_null_fields
758
313
  assert_nil Topic.find(1).parent_id
759
314
  assert_nil Topic.create("title" => "Hey you").parent_id
760
315
  end
761
-
316
+
762
317
  def test_default_values
763
318
  topic = Topic.new
764
319
  assert topic.approved?
765
320
  assert_nil topic.written_on
766
321
  assert_nil topic.bonus_time
767
322
  assert_nil topic.last_read
768
-
323
+
769
324
  topic.save
770
-
325
+
771
326
  topic = Topic.find(topic.id)
772
327
  assert topic.approved?
773
328
  assert_nil topic.last_read
774
-
329
+
775
330
  # Oracle has some funky default handling, so it requires a bit of
776
331
  # extra testing. See ticket #2788.
777
332
  if current_adapter?(:OracleAdapter)
@@ -792,7 +347,7 @@ class BasicsTest < ActiveRecord::TestCase
792
347
  assert_equal Time.utc(2000, 1, 1, 5, 42, 0), topic.bonus_time
793
348
  Topic.default_timezone = :local
794
349
  end
795
-
350
+
796
351
  def test_utc_as_time_zone_and_new
797
352
  Topic.default_timezone = :utc
798
353
  attributes = { "bonus_time(1i)"=>"2000",
@@ -806,17 +361,17 @@ class BasicsTest < ActiveRecord::TestCase
806
361
  Topic.default_timezone = :local
807
362
  end
808
363
  end
809
-
364
+
810
365
  def test_default_values_on_empty_strings
811
366
  topic = Topic.new
812
367
  topic.approved = nil
813
368
  topic.last_read = nil
814
-
369
+
815
370
  topic.save
816
-
371
+
817
372
  topic = Topic.find(topic.id)
818
373
  assert_nil topic.last_read
819
-
374
+
820
375
  # Sybase adapter does not allow nulls in boolean columns
821
376
  if current_adapter?(:SybaseAdapter)
822
377
  assert topic.approved == false
@@ -824,185 +379,41 @@ class BasicsTest < ActiveRecord::TestCase
824
379
  assert_nil topic.approved
825
380
  end
826
381
  end
827
-
382
+
828
383
  def test_equality
829
384
  assert_equal Topic.find(1), Topic.find(2).topic
830
385
  end
831
-
386
+
832
387
  def test_equality_of_new_records
833
388
  assert_not_equal Topic.new, Topic.new
834
389
  end
835
-
836
- def test_hashing
837
- assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ]
838
- end
839
390
 
840
- def test_delete_new_record
841
- client = Client.new
842
- client.delete
843
- assert client.frozen?
844
- end
845
-
846
- def test_delete_record_with_associations
847
- client = Client.find(3)
848
- client.delete
849
- assert client.frozen?
850
- assert_kind_of Firm, client.firm
851
- assert_raise(ActiveSupport::FrozenObjectError) { client.name = "something else" }
852
- end
853
-
854
- def test_destroy_new_record
855
- client = Client.new
856
- client.destroy
857
- assert client.frozen?
858
- end
859
-
860
- def test_destroy_record_with_associations
861
- client = Client.find(3)
862
- client.destroy
863
- assert client.frozen?
864
- assert_kind_of Firm, client.firm
865
- assert_raise(ActiveSupport::FrozenObjectError) { client.name = "something else" }
866
- end
867
-
868
- def test_update_attribute
869
- assert !Topic.find(1).approved?
870
- Topic.find(1).update_attribute("approved", true)
871
- assert Topic.find(1).approved?
872
-
873
- Topic.find(1).update_attribute(:approved, false)
874
- assert !Topic.find(1).approved?
875
- end
876
-
877
- def test_update_attributes
878
- topic = Topic.find(1)
879
- assert !topic.approved?
880
- assert_equal "The First Topic", topic.title
881
-
882
- topic.update_attributes("approved" => true, "title" => "The First Topic Updated")
883
- topic.reload
884
- assert topic.approved?
885
- assert_equal "The First Topic Updated", topic.title
886
-
887
- topic.update_attributes(:approved => false, :title => "The First Topic")
888
- topic.reload
889
- assert !topic.approved?
890
- assert_equal "The First Topic", topic.title
891
- end
892
-
893
- def test_update_attributes!
894
- reply = Reply.find(2)
895
- assert_equal "The Second Topic of the day", reply.title
896
- assert_equal "Have a nice day", reply.content
897
-
898
- reply.update_attributes!("title" => "The Second Topic of the day updated", "content" => "Have a nice evening")
899
- reply.reload
900
- assert_equal "The Second Topic of the day updated", reply.title
901
- assert_equal "Have a nice evening", reply.content
902
-
903
- reply.update_attributes!(:title => "The Second Topic of the day", :content => "Have a nice day")
904
- reply.reload
905
- assert_equal "The Second Topic of the day", reply.title
906
- assert_equal "Have a nice day", reply.content
907
-
908
- assert_raise(ActiveRecord::RecordInvalid) { reply.update_attributes!(:title => nil, :content => "Have a nice evening") }
909
- end
910
-
911
- def test_mass_assignment_should_raise_exception_if_accessible_and_protected_attribute_writers_are_both_used
912
- topic = TopicWithProtectedContentAndAccessibleAuthorName.new
913
- assert_raise(RuntimeError) { topic.attributes = { "author_name" => "me" } }
914
- assert_raise(RuntimeError) { topic.attributes = { "content" => "stuff" } }
915
- end
916
-
917
- def test_mass_assignment_protection
918
- firm = Firm.new
919
- firm.attributes = { "name" => "Next Angle", "rating" => 5 }
920
- assert_equal 1, firm.rating
921
- end
922
-
923
- def test_mass_assignment_protection_against_class_attribute_writers
924
- [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :colorize_logging,
925
- :default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method|
926
- assert Task.respond_to?(method)
927
- assert Task.respond_to?("#{method}=")
928
- assert Task.new.respond_to?(method)
929
- assert !Task.new.respond_to?("#{method}=")
930
- end
931
- end
932
-
933
- def test_customized_primary_key_remains_protected
934
- subscriber = Subscriber.new(:nick => 'webster123', :name => 'nice try')
935
- assert_nil subscriber.id
936
-
937
- keyboard = Keyboard.new(:key_number => 9, :name => 'nice try')
938
- assert_nil keyboard.id
939
- end
940
-
941
- def test_customized_primary_key_remains_protected_when_referred_to_as_id
942
- subscriber = Subscriber.new(:id => 'webster123', :name => 'nice try')
943
- assert_nil subscriber.id
944
-
945
- keyboard = Keyboard.new(:id => 9, :name => 'nice try')
946
- assert_nil keyboard.id
391
+ def test_equality_of_destroyed_records
392
+ topic_1 = Topic.new(:title => 'test_1')
393
+ topic_1.save
394
+ topic_2 = Topic.find(topic_1.id)
395
+ topic_1.destroy
396
+ assert_equal topic_1, topic_2
397
+ assert_equal topic_2, topic_1
947
398
  end
948
399
 
949
- def test_mass_assigning_invalid_attribute
950
- firm = Firm.new
951
-
952
- assert_raise(ActiveRecord::UnknownAttributeError) do
953
- firm.attributes = { "id" => 5, "type" => "Client", "i_dont_even_exist" => 20 }
954
- end
400
+ def test_hashing
401
+ assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ]
955
402
  end
956
403
 
957
- def test_mass_assignment_protection_on_defaults
958
- firm = Firm.new
959
- firm.attributes = { "id" => 5, "type" => "Client" }
960
- assert_nil firm.id
961
- assert_equal "Firm", firm[:type]
962
- end
963
-
964
- def test_mass_assignment_accessible
965
- reply = Reply.new("title" => "hello", "content" => "world", "approved" => true)
966
- reply.save
967
-
968
- assert reply.approved?
969
-
970
- reply.approved = false
971
- reply.save
972
-
973
- assert !reply.approved?
974
- end
975
-
976
- def test_mass_assignment_protection_inheritance
977
- assert_nil LoosePerson.accessible_attributes
978
- assert_equal Set.new([ 'credit_rating', 'administrator' ]), LoosePerson.protected_attributes
979
-
980
- assert_nil LooseDescendant.accessible_attributes
981
- assert_equal Set.new([ 'credit_rating', 'administrator', 'phone_number' ]), LooseDescendant.protected_attributes
982
-
983
- assert_nil LooseDescendantSecond.accessible_attributes
984
- assert_equal Set.new([ 'credit_rating', 'administrator', 'phone_number', 'name' ]), LooseDescendantSecond.protected_attributes, 'Running attr_protected twice in one class should merge the protections'
985
-
986
- assert_nil TightPerson.protected_attributes
987
- assert_equal Set.new([ 'name', 'address' ]), TightPerson.accessible_attributes
988
-
989
- assert_nil TightDescendant.protected_attributes
990
- assert_equal Set.new([ 'name', 'address', 'phone_number' ]), TightDescendant.accessible_attributes
991
- end
992
-
993
404
  def test_readonly_attributes
994
405
  assert_equal Set.new([ 'title' , 'comments_count' ]), ReadonlyTitlePost.readonly_attributes
995
-
406
+
996
407
  post = ReadonlyTitlePost.create(:title => "cannot change this", :body => "changeable")
997
408
  post.reload
998
409
  assert_equal "cannot change this", post.title
999
-
410
+
1000
411
  post.update_attributes(:title => "try to change", :body => "changed")
1001
412
  post.reload
1002
413
  assert_equal "cannot change this", post.title
1003
414
  assert_equal "changed", post.body
1004
415
  end
1005
-
416
+
1006
417
  def test_multiparameter_attributes_on_date
1007
418
  attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" }
1008
419
  topic = Topic.find(1)
@@ -1011,8 +422,26 @@ class BasicsTest < ActiveRecord::TestCase
1011
422
  # treats dates/times the same
1012
423
  assert_date_from_db Date.new(2004, 6, 24), topic.last_read.to_date
1013
424
  end
1014
-
1015
- def test_multiparameter_attributes_on_date_with_empty_date
425
+
426
+ def test_multiparameter_attributes_on_date_with_empty_year
427
+ attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "24" }
428
+ topic = Topic.find(1)
429
+ topic.attributes = attributes
430
+ # note that extra #to_date call allows test to pass for Oracle, which
431
+ # treats dates/times the same
432
+ assert_date_from_db Date.new(1, 6, 24), topic.last_read.to_date
433
+ end
434
+
435
+ def test_multiparameter_attributes_on_date_with_empty_month
436
+ attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "24" }
437
+ topic = Topic.find(1)
438
+ topic.attributes = attributes
439
+ # note that extra #to_date call allows test to pass for Oracle, which
440
+ # treats dates/times the same
441
+ assert_date_from_db Date.new(2004, 1, 24), topic.last_read.to_date
442
+ end
443
+
444
+ def test_multiparameter_attributes_on_date_with_empty_day
1016
445
  attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" }
1017
446
  topic = Topic.find(1)
1018
447
  topic.attributes = attributes
@@ -1020,14 +449,41 @@ class BasicsTest < ActiveRecord::TestCase
1020
449
  # treats dates/times the same
1021
450
  assert_date_from_db Date.new(2004, 6, 1), topic.last_read.to_date
1022
451
  end
1023
-
452
+
453
+ def test_multiparameter_attributes_on_date_with_empty_day_and_year
454
+ attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "" }
455
+ topic = Topic.find(1)
456
+ topic.attributes = attributes
457
+ # note that extra #to_date call allows test to pass for Oracle, which
458
+ # treats dates/times the same
459
+ assert_date_from_db Date.new(1, 6, 1), topic.last_read.to_date
460
+ end
461
+
462
+ def test_multiparameter_attributes_on_date_with_empty_day_and_month
463
+ attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "" }
464
+ topic = Topic.find(1)
465
+ topic.attributes = attributes
466
+ # note that extra #to_date call allows test to pass for Oracle, which
467
+ # treats dates/times the same
468
+ assert_date_from_db Date.new(2004, 1, 1), topic.last_read.to_date
469
+ end
470
+
471
+ def test_multiparameter_attributes_on_date_with_empty_year_and_month
472
+ attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "24" }
473
+ topic = Topic.find(1)
474
+ topic.attributes = attributes
475
+ # note that extra #to_date call allows test to pass for Oracle, which
476
+ # treats dates/times the same
477
+ assert_date_from_db Date.new(1, 1, 24), topic.last_read.to_date
478
+ end
479
+
1024
480
  def test_multiparameter_attributes_on_date_with_all_empty
1025
481
  attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "" }
1026
482
  topic = Topic.find(1)
1027
483
  topic.attributes = attributes
1028
484
  assert_nil topic.last_read
1029
485
  end
1030
-
486
+
1031
487
  def test_multiparameter_attributes_on_time
1032
488
  attributes = {
1033
489
  "written_on(1i)" => "2004", "written_on(2i)" => "6", "written_on(3i)" => "24",
@@ -1037,7 +493,7 @@ class BasicsTest < ActiveRecord::TestCase
1037
493
  topic.attributes = attributes
1038
494
  assert_equal Time.local(2004, 6, 24, 16, 24, 0), topic.written_on
1039
495
  end
1040
-
496
+
1041
497
  def test_multiparameter_attributes_on_time_with_old_date
1042
498
  attributes = {
1043
499
  "written_on(1i)" => "1850", "written_on(2i)" => "6", "written_on(3i)" => "24",
@@ -1048,7 +504,7 @@ class BasicsTest < ActiveRecord::TestCase
1048
504
  # testing against to_s(:db) representation because either a Time or a DateTime might be returned, depending on platform
1049
505
  assert_equal "1850-06-24 16:24:00", topic.written_on.to_s(:db)
1050
506
  end
1051
-
507
+
1052
508
  def test_multiparameter_attributes_on_time_with_utc
1053
509
  ActiveRecord::Base.default_timezone = :utc
1054
510
  attributes = {
@@ -1061,7 +517,7 @@ class BasicsTest < ActiveRecord::TestCase
1061
517
  ensure
1062
518
  ActiveRecord::Base.default_timezone = :local
1063
519
  end
1064
-
520
+
1065
521
  def test_multiparameter_attributes_on_time_with_time_zone_aware_attributes
1066
522
  ActiveRecord::Base.time_zone_aware_attributes = true
1067
523
  ActiveRecord::Base.default_timezone = :utc
@@ -1080,7 +536,7 @@ class BasicsTest < ActiveRecord::TestCase
1080
536
  ActiveRecord::Base.default_timezone = :local
1081
537
  Time.zone = nil
1082
538
  end
1083
-
539
+
1084
540
  def test_multiparameter_attributes_on_time_with_time_zone_aware_attributes_false
1085
541
  ActiveRecord::Base.time_zone_aware_attributes = false
1086
542
  Time.zone = ActiveSupport::TimeZone[-28800]
@@ -1095,7 +551,7 @@ class BasicsTest < ActiveRecord::TestCase
1095
551
  ensure
1096
552
  Time.zone = nil
1097
553
  end
1098
-
554
+
1099
555
  def test_multiparameter_attributes_on_time_with_skip_time_zone_conversion_for_attributes
1100
556
  ActiveRecord::Base.time_zone_aware_attributes = true
1101
557
  ActiveRecord::Base.default_timezone = :utc
@@ -1115,23 +571,26 @@ class BasicsTest < ActiveRecord::TestCase
1115
571
  Time.zone = nil
1116
572
  Topic.skip_time_zone_conversion_for_attributes = []
1117
573
  end
1118
-
1119
- def test_multiparameter_attributes_on_time_only_column_with_time_zone_aware_attributes_does_not_do_time_zone_conversion
1120
- ActiveRecord::Base.time_zone_aware_attributes = true
1121
- ActiveRecord::Base.default_timezone = :utc
1122
- Time.zone = ActiveSupport::TimeZone[-28800]
1123
- attributes = {
1124
- "bonus_time(1i)" => "2000", "bonus_time(2i)" => "1", "bonus_time(3i)" => "1",
1125
- "bonus_time(4i)" => "16", "bonus_time(5i)" => "24"
1126
- }
1127
- topic = Topic.find(1)
1128
- topic.attributes = attributes
1129
- assert_equal Time.utc(2000, 1, 1, 16, 24, 0), topic.bonus_time
1130
- assert topic.bonus_time.utc?
1131
- ensure
1132
- ActiveRecord::Base.time_zone_aware_attributes = false
1133
- ActiveRecord::Base.default_timezone = :local
1134
- Time.zone = nil
574
+
575
+ # Oracle, and Sybase do not have a TIME datatype.
576
+ unless current_adapter?(:OracleAdapter, :SybaseAdapter)
577
+ def test_multiparameter_attributes_on_time_only_column_with_time_zone_aware_attributes_does_not_do_time_zone_conversion
578
+ ActiveRecord::Base.time_zone_aware_attributes = true
579
+ ActiveRecord::Base.default_timezone = :utc
580
+ Time.zone = ActiveSupport::TimeZone[-28800]
581
+ attributes = {
582
+ "bonus_time(1i)" => "2000", "bonus_time(2i)" => "1", "bonus_time(3i)" => "1",
583
+ "bonus_time(4i)" => "16", "bonus_time(5i)" => "24"
584
+ }
585
+ topic = Topic.find(1)
586
+ topic.attributes = attributes
587
+ assert_equal Time.utc(2000, 1, 1, 16, 24, 0), topic.bonus_time
588
+ assert topic.bonus_time.utc?
589
+ ensure
590
+ ActiveRecord::Base.time_zone_aware_attributes = false
591
+ ActiveRecord::Base.default_timezone = :local
592
+ Time.zone = nil
593
+ end
1135
594
  end
1136
595
 
1137
596
  def test_multiparameter_attributes_on_time_with_empty_seconds
@@ -1143,16 +602,7 @@ class BasicsTest < ActiveRecord::TestCase
1143
602
  topic.attributes = attributes
1144
603
  assert_equal Time.local(2004, 6, 24, 16, 24, 0), topic.written_on
1145
604
  end
1146
-
1147
- def test_multiparameter_mass_assignment_protector
1148
- task = Task.new
1149
- time = Time.mktime(2000, 1, 1, 1)
1150
- task.starting = time
1151
- attributes = { "starting(1i)" => "2004", "starting(2i)" => "6", "starting(3i)" => "24" }
1152
- task.attributes = attributes
1153
- assert_equal time, task.starting
1154
- end
1155
-
605
+
1156
606
  def test_multiparameter_assignment_of_aggregation
1157
607
  customer = Customer.new
1158
608
  address = Address.new("The Street", "The City", "The Country")
@@ -1160,7 +610,7 @@ class BasicsTest < ActiveRecord::TestCase
1160
610
  customer.attributes = attributes
1161
611
  assert_equal address, customer.address
1162
612
  end
1163
-
613
+
1164
614
  def test_attributes_on_dummy_time
1165
615
  # Oracle, and Sybase do not have a TIME datatype.
1166
616
  return true if current_adapter?(:OracleAdapter, :SybaseAdapter)
@@ -1172,42 +622,42 @@ class BasicsTest < ActiveRecord::TestCase
1172
622
  topic.attributes = attributes
1173
623
  assert_equal Time.local(2000, 1, 1, 5, 42, 0), topic.bonus_time
1174
624
  end
1175
-
625
+
1176
626
  def test_boolean
1177
- b_nil = Booleantest.create({ "value" => nil })
627
+ b_nil = Boolean.create({ "value" => nil })
1178
628
  nil_id = b_nil.id
1179
- b_false = Booleantest.create({ "value" => false })
629
+ b_false = Boolean.create({ "value" => false })
1180
630
  false_id = b_false.id
1181
- b_true = Booleantest.create({ "value" => true })
631
+ b_true = Boolean.create({ "value" => true })
1182
632
  true_id = b_true.id
1183
633
 
1184
- b_nil = Booleantest.find(nil_id)
634
+ b_nil = Boolean.find(nil_id)
1185
635
  assert_nil b_nil.value
1186
- b_false = Booleantest.find(false_id)
636
+ b_false = Boolean.find(false_id)
1187
637
  assert !b_false.value?
1188
- b_true = Booleantest.find(true_id)
638
+ b_true = Boolean.find(true_id)
1189
639
  assert b_true.value?
1190
640
  end
1191
-
641
+
1192
642
  def test_boolean_cast_from_string
1193
- b_blank = Booleantest.create({ "value" => "" })
643
+ b_blank = Boolean.create({ "value" => "" })
1194
644
  blank_id = b_blank.id
1195
- b_false = Booleantest.create({ "value" => "0" })
645
+ b_false = Boolean.create({ "value" => "0" })
1196
646
  false_id = b_false.id
1197
- b_true = Booleantest.create({ "value" => "1" })
647
+ b_true = Boolean.create({ "value" => "1" })
1198
648
  true_id = b_true.id
1199
649
 
1200
- b_blank = Booleantest.find(blank_id)
650
+ b_blank = Boolean.find(blank_id)
1201
651
  assert_nil b_blank.value
1202
- b_false = Booleantest.find(false_id)
652
+ b_false = Boolean.find(false_id)
1203
653
  assert !b_false.value?
1204
- b_true = Booleantest.find(true_id)
654
+ b_true = Boolean.find(true_id)
1205
655
  assert b_true.value?
1206
656
  end
1207
657
 
1208
658
  def test_new_record_returns_boolean
1209
- assert_equal Topic.new.new_record?, true
1210
- assert_equal Topic.find(1).new_record?, false
659
+ assert_equal false, Topic.new.persisted?
660
+ assert_equal true, Topic.find(1).persisted?
1211
661
  end
1212
662
 
1213
663
  def test_clone
@@ -1215,55 +665,113 @@ class BasicsTest < ActiveRecord::TestCase
1215
665
  cloned_topic = nil
1216
666
  assert_nothing_raised { cloned_topic = topic.clone }
1217
667
  assert_equal topic.title, cloned_topic.title
1218
- assert cloned_topic.new_record?
1219
-
668
+ assert !cloned_topic.persisted?
669
+
1220
670
  # test if the attributes have been cloned
1221
671
  topic.title = "a"
1222
672
  cloned_topic.title = "b"
1223
673
  assert_equal "a", topic.title
1224
674
  assert_equal "b", cloned_topic.title
1225
-
675
+
1226
676
  # test if the attribute values have been cloned
1227
677
  topic.title = {"a" => "b"}
1228
678
  cloned_topic = topic.clone
1229
679
  cloned_topic.title["a"] = "c"
1230
680
  assert_equal "b", topic.title["a"]
1231
-
1232
- #test if attributes set as part of after_initialize are cloned correctly
681
+
682
+ # test if attributes set as part of after_initialize are cloned correctly
1233
683
  assert_equal topic.author_email_address, cloned_topic.author_email_address
1234
-
684
+
1235
685
  # test if saved clone object differs from original
1236
686
  cloned_topic.save
1237
- assert !cloned_topic.new_record?
1238
- assert cloned_topic.id != topic.id
687
+ assert cloned_topic.persisted?
688
+ assert_not_equal cloned_topic.id, topic.id
1239
689
  end
1240
-
690
+
1241
691
  def test_clone_with_aggregate_of_same_name_as_attribute
1242
692
  dev = DeveloperWithAggregate.find(1)
1243
693
  assert_kind_of DeveloperSalary, dev.salary
1244
-
694
+
1245
695
  clone = nil
1246
696
  assert_nothing_raised { clone = dev.clone }
1247
697
  assert_kind_of DeveloperSalary, clone.salary
1248
698
  assert_equal dev.salary.amount, clone.salary.amount
1249
- assert clone.new_record?
1250
-
699
+ assert !clone.persisted?
700
+
1251
701
  # test if the attributes have been cloned
1252
702
  original_amount = clone.salary.amount
1253
703
  dev.salary.amount = 1
1254
704
  assert_equal original_amount, clone.salary.amount
1255
-
705
+
1256
706
  assert clone.save
1257
- assert !clone.new_record?
1258
- assert clone.id != dev.id
707
+ assert clone.persisted?
708
+ assert_not_equal clone.id, dev.id
709
+ end
710
+
711
+ def test_clone_does_not_clone_associations
712
+ author = authors(:david)
713
+ assert_not_equal [], author.posts
714
+
715
+ author_clone = author.clone
716
+ assert_equal [], author_clone.posts
1259
717
  end
1260
-
718
+
1261
719
  def test_clone_preserves_subtype
1262
720
  clone = nil
1263
721
  assert_nothing_raised { clone = Company.find(3).clone }
1264
722
  assert_kind_of Client, clone
1265
723
  end
1266
-
724
+
725
+ def test_clone_of_new_object_with_defaults
726
+ developer = Developer.new
727
+ assert !developer.name_changed?
728
+ assert !developer.salary_changed?
729
+
730
+ cloned_developer = developer.clone
731
+ assert !cloned_developer.name_changed?
732
+ assert !cloned_developer.salary_changed?
733
+ end
734
+
735
+ def test_clone_of_new_object_marks_attributes_as_dirty
736
+ developer = Developer.new :name => 'Bjorn', :salary => 100000
737
+ assert developer.name_changed?
738
+ assert developer.salary_changed?
739
+
740
+ cloned_developer = developer.clone
741
+ assert cloned_developer.name_changed?
742
+ assert cloned_developer.salary_changed?
743
+ end
744
+
745
+ def test_clone_of_new_object_marks_as_dirty_only_changed_attributes
746
+ developer = Developer.new :name => 'Bjorn'
747
+ assert developer.name_changed? # obviously
748
+ assert !developer.salary_changed? # attribute has non-nil default value, so treated as not changed
749
+
750
+ cloned_developer = developer.clone
751
+ assert cloned_developer.name_changed?
752
+ assert !cloned_developer.salary_changed? # ... and cloned instance should behave same
753
+ end
754
+
755
+ def test_clone_of_saved_object_marks_attributes_as_dirty
756
+ developer = Developer.create! :name => 'Bjorn', :salary => 100000
757
+ assert !developer.name_changed?
758
+ assert !developer.salary_changed?
759
+
760
+ cloned_developer = developer.clone
761
+ assert cloned_developer.name_changed? # both attributes differ from defaults
762
+ assert cloned_developer.salary_changed?
763
+ end
764
+
765
+ def test_clone_of_saved_object_marks_as_dirty_only_changed_attributes
766
+ developer = Developer.create! :name => 'Bjorn'
767
+ assert !developer.name_changed? # both attributes of saved object should be threated as not changed
768
+ assert !developer.salary_changed?
769
+
770
+ cloned_developer = developer.clone
771
+ assert cloned_developer.name_changed? # ... but on cloned object should be
772
+ assert !cloned_developer.salary_changed? # ... BUT salary has non-nil default which should be threated as not changed on cloned instance
773
+ end
774
+
1267
775
  def test_bignum
1268
776
  company = Company.find(1)
1269
777
  company.rating = 2147483647
@@ -1271,29 +779,29 @@ class BasicsTest < ActiveRecord::TestCase
1271
779
  company = Company.find(1)
1272
780
  assert_equal 2147483647, company.rating
1273
781
  end
1274
-
782
+
1275
783
  # TODO: extend defaults tests to other databases!
1276
784
  if current_adapter?(:PostgreSQLAdapter)
1277
785
  def test_default
1278
786
  default = Default.new
1279
-
787
+
1280
788
  # fixed dates / times
1281
789
  assert_equal Date.new(2004, 1, 1), default.fixed_date
1282
790
  assert_equal Time.local(2004, 1,1,0,0,0,0), default.fixed_time
1283
-
791
+
1284
792
  # char types
1285
793
  assert_equal 'Y', default.char1
1286
794
  assert_equal 'a varchar field', default.char2
1287
795
  assert_equal 'a text field', default.char3
1288
796
  end
1289
-
797
+
1290
798
  class Geometric < ActiveRecord::Base; end
1291
799
  def test_geometric_content
1292
-
800
+
1293
801
  # accepted format notes:
1294
802
  # ()'s aren't required
1295
803
  # values can be a mix of float or integer
1296
-
804
+
1297
805
  g = Geometric.new(
1298
806
  :a_point => '(5.0, 6.1)',
1299
807
  #:a_line => '((2.0, 3), (5.5, 7.0))' # line type is currently unsupported in postgresql
@@ -1303,25 +811,25 @@ class BasicsTest < ActiveRecord::TestCase
1303
811
  :a_polygon => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))',
1304
812
  :a_circle => '<(5.3, 10.4), 2>'
1305
813
  )
1306
-
814
+
1307
815
  assert g.save
1308
-
816
+
1309
817
  # Reload and check that we have all the geometric attributes.
1310
818
  h = Geometric.find(g.id)
1311
-
819
+
1312
820
  assert_equal '(5,6.1)', h.a_point
1313
821
  assert_equal '[(2,3),(5.5,7)]', h.a_line_segment
1314
822
  assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner
1315
823
  assert_equal '[(2,3),(5.5,7),(8.5,11)]', h.a_path
1316
824
  assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon
1317
825
  assert_equal '<(5.3,10.4),2>', h.a_circle
1318
-
826
+
1319
827
  # use a geometric function to test for an open path
1320
828
  objs = Geometric.find_by_sql ["select isopen(a_path) from geometrics where id = ?", g.id]
1321
829
  assert_equal objs[0].isopen, 't'
1322
-
830
+
1323
831
  # test alternate formats when defining the geometric types
1324
-
832
+
1325
833
  g = Geometric.new(
1326
834
  :a_point => '5.0, 6.1',
1327
835
  #:a_line => '((2.0, 3), (5.5, 7.0))' # line type is currently unsupported in postgresql
@@ -1331,29 +839,29 @@ class BasicsTest < ActiveRecord::TestCase
1331
839
  :a_polygon => '2.0, 3, 5.5, 7.0, 8.5, 11.0',
1332
840
  :a_circle => '((5.3, 10.4), 2)'
1333
841
  )
1334
-
842
+
1335
843
  assert g.save
1336
-
844
+
1337
845
  # Reload and check that we have all the geometric attributes.
1338
846
  h = Geometric.find(g.id)
1339
-
847
+
1340
848
  assert_equal '(5,6.1)', h.a_point
1341
849
  assert_equal '[(2,3),(5.5,7)]', h.a_line_segment
1342
850
  assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner
1343
851
  assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_path
1344
852
  assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon
1345
853
  assert_equal '<(5.3,10.4),2>', h.a_circle
1346
-
854
+
1347
855
  # use a geometric function to test for an closed path
1348
856
  objs = Geometric.find_by_sql ["select isclosed(a_path) from geometrics where id = ?", g.id]
1349
857
  assert_equal objs[0].isclosed, 't'
1350
858
  end
1351
859
  end
1352
-
860
+
1353
861
  class NumericData < ActiveRecord::Base
1354
862
  self.table_name = 'numeric_data'
1355
863
  end
1356
-
864
+
1357
865
  def test_numeric_fields
1358
866
  m = NumericData.new(
1359
867
  :bank_balance => 1586.43,
@@ -1362,10 +870,10 @@ class BasicsTest < ActiveRecord::TestCase
1362
870
  :my_house_population => 3
1363
871
  )
1364
872
  assert m.save
1365
-
873
+
1366
874
  m1 = NumericData.find(m.id)
1367
875
  assert_not_nil m1
1368
-
876
+
1369
877
  # As with migration_test.rb, we should make world_population >= 2**62
1370
878
  # to cover 64-bit platforms and test it is a Bignum, but the main thing
1371
879
  # is that it's an Integer.
@@ -1381,24 +889,24 @@ class BasicsTest < ActiveRecord::TestCase
1381
889
  assert_kind_of BigDecimal, m1.my_house_population
1382
890
  end
1383
891
  assert_equal 3, m1.my_house_population
1384
-
892
+
1385
893
  assert_kind_of BigDecimal, m1.bank_balance
1386
894
  assert_equal BigDecimal("1586.43"), m1.bank_balance
1387
-
895
+
1388
896
  assert_kind_of BigDecimal, m1.big_bank_balance
1389
897
  assert_equal BigDecimal("1000234000567.95"), m1.big_bank_balance
1390
898
  end
1391
-
899
+
1392
900
  def test_auto_id
1393
901
  auto = AutoId.new
1394
902
  auto.save
1395
- assert (auto.id > 0)
903
+ assert(auto.id > 0)
1396
904
  end
1397
-
905
+
1398
906
  def quote_column_name(name)
1399
907
  "<#{name}>"
1400
908
  end
1401
-
909
+
1402
910
  def test_quote_keys
1403
911
  ar = AutoId.new
1404
912
  source = {"foo" => "bar", "baz" => "quux"}
@@ -1407,13 +915,13 @@ class BasicsTest < ActiveRecord::TestCase
1407
915
  assert_equal("<foo>", inverted["bar"])
1408
916
  assert_equal("<baz>", inverted["quux"])
1409
917
  end
1410
-
918
+
1411
919
  def test_sql_injection_via_find
1412
920
  assert_raise(ActiveRecord::RecordNotFound, ActiveRecord::StatementInvalid) do
1413
921
  Topic.find("123456 OR id > 0")
1414
922
  end
1415
923
  end
1416
-
924
+
1417
925
  def test_column_name_properly_quoted
1418
926
  col_record = ColumnName.new
1419
927
  col_record.references = 40
@@ -1423,21 +931,25 @@ class BasicsTest < ActiveRecord::TestCase
1423
931
  assert_not_nil c2 = ColumnName.find(col_record.id)
1424
932
  assert_equal(41, c2.references)
1425
933
  end
1426
-
934
+
1427
935
  def test_quoting_arrays
1428
936
  replies = Reply.find(:all, :conditions => [ "id IN (?)", topics(:first).replies.collect(&:id) ])
1429
937
  assert_equal topics(:first).replies.size, replies.size
1430
-
938
+
1431
939
  replies = Reply.find(:all, :conditions => [ "id IN (?)", [] ])
1432
940
  assert_equal 0, replies.size
1433
941
  end
1434
-
942
+
1435
943
  MyObject = Struct.new :attribute1, :attribute2
1436
-
944
+
1437
945
  def test_serialized_attribute
946
+ Topic.serialize("content", MyObject)
947
+
1438
948
  myobj = MyObject.new('value1', 'value2')
1439
949
  topic = Topic.create("content" => myobj)
1440
- Topic.serialize("content", MyObject)
950
+ assert_equal(myobj, topic.content)
951
+
952
+ topic.reload
1441
953
  assert_equal(myobj, topic.content)
1442
954
  end
1443
955
 
@@ -1446,7 +958,7 @@ class BasicsTest < ActiveRecord::TestCase
1446
958
  topic = Topic.create("content" => myobj).reload
1447
959
  assert_equal(myobj, topic.content)
1448
960
  end
1449
-
961
+
1450
962
  def test_serialized_string_attribute
1451
963
  myobj = "Yes"
1452
964
  topic = Topic.create("content" => myobj).reload
@@ -1458,7 +970,7 @@ class BasicsTest < ActiveRecord::TestCase
1458
970
  topic = Topic.new
1459
971
  assert_nil topic.content
1460
972
  end
1461
-
973
+
1462
974
  def test_should_raise_exception_on_serialized_attribute_with_type_mismatch
1463
975
  myobj = MyObject.new('value1', 'value2')
1464
976
  topic = Topic.new(:content => myobj)
@@ -1468,7 +980,7 @@ class BasicsTest < ActiveRecord::TestCase
1468
980
  ensure
1469
981
  Topic.serialize(:content)
1470
982
  end
1471
-
983
+
1472
984
  def test_serialized_attribute_with_class_constraint
1473
985
  settings = { "color" => "blue" }
1474
986
  Topic.serialize(:content, Hash)
@@ -1478,13 +990,13 @@ class BasicsTest < ActiveRecord::TestCase
1478
990
  ensure
1479
991
  Topic.serialize(:content)
1480
992
  end
1481
-
993
+
1482
994
  def test_quote
1483
995
  author_name = "\\ \001 ' \n \\n \""
1484
996
  topic = Topic.create('author_name' => author_name)
1485
997
  assert_equal author_name, Topic.find(topic.id).author_name
1486
998
  end
1487
-
999
+
1488
1000
  if RUBY_VERSION < '1.9'
1489
1001
  def test_quote_chars
1490
1002
  with_kcode('UTF8') do
@@ -1500,68 +1012,7 @@ class BasicsTest < ActiveRecord::TestCase
1500
1012
  end
1501
1013
  end
1502
1014
  end
1503
-
1504
- def test_class_level_destroy
1505
- should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
1506
- Topic.find(1).replies << should_be_destroyed_reply
1507
-
1508
- Topic.destroy(1)
1509
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
1510
- assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) }
1511
- end
1512
-
1513
- def test_class_level_delete
1514
- should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
1515
- Topic.find(1).replies << should_be_destroyed_reply
1516
-
1517
- Topic.delete(1)
1518
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
1519
- assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
1520
- end
1521
-
1522
- def test_increment_attribute
1523
- assert_equal 50, accounts(:signals37).credit_limit
1524
- accounts(:signals37).increment! :credit_limit
1525
- assert_equal 51, accounts(:signals37, :reload).credit_limit
1526
-
1527
- accounts(:signals37).increment(:credit_limit).increment!(:credit_limit)
1528
- assert_equal 53, accounts(:signals37, :reload).credit_limit
1529
- end
1530
-
1531
- def test_increment_nil_attribute
1532
- assert_nil topics(:first).parent_id
1533
- topics(:first).increment! :parent_id
1534
- assert_equal 1, topics(:first).parent_id
1535
- end
1536
-
1537
- def test_increment_attribute_by
1538
- assert_equal 50, accounts(:signals37).credit_limit
1539
- accounts(:signals37).increment! :credit_limit, 5
1540
- assert_equal 55, accounts(:signals37, :reload).credit_limit
1541
-
1542
- accounts(:signals37).increment(:credit_limit, 1).increment!(:credit_limit, 3)
1543
- assert_equal 59, accounts(:signals37, :reload).credit_limit
1544
- end
1545
-
1546
- def test_decrement_attribute
1547
- assert_equal 50, accounts(:signals37).credit_limit
1548
-
1549
- accounts(:signals37).decrement!(:credit_limit)
1550
- assert_equal 49, accounts(:signals37, :reload).credit_limit
1551
-
1552
- accounts(:signals37).decrement(:credit_limit).decrement!(:credit_limit)
1553
- assert_equal 47, accounts(:signals37, :reload).credit_limit
1554
- end
1555
-
1556
- def test_decrement_attribute_by
1557
- assert_equal 50, accounts(:signals37).credit_limit
1558
- accounts(:signals37).decrement! :credit_limit, 5
1559
- assert_equal 45, accounts(:signals37, :reload).credit_limit
1560
-
1561
- accounts(:signals37).decrement(:credit_limit, 1).decrement!(:credit_limit, 3)
1562
- assert_equal 41, accounts(:signals37, :reload).credit_limit
1563
- end
1564
-
1015
+
1565
1016
  def test_toggle_attribute
1566
1017
  assert !topics(:first).approved?
1567
1018
  topics(:first).toggle!(:approved)
@@ -1572,7 +1023,7 @@ class BasicsTest < ActiveRecord::TestCase
1572
1023
  topic.reload
1573
1024
  assert topic.approved?
1574
1025
  end
1575
-
1026
+
1576
1027
  def test_reload
1577
1028
  t1 = Topic.find(1)
1578
1029
  t2 = Topic.find(1)
@@ -1581,19 +1032,25 @@ class BasicsTest < ActiveRecord::TestCase
1581
1032
  t2.reload
1582
1033
  assert_equal t1.title, t2.title
1583
1034
  end
1584
-
1035
+
1036
+ def test_reload_with_exclusive_scope
1037
+ dev = DeveloperCalledDavid.first
1038
+ dev.update_attributes!( :name => "NotDavid" )
1039
+ assert_equal dev, dev.reload
1040
+ end
1041
+
1585
1042
  def test_define_attr_method_with_value
1586
1043
  k = Class.new( ActiveRecord::Base )
1587
1044
  k.send(:define_attr_method, :table_name, "foo")
1588
1045
  assert_equal "foo", k.table_name
1589
1046
  end
1590
-
1047
+
1591
1048
  def test_define_attr_method_with_block
1592
1049
  k = Class.new( ActiveRecord::Base )
1593
1050
  k.send(:define_attr_method, :primary_key) { "sys_" + original_primary_key }
1594
1051
  assert_equal "sys_id", k.primary_key
1595
1052
  end
1596
-
1053
+
1597
1054
  def test_set_table_name_with_value
1598
1055
  k = Class.new( ActiveRecord::Base )
1599
1056
  k.table_name = "foo"
@@ -1601,13 +1058,25 @@ class BasicsTest < ActiveRecord::TestCase
1601
1058
  k.set_table_name "bar"
1602
1059
  assert_equal "bar", k.table_name
1603
1060
  end
1604
-
1061
+
1062
+ def test_quoted_table_name_after_set_table_name
1063
+ klass = Class.new(ActiveRecord::Base)
1064
+
1065
+ klass.set_table_name "foo"
1066
+ assert_equal "foo", klass.table_name
1067
+ assert_equal klass.connection.quote_table_name("foo"), klass.quoted_table_name
1068
+
1069
+ klass.set_table_name "bar"
1070
+ assert_equal "bar", klass.table_name
1071
+ assert_equal klass.connection.quote_table_name("bar"), klass.quoted_table_name
1072
+ end
1073
+
1605
1074
  def test_set_table_name_with_block
1606
1075
  k = Class.new( ActiveRecord::Base )
1607
1076
  k.set_table_name { "ks" }
1608
1077
  assert_equal "ks", k.table_name
1609
1078
  end
1610
-
1079
+
1611
1080
  def test_set_primary_key_with_value
1612
1081
  k = Class.new( ActiveRecord::Base )
1613
1082
  k.primary_key = "foo"
@@ -1615,13 +1084,13 @@ class BasicsTest < ActiveRecord::TestCase
1615
1084
  k.set_primary_key "bar"
1616
1085
  assert_equal "bar", k.primary_key
1617
1086
  end
1618
-
1087
+
1619
1088
  def test_set_primary_key_with_block
1620
1089
  k = Class.new( ActiveRecord::Base )
1621
1090
  k.set_primary_key { "sys_" + original_primary_key }
1622
1091
  assert_equal "sys_id", k.primary_key
1623
1092
  end
1624
-
1093
+
1625
1094
  def test_set_inheritance_column_with_value
1626
1095
  k = Class.new( ActiveRecord::Base )
1627
1096
  k.inheritance_column = "foo"
@@ -1629,26 +1098,26 @@ class BasicsTest < ActiveRecord::TestCase
1629
1098
  k.set_inheritance_column "bar"
1630
1099
  assert_equal "bar", k.inheritance_column
1631
1100
  end
1632
-
1101
+
1633
1102
  def test_set_inheritance_column_with_block
1634
1103
  k = Class.new( ActiveRecord::Base )
1635
1104
  k.set_inheritance_column { original_inheritance_column + "_id" }
1636
1105
  assert_equal "type_id", k.inheritance_column
1637
1106
  end
1638
-
1107
+
1639
1108
  def test_count_with_join
1640
1109
  res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'"
1641
-
1110
+
1642
1111
  res2 = Post.count(:conditions => "posts.#{QUOTED_TYPE} = 'Post'", :joins => "LEFT JOIN comments ON posts.id=comments.post_id")
1643
1112
  assert_equal res, res2
1644
-
1113
+
1645
1114
  res3 = nil
1646
1115
  assert_nothing_raised do
1647
1116
  res3 = Post.count(:conditions => "posts.#{QUOTED_TYPE} = 'Post'",
1648
1117
  :joins => "LEFT JOIN comments ON posts.id=comments.post_id")
1649
1118
  end
1650
1119
  assert_equal res, res3
1651
-
1120
+
1652
1121
  res4 = Post.count_by_sql "SELECT COUNT(p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1653
1122
  res5 = nil
1654
1123
  assert_nothing_raised do
@@ -1656,104 +1125,82 @@ class BasicsTest < ActiveRecord::TestCase
1656
1125
  :joins => "p, comments co",
1657
1126
  :select => "p.id")
1658
1127
  end
1659
-
1128
+
1660
1129
  assert_equal res4, res5
1661
-
1662
- unless current_adapter?(:SQLite2Adapter, :DeprecatedSQLiteAdapter)
1663
- res6 = Post.count_by_sql "SELECT COUNT(DISTINCT p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1664
- res7 = nil
1665
- assert_nothing_raised do
1666
- res7 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id",
1667
- :joins => "p, comments co",
1668
- :select => "p.id",
1669
- :distinct => true)
1670
- end
1671
- assert_equal res6, res7
1130
+
1131
+ res6 = Post.count_by_sql "SELECT COUNT(DISTINCT p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1132
+ res7 = nil
1133
+ assert_nothing_raised do
1134
+ res7 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id",
1135
+ :joins => "p, comments co",
1136
+ :select => "p.id",
1137
+ :distinct => true)
1672
1138
  end
1139
+ assert_equal res6, res7
1673
1140
  end
1674
-
1675
- def test_clear_association_cache_stored
1676
- firm = Firm.find(1)
1677
- assert_kind_of Firm, firm
1678
-
1679
- firm.clear_association_cache
1680
- assert_equal Firm.find(1).clients.collect{ |x| x.name }.sort, firm.clients.collect{ |x| x.name }.sort
1681
- end
1682
-
1683
- def test_clear_association_cache_new_record
1684
- firm = Firm.new
1685
- client_stored = Client.find(3)
1686
- client_new = Client.new
1687
- client_new.name = "The Joneses"
1688
- clients = [ client_stored, client_new ]
1689
-
1690
- firm.clients << clients
1691
- assert_equal clients.map(&:name).to_set, firm.clients.map(&:name).to_set
1692
-
1693
- firm.clear_association_cache
1694
- assert_equal clients.map(&:name).to_set, firm.clients.map(&:name).to_set
1695
- end
1696
-
1141
+
1697
1142
  def test_interpolate_sql
1698
1143
  assert_nothing_raised { Category.new.send(:interpolate_sql, 'foo@bar') }
1699
1144
  assert_nothing_raised { Category.new.send(:interpolate_sql, 'foo bar) baz') }
1700
1145
  assert_nothing_raised { Category.new.send(:interpolate_sql, 'foo bar} baz') }
1701
1146
  end
1702
-
1147
+
1703
1148
  def test_scoped_find_conditions
1704
- scoped_developers = Developer.with_scope(:find => { :conditions => 'salary > 90000' }) do
1149
+ scoped_developers = Developer.send(:with_scope, :find => { :conditions => 'salary > 90000' }) do
1705
1150
  Developer.find(:all, :conditions => 'id < 5')
1706
1151
  end
1707
1152
  assert !scoped_developers.include?(developers(:david)) # David's salary is less than 90,000
1708
1153
  assert_equal 3, scoped_developers.size
1709
1154
  end
1710
-
1155
+
1711
1156
  def test_scoped_find_limit_offset
1712
- scoped_developers = Developer.with_scope(:find => { :limit => 3, :offset => 2 }) do
1157
+ scoped_developers = Developer.send(:with_scope, :find => { :limit => 3, :offset => 2 }) do
1713
1158
  Developer.find(:all, :order => 'id')
1714
1159
  end
1715
1160
  assert !scoped_developers.include?(developers(:david))
1716
1161
  assert !scoped_developers.include?(developers(:jamis))
1717
1162
  assert_equal 3, scoped_developers.size
1718
-
1163
+
1719
1164
  # Test without scoped find conditions to ensure we get the whole thing
1720
1165
  developers = Developer.find(:all, :order => 'id')
1721
1166
  assert_equal Developer.count, developers.size
1722
1167
  end
1723
-
1168
+
1724
1169
  def test_scoped_find_order
1725
1170
  # Test order in scope
1726
- scoped_developers = Developer.with_scope(:find => { :limit => 1, :order => 'salary DESC' }) do
1171
+ scoped_developers = Developer.send(:with_scope, :find => { :limit => 1, :order => 'salary DESC' }) do
1727
1172
  Developer.find(:all)
1728
1173
  end
1729
1174
  assert_equal 'Jamis', scoped_developers.first.name
1730
1175
  assert scoped_developers.include?(developers(:jamis))
1731
1176
  # Test scope without order and order in find
1732
- scoped_developers = Developer.with_scope(:find => { :limit => 1 }) do
1177
+ scoped_developers = Developer.send(:with_scope, :find => { :limit => 1 }) do
1733
1178
  Developer.find(:all, :order => 'salary DESC')
1734
1179
  end
1735
- # Test scope order + find order, find has priority
1736
- scoped_developers = Developer.with_scope(:find => { :limit => 3, :order => 'id DESC' }) do
1180
+ # Test scope order + find order, order has priority
1181
+ scoped_developers = Developer.send(:with_scope, :find => { :limit => 3, :order => 'id DESC' }) do
1737
1182
  Developer.find(:all, :order => 'salary ASC')
1738
1183
  end
1739
1184
  assert scoped_developers.include?(developers(:poor_jamis))
1740
- assert scoped_developers.include?(developers(:david))
1741
- assert scoped_developers.include?(developers(:dev_10))
1185
+ assert ! scoped_developers.include?(developers(:david))
1186
+ assert ! scoped_developers.include?(developers(:jamis))
1187
+ assert_equal 3, scoped_developers.size
1188
+
1742
1189
  # Test without scoped find conditions to ensure we get the right thing
1743
- developers = Developer.find(:all, :order => 'id', :limit => 1)
1744
- assert scoped_developers.include?(developers(:david))
1190
+ assert ! scoped_developers.include?(Developer.find(1))
1191
+ assert scoped_developers.include?(Developer.find(11))
1745
1192
  end
1746
-
1193
+
1747
1194
  def test_scoped_find_limit_offset_including_has_many_association
1748
- topics = Topic.with_scope(:find => {:limit => 1, :offset => 1, :include => :replies}) do
1195
+ topics = Topic.send(:with_scope, :find => {:limit => 1, :offset => 1, :include => :replies}) do
1749
1196
  Topic.find(:all, :order => "topics.id")
1750
1197
  end
1751
1198
  assert_equal 1, topics.size
1752
1199
  assert_equal 2, topics.first.id
1753
1200
  end
1754
-
1201
+
1755
1202
  def test_scoped_find_order_including_has_many_association
1756
- developers = Developer.with_scope(:find => { :order => 'developers.salary DESC', :include => :projects }) do
1203
+ developers = Developer.send(:with_scope, :find => { :order => 'developers.salary DESC', :include => :projects }) do
1757
1204
  Developer.find(:all)
1758
1205
  end
1759
1206
  assert developers.size >= 2
@@ -1763,7 +1210,7 @@ class BasicsTest < ActiveRecord::TestCase
1763
1210
  end
1764
1211
 
1765
1212
  def test_scoped_find_with_group_and_having
1766
- developers = Developer.with_scope(:find => { :group => 'developers.salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
1213
+ developers = Developer.send(:with_scope, :find => { :group => 'developers.salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
1767
1214
  Developer.find(:all)
1768
1215
  end
1769
1216
  assert_equal 3, developers.size
@@ -1773,93 +1220,109 @@ class BasicsTest < ActiveRecord::TestCase
1773
1220
  last = Developer.find :last
1774
1221
  assert_equal last, Developer.find(:first, :order => 'id desc')
1775
1222
  end
1776
-
1223
+
1777
1224
  def test_last
1778
1225
  assert_equal Developer.find(:first, :order => 'id desc'), Developer.last
1779
1226
  end
1780
-
1227
+
1228
+ def test_all
1229
+ developers = Developer.all
1230
+ assert_kind_of Array, developers
1231
+ assert_equal Developer.find(:all), developers
1232
+ end
1233
+
1781
1234
  def test_all_with_conditions
1782
- assert_equal Developer.find(:all, :order => 'id desc'), Developer.all(:order => 'id desc')
1235
+ assert_equal Developer.find(:all, :order => 'id desc'), Developer.order('id desc').all
1783
1236
  end
1784
-
1237
+
1785
1238
  def test_find_ordered_last
1786
1239
  last = Developer.find :last, :order => 'developers.salary ASC'
1787
1240
  assert_equal last, Developer.find(:all, :order => 'developers.salary ASC').last
1788
1241
  end
1789
-
1242
+
1790
1243
  def test_find_reverse_ordered_last
1791
1244
  last = Developer.find :last, :order => 'developers.salary DESC'
1792
1245
  assert_equal last, Developer.find(:all, :order => 'developers.salary DESC').last
1793
1246
  end
1794
-
1247
+
1795
1248
  def test_find_multiple_ordered_last
1796
1249
  last = Developer.find :last, :order => 'developers.name, developers.salary DESC'
1797
1250
  assert_equal last, Developer.find(:all, :order => 'developers.name, developers.salary DESC').last
1798
1251
  end
1799
1252
 
1253
+ def test_find_keeps_multiple_order_values
1254
+ combined = Developer.find(:all, :order => 'developers.name, developers.salary')
1255
+ assert_equal combined, Developer.find(:all, :order => ['developers.name', 'developers.salary'])
1256
+ end
1257
+
1258
+ def test_find_keeps_multiple_group_values
1259
+ combined = Developer.find(:all, :group => 'developers.name, developers.salary, developers.id, developers.created_at, developers.updated_at')
1260
+ assert_equal combined, Developer.find(:all, :group => ['developers.name', 'developers.salary', 'developers.id', 'developers.created_at', 'developers.updated_at'])
1261
+ end
1262
+
1800
1263
  def test_find_symbol_ordered_last
1801
1264
  last = Developer.find :last, :order => :salary
1802
1265
  assert_equal last, Developer.find(:all, :order => :salary).last
1803
1266
  end
1804
1267
 
1805
1268
  def test_find_scoped_ordered_last
1806
- last_developer = Developer.with_scope(:find => { :order => 'developers.salary ASC' }) do
1269
+ last_developer = Developer.send(:with_scope, :find => { :order => 'developers.salary ASC' }) do
1807
1270
  Developer.find(:last)
1808
1271
  end
1809
1272
  assert_equal last_developer, Developer.find(:all, :order => 'developers.salary ASC').last
1810
1273
  end
1811
-
1274
+
1812
1275
  def test_abstract_class
1813
1276
  assert !ActiveRecord::Base.abstract_class?
1814
1277
  assert LoosePerson.abstract_class?
1815
1278
  assert !LooseDescendant.abstract_class?
1816
1279
  end
1817
-
1280
+
1818
1281
  def test_base_class
1819
1282
  assert_equal LoosePerson, LoosePerson.base_class
1820
1283
  assert_equal LooseDescendant, LooseDescendant.base_class
1821
1284
  assert_equal TightPerson, TightPerson.base_class
1822
1285
  assert_equal TightPerson, TightDescendant.base_class
1823
-
1286
+
1824
1287
  assert_equal Post, Post.base_class
1825
1288
  assert_equal Post, SpecialPost.base_class
1826
1289
  assert_equal Post, StiPost.base_class
1827
1290
  assert_equal SubStiPost, SubStiPost.base_class
1828
1291
  end
1829
-
1292
+
1830
1293
  def test_descends_from_active_record
1831
1294
  # Tries to call Object.abstract_class?
1832
1295
  assert_raise(NoMethodError) do
1833
1296
  ActiveRecord::Base.descends_from_active_record?
1834
1297
  end
1835
-
1298
+
1836
1299
  # Abstract subclass of AR::Base.
1837
1300
  assert LoosePerson.descends_from_active_record?
1838
-
1301
+
1839
1302
  # Concrete subclass of an abstract class.
1840
1303
  assert LooseDescendant.descends_from_active_record?
1841
-
1304
+
1842
1305
  # Concrete subclass of AR::Base.
1843
1306
  assert TightPerson.descends_from_active_record?
1844
-
1307
+
1845
1308
  # Concrete subclass of a concrete class but has no type column.
1846
1309
  assert TightDescendant.descends_from_active_record?
1847
-
1310
+
1848
1311
  # Concrete subclass of AR::Base.
1849
1312
  assert Post.descends_from_active_record?
1850
-
1313
+
1851
1314
  # Abstract subclass of a concrete class which has a type column.
1852
1315
  # This is pathological, as you'll never have Sub < Abstract < Concrete.
1853
1316
  assert !StiPost.descends_from_active_record?
1854
-
1317
+
1855
1318
  # Concrete subclasses an abstract class which has a type column.
1856
1319
  assert !SubStiPost.descends_from_active_record?
1857
1320
  end
1858
-
1321
+
1859
1322
  def test_find_on_abstract_base_class_doesnt_use_type_condition
1860
1323
  old_class = LooseDescendant
1861
1324
  Object.send :remove_const, :LooseDescendant
1862
-
1325
+
1863
1326
  descendant = old_class.create! :first_name => 'bob'
1864
1327
  assert_not_nil LoosePerson.find(descendant.id), "Should have found instance of LooseDescendant when finding abstract LoosePerson: #{descendant.inspect}"
1865
1328
  ensure
@@ -1867,189 +1330,55 @@ class BasicsTest < ActiveRecord::TestCase
1867
1330
  Object.const_set :LooseDescendant, old_class
1868
1331
  end
1869
1332
  end
1870
-
1333
+
1871
1334
  def test_assert_queries
1872
1335
  query = lambda { ActiveRecord::Base.connection.execute 'select count(*) from developers' }
1873
1336
  assert_queries(2) { 2.times { query.call } }
1874
1337
  assert_queries 1, &query
1875
1338
  assert_no_queries { assert true }
1876
1339
  end
1877
-
1878
- def test_to_xml
1879
- xml = REXML::Document.new(topics(:first).to_xml(:indent => 0))
1880
- bonus_time_in_current_timezone = topics(:first).bonus_time.xmlschema
1881
- written_on_in_current_timezone = topics(:first).written_on.xmlschema
1882
- last_read_in_current_timezone = topics(:first).last_read.xmlschema
1883
-
1884
- assert_equal "topic", xml.root.name
1885
- assert_equal "The First Topic" , xml.elements["//title"].text
1886
- assert_equal "David" , xml.elements["//author-name"].text
1887
-
1888
- assert_equal "1", xml.elements["//id"].text
1889
- assert_equal "integer" , xml.elements["//id"].attributes['type']
1890
-
1891
- assert_equal "1", xml.elements["//replies-count"].text
1892
- assert_equal "integer" , xml.elements["//replies-count"].attributes['type']
1893
-
1894
- assert_equal written_on_in_current_timezone, xml.elements["//written-on"].text
1895
- assert_equal "datetime" , xml.elements["//written-on"].attributes['type']
1896
-
1897
- assert_equal "--- Have a nice day\n" , xml.elements["//content"].text
1898
- assert_equal "yaml" , xml.elements["//content"].attributes['type']
1899
-
1900
- assert_equal "david@loudthinking.com", xml.elements["//author-email-address"].text
1901
-
1902
- assert_equal nil, xml.elements["//parent-id"].text
1903
- assert_equal "integer", xml.elements["//parent-id"].attributes['type']
1904
- assert_equal "true", xml.elements["//parent-id"].attributes['nil']
1905
-
1906
- if current_adapter?(:SybaseAdapter, :OracleAdapter)
1907
- assert_equal last_read_in_current_timezone, xml.elements["//last-read"].text
1908
- assert_equal "datetime" , xml.elements["//last-read"].attributes['type']
1909
- else
1910
- assert_equal "2004-04-15", xml.elements["//last-read"].text
1911
- assert_equal "date" , xml.elements["//last-read"].attributes['type']
1912
- end
1913
-
1914
- # Oracle and DB2 don't have true boolean or time-only fields
1915
- unless current_adapter?(:OracleAdapter, :DB2Adapter)
1916
- assert_equal "false", xml.elements["//approved"].text
1917
- assert_equal "boolean" , xml.elements["//approved"].attributes['type']
1918
-
1919
- assert_equal bonus_time_in_current_timezone, xml.elements["//bonus-time"].text
1920
- assert_equal "datetime" , xml.elements["//bonus-time"].attributes['type']
1921
- end
1922
- end
1923
-
1924
- def test_to_xml_skipping_attributes
1925
- xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :replies_count])
1926
- assert_equal "<topic>", xml.first(7)
1927
- assert !xml.include?(%(<title>The First Topic</title>))
1928
- assert xml.include?(%(<author-name>David</author-name>))
1929
-
1930
- xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :author_name, :replies_count])
1931
- assert !xml.include?(%(<title>The First Topic</title>))
1932
- assert !xml.include?(%(<author-name>David</author-name>))
1933
- end
1934
-
1935
- def test_to_xml_including_has_many_association
1936
- xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :include => :replies, :except => :replies_count)
1937
- assert_equal "<topic>", xml.first(7)
1938
- assert xml.include?(%(<replies type="array"><reply>))
1939
- assert xml.include?(%(<title>The Second Topic of the day</title>))
1940
- end
1941
-
1942
- def test_array_to_xml_including_has_many_association
1943
- xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :include => :replies)
1944
- assert xml.include?(%(<replies type="array"><reply>))
1945
- end
1946
-
1947
- def test_array_to_xml_including_methods
1948
- xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :methods => [ :topic_id ])
1949
- assert xml.include?(%(<topic-id type="integer">#{topics(:first).topic_id}</topic-id>)), xml
1950
- assert xml.include?(%(<topic-id type="integer">#{topics(:second).topic_id}</topic-id>)), xml
1951
- end
1952
-
1953
- def test_array_to_xml_including_has_one_association
1954
- xml = [ companies(:first_firm), companies(:rails_core) ].to_xml(:indent => 0, :skip_instruct => true, :include => :account)
1955
- assert xml.include?(companies(:first_firm).account.to_xml(:indent => 0, :skip_instruct => true))
1956
- assert xml.include?(companies(:rails_core).account.to_xml(:indent => 0, :skip_instruct => true))
1957
- end
1958
-
1959
- def test_array_to_xml_including_belongs_to_association
1960
- xml = [ companies(:first_client), companies(:second_client), companies(:another_client) ].to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
1961
- assert xml.include?(companies(:first_client).to_xml(:indent => 0, :skip_instruct => true))
1962
- assert xml.include?(companies(:second_client).firm.to_xml(:indent => 0, :skip_instruct => true))
1963
- assert xml.include?(companies(:another_client).firm.to_xml(:indent => 0, :skip_instruct => true))
1964
- end
1965
-
1966
- def test_to_xml_including_belongs_to_association
1967
- xml = companies(:first_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
1968
- assert !xml.include?("<firm>")
1969
-
1970
- xml = companies(:second_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
1971
- assert xml.include?("<firm>")
1972
- end
1973
-
1974
- def test_to_xml_including_multiple_associations
1975
- xml = companies(:first_firm).to_xml(:indent => 0, :skip_instruct => true, :include => [ :clients, :account ])
1976
- assert_equal "<firm>", xml.first(6)
1977
- assert xml.include?(%(<account>))
1978
- assert xml.include?(%(<clients type="array"><client>))
1979
- end
1980
-
1981
- def test_to_xml_including_multiple_associations_with_options
1982
- xml = companies(:first_firm).to_xml(
1983
- :indent => 0, :skip_instruct => true,
1984
- :include => { :clients => { :only => :name } }
1985
- )
1986
-
1987
- assert_equal "<firm>", xml.first(6)
1988
- assert xml.include?(%(<client><name>Summit</name></client>))
1989
- assert xml.include?(%(<clients type="array"><client>))
1990
- end
1991
-
1992
- def test_to_xml_including_methods
1993
- xml = Company.new.to_xml(:methods => :arbitrary_method, :skip_instruct => true)
1994
- assert_equal "<company>", xml.first(9)
1995
- assert xml.include?(%(<arbitrary-method>I am Jack's profound disappointment</arbitrary-method>))
1996
- end
1997
-
1998
- def test_to_xml_with_block
1999
- value = "Rockin' the block"
2000
- xml = Company.new.to_xml(:skip_instruct => true) do |xml|
2001
- xml.tag! "arbitrary-element", value
2002
- end
2003
- assert_equal "<company>", xml.first(9)
2004
- assert xml.include?(%(<arbitrary-element>#{value}</arbitrary-element>))
2005
- end
2006
-
2007
- def test_type_name_with_module_should_handle_beginning
2008
- assert_equal 'ActiveRecord::Person', ActiveRecord::Base.send(:type_name_with_module, 'Person')
2009
- assert_equal '::Person', ActiveRecord::Base.send(:type_name_with_module, '::Person')
2010
- end
2011
-
1340
+
2012
1341
  def test_to_param_should_return_string
2013
1342
  assert_kind_of String, Client.find(:first).to_param
2014
1343
  end
2015
-
1344
+
2016
1345
  def test_inspect_class
2017
1346
  assert_equal 'ActiveRecord::Base', ActiveRecord::Base.inspect
2018
1347
  assert_equal 'LoosePerson(abstract)', LoosePerson.inspect
2019
1348
  assert_match(/^Topic\(id: integer, title: string/, Topic.inspect)
2020
1349
  end
2021
-
1350
+
2022
1351
  def test_inspect_instance
2023
1352
  topic = topics(:first)
2024
- assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil>), topic.inspect
1353
+ assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil, group: nil>), topic.inspect
2025
1354
  end
2026
-
1355
+
2027
1356
  def test_inspect_new_instance
2028
- assert_match /Topic id: nil/, Topic.new.inspect
1357
+ assert_match(/Topic id: nil/, Topic.new.inspect)
2029
1358
  end
2030
-
1359
+
2031
1360
  def test_inspect_limited_select_instance
2032
1361
  assert_equal %(#<Topic id: 1>), Topic.find(:first, :select => 'id', :conditions => 'id = 1').inspect
2033
1362
  assert_equal %(#<Topic id: 1, title: "The First Topic">), Topic.find(:first, :select => 'id, title', :conditions => 'id = 1').inspect
2034
1363
  end
2035
-
1364
+
2036
1365
  def test_inspect_class_without_table
2037
1366
  assert_equal "NonExistentTable(Table doesn't exist)", NonExistentTable.inspect
2038
1367
  end
2039
-
1368
+
2040
1369
  def test_attribute_for_inspect
2041
1370
  t = topics(:first)
2042
1371
  t.title = "The First Topic Now Has A Title With\nNewlines And More Than 50 Characters"
2043
-
1372
+
2044
1373
  assert_equal %("#{t.written_on.to_s(:db)}"), t.attribute_for_inspect(:written_on)
2045
1374
  assert_equal '"The First Topic Now Has A Title With\nNewlines And M..."', t.attribute_for_inspect(:title)
2046
1375
  end
2047
-
1376
+
2048
1377
  def test_becomes
2049
1378
  assert_kind_of Reply, topics(:first).becomes(Reply)
2050
1379
  assert_equal "The First Topic", topics(:first).becomes(Reply).title
2051
1380
  end
2052
-
1381
+
2053
1382
  def test_silence_sets_log_level_to_error_in_block
2054
1383
  original_logger = ActiveRecord::Base.logger
2055
1384
  log = StringIO.new
@@ -2063,7 +1392,7 @@ class BasicsTest < ActiveRecord::TestCase
2063
1392
  ensure
2064
1393
  ActiveRecord::Base.logger = original_logger
2065
1394
  end
2066
-
1395
+
2067
1396
  def test_silence_sets_log_level_back_to_level_before_yield
2068
1397
  original_logger = ActiveRecord::Base.logger
2069
1398
  log = StringIO.new
@@ -2075,40 +1404,83 @@ class BasicsTest < ActiveRecord::TestCase
2075
1404
  ensure
2076
1405
  ActiveRecord::Base.logger = original_logger
2077
1406
  end
2078
-
1407
+
2079
1408
  def test_benchmark_with_log_level
2080
1409
  original_logger = ActiveRecord::Base.logger
2081
1410
  log = StringIO.new
2082
1411
  ActiveRecord::Base.logger = Logger.new(log)
2083
1412
  ActiveRecord::Base.logger.level = Logger::WARN
2084
- ActiveRecord::Base.benchmark("Debug Topic Count", Logger::DEBUG) { Topic.count }
2085
- ActiveRecord::Base.benchmark("Warn Topic Count", Logger::WARN) { Topic.count }
2086
- ActiveRecord::Base.benchmark("Error Topic Count", Logger::ERROR) { Topic.count }
2087
- assert_no_match /Debug Topic Count/, log.string
2088
- assert_match /Warn Topic Count/, log.string
2089
- assert_match /Error Topic Count/, log.string
1413
+ ActiveRecord::Base.benchmark("Debug Topic Count", :level => :debug) { Topic.count }
1414
+ ActiveRecord::Base.benchmark("Warn Topic Count", :level => :warn) { Topic.count }
1415
+ ActiveRecord::Base.benchmark("Error Topic Count", :level => :error) { Topic.count }
1416
+ assert_no_match(/Debug Topic Count/, log.string)
1417
+ assert_match(/Warn Topic Count/, log.string)
1418
+ assert_match(/Error Topic Count/, log.string)
2090
1419
  ensure
2091
1420
  ActiveRecord::Base.logger = original_logger
2092
1421
  end
2093
-
1422
+
2094
1423
  def test_benchmark_with_use_silence
2095
1424
  original_logger = ActiveRecord::Base.logger
2096
1425
  log = StringIO.new
2097
1426
  ActiveRecord::Base.logger = Logger.new(log)
2098
- ActiveRecord::Base.benchmark("Logging", Logger::DEBUG, true) { ActiveRecord::Base.logger.debug "Loud" }
2099
- ActiveRecord::Base.benchmark("Logging", Logger::DEBUG, false) { ActiveRecord::Base.logger.debug "Quiet" }
2100
- assert_no_match /Loud/, log.string
2101
- assert_match /Quiet/, log.string
1427
+ ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => true) { ActiveRecord::Base.logger.debug "Loud" }
1428
+ ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" }
1429
+ assert_no_match(/Loud/, log.string)
1430
+ assert_match(/Quiet/, log.string)
2102
1431
  ensure
2103
1432
  ActiveRecord::Base.logger = original_logger
2104
1433
  end
2105
1434
 
2106
- def test_create_with_custom_timestamps
2107
- custom_datetime = 1.hour.ago.beginning_of_day
1435
+ def test_dup
1436
+ assert !Minimalistic.new.freeze.dup.frozen?
1437
+ end
1438
+
1439
+ def test_compute_type_success
1440
+ assert_equal Author, ActiveRecord::Base.send(:compute_type, 'Author')
1441
+ end
2108
1442
 
2109
- %w(created_at created_on updated_at updated_on).each do |attribute|
2110
- parrot = LiveParrot.create(:name => "colombian", attribute => custom_datetime)
2111
- assert_equal custom_datetime, parrot[attribute]
1443
+ def test_compute_type_nonexistent_constant
1444
+ assert_raises NameError do
1445
+ ActiveRecord::Base.send :compute_type, 'NonexistentModel'
2112
1446
  end
2113
1447
  end
1448
+
1449
+ def test_compute_type_no_method_error
1450
+ ActiveSupport::Dependencies.stubs(:constantize).raises(NoMethodError)
1451
+ assert_raises NoMethodError do
1452
+ ActiveRecord::Base.send :compute_type, 'InvalidModel'
1453
+ end
1454
+ end
1455
+
1456
+ def test_default_scope_is_reset
1457
+ Object.const_set :UnloadablePost, Class.new(ActiveRecord::Base)
1458
+ UnloadablePost.table_name = 'posts'
1459
+ UnloadablePost.class_eval do
1460
+ default_scope order('posts.comments_count ASC')
1461
+ end
1462
+ UnloadablePost.scoped_methods # make Thread.current[:UnloadablePost_scoped_methods] not nil
1463
+
1464
+ UnloadablePost.unloadable
1465
+ assert_not_nil Thread.current[:UnloadablePost_scoped_methods]
1466
+ ActiveSupport::Dependencies.remove_unloadable_constants!
1467
+ assert_nil Thread.current[:UnloadablePost_scoped_methods]
1468
+ ensure
1469
+ Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost)
1470
+ end
1471
+
1472
+ protected
1473
+ def with_env_tz(new_tz = 'US/Eastern')
1474
+ old_tz, ENV['TZ'] = ENV['TZ'], new_tz
1475
+ yield
1476
+ ensure
1477
+ old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
1478
+ end
1479
+
1480
+ def with_active_record_default_timezone(zone)
1481
+ old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
1482
+ yield
1483
+ ensure
1484
+ ActiveRecord::Base.default_timezone = old_zone
1485
+ end
2114
1486
  end