ibm_db 2.5.6-x86-mswin32-60 → 2.5.7-x86-mswin32-60

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.
Files changed (38) hide show
  1. data/CHANGES +6 -0
  2. data/README +1 -1
  3. data/ext/Makefile.nt32 +3 -3
  4. data/ext/Makefile.nt32.191 +212 -0
  5. data/ext/ibm_db.c +30 -5
  6. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +300 -108
  7. data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1 -1
  8. data/lib/mswin32/rb18x/ibm_db.so +0 -0
  9. data/test/cases/adapter_test.rb +25 -22
  10. data/test/cases/associations/belongs_to_associations_test.rb +245 -43
  11. data/test/cases/associations/cascaded_eager_loading_test.rb +28 -26
  12. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +60 -156
  13. data/test/cases/associations/join_model_test.rb +96 -146
  14. data/test/cases/attribute_methods_test.rb +98 -33
  15. data/test/cases/base_test.rb +525 -103
  16. data/test/cases/calculations_test.rb +92 -8
  17. data/test/cases/migration_test.rb +533 -207
  18. data/test/cases/persistence_test.rb +636 -0
  19. data/test/cases/query_cache_test.rb +242 -0
  20. data/test/cases/relations_test.rb +1019 -0
  21. data/test/cases/schema_dumper_test.rb +37 -17
  22. data/test/cases/transaction_callbacks_test.rb +300 -0
  23. data/test/cases/validations/uniqueness_validation_test.rb +38 -22
  24. data/test/cases/xml_serialization_test.rb +276 -0
  25. data/test/config.yml +154 -0
  26. data/test/connections/native_ibm_db/connection.rb +2 -0
  27. data/test/models/warehouse_thing.rb +4 -4
  28. data/test/schema/i5/ibm_db_specific_schema.rb +3 -1
  29. data/test/schema/ids/ibm_db_specific_schema.rb +3 -1
  30. data/test/schema/luw/ibm_db_specific_schema.rb +2 -0
  31. data/test/schema/schema.rb +174 -89
  32. data/test/schema/zOS/ibm_db_specific_schema.rb +3 -1
  33. metadata +9 -7
  34. data/lib/mswin32/rb19x/ibm_db.so +0 -0
  35. data/test/cases/associations/eager_test.rb +0 -862
  36. data/test/cases/associations/has_many_through_associations_test.rb +0 -461
  37. data/test/cases/finder_test.rb +0 -1088
  38. data/test/cases/fixtures_test.rb +0 -684
@@ -0,0 +1,636 @@
1
+ require "cases/helper"
2
+ require 'models/post'
3
+ require 'models/comment'
4
+ require 'models/author'
5
+ require 'models/topic'
6
+ require 'models/reply'
7
+ require 'models/category'
8
+ require 'models/company'
9
+ require 'models/developer'
10
+ require 'models/project'
11
+ require 'models/minimalistic'
12
+ require 'models/warehouse_thing'
13
+ require 'models/parrot'
14
+ require 'models/minivan'
15
+ require 'models/person'
16
+ require 'rexml/document'
17
+ require 'active_support/core_ext/exception'
18
+
19
+ class PersistencesTest < ActiveRecord::TestCase
20
+
21
+ fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse_things', :authors, :categorizations, :categories, :posts, :minivans
22
+
23
+ # Oracle UPDATE does not support ORDER BY
24
+ unless current_adapter?(:OracleAdapter)
25
+ def test_update_all_ignores_order_without_limit_from_association
26
+ author = authors(:david)
27
+ assert_nothing_raised do
28
+ assert_equal author.posts_with_comments_and_categories.length, author.posts_with_comments_and_categories.update_all([ "body = ?", "bulk update!" ])
29
+ end
30
+ end
31
+
32
+ def test_update_all_doesnt_ignore_order
33
+ assert_equal authors(:david).id + 1, authors(:mary).id # make sure there is going to be a duplicate PK error
34
+ test_update_with_order_succeeds = lambda do |order|
35
+ begin
36
+ Author.order(order).update_all('id = id + 1')
37
+ rescue ActiveRecord::ActiveRecordError
38
+ false
39
+ end
40
+ end
41
+
42
+ if !current_adapter?(:IBM_DBAdapter) && test_update_with_order_succeeds.call('id DESC')
43
+ # The update below goes on successfully in DB2.
44
+ assert !test_update_with_order_succeeds.call('id ASC') # test that this wasn't a fluke and using an incorrect order results in an exception
45
+ else
46
+ # test that we're failing because the current Arel's engine doesn't support UPDATE ORDER BY queries is using subselects instead
47
+ assert_sql(/\AUPDATE .+ \(SELECT .* ORDER BY id DESC\)\Z/i) do
48
+ test_update_with_order_succeeds.call('id DESC')
49
+ end
50
+ end
51
+ end
52
+
53
+ def test_update_all_with_order_and_limit_updates_subset_only
54
+ author = authors(:david)
55
+ assert_nothing_raised do
56
+ assert_equal 1, author.posts_sorted_by_id_limited.size
57
+ assert_equal 2, author.posts_sorted_by_id_limited.find(:all, :limit => 2).size
58
+ assert_equal 1, author.posts_sorted_by_id_limited.update_all([ "body = ?", "bulk update!" ])
59
+ assert_equal "bulk update!", posts(:welcome).body
60
+ assert_not_equal "bulk update!", posts(:thinking).body
61
+ end
62
+ end
63
+ end
64
+
65
+ def test_update_many
66
+ topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
67
+ updated = Topic.update(topic_data.keys, topic_data.values)
68
+
69
+ assert_equal 2, updated.size
70
+ assert_equal "1 updated", Topic.find(1).content
71
+ assert_equal "2 updated", Topic.find(2).content
72
+ end
73
+
74
+ def test_delete_all
75
+ assert Topic.count > 0
76
+
77
+ assert_equal Topic.count, Topic.delete_all
78
+ end
79
+
80
+ def test_update_by_condition
81
+ Topic.update_all "content = 'bulk updated!'", ["approved = ?", true]
82
+ assert_equal "Have a nice day", Topic.find(1).content
83
+ assert_equal "bulk updated!", Topic.find(2).content
84
+ end
85
+
86
+ def test_increment_attribute
87
+ assert_equal 50, accounts(:signals37).credit_limit
88
+ accounts(:signals37).increment! :credit_limit
89
+ assert_equal 51, accounts(:signals37, :reload).credit_limit
90
+
91
+ accounts(:signals37).increment(:credit_limit).increment!(:credit_limit)
92
+ assert_equal 53, accounts(:signals37, :reload).credit_limit
93
+ end
94
+
95
+ def test_increment_nil_attribute
96
+ assert_nil topics(:first).parent_id
97
+ topics(:first).increment! :parent_id
98
+ assert_equal 1, topics(:first).parent_id
99
+ end
100
+
101
+ def test_increment_attribute_by
102
+ assert_equal 50, accounts(:signals37).credit_limit
103
+ accounts(:signals37).increment! :credit_limit, 5
104
+ assert_equal 55, accounts(:signals37, :reload).credit_limit
105
+
106
+ accounts(:signals37).increment(:credit_limit, 1).increment!(:credit_limit, 3)
107
+ assert_equal 59, accounts(:signals37, :reload).credit_limit
108
+ end
109
+
110
+ def test_destroy_all
111
+ conditions = "author_name = 'Mary'"
112
+ topics_by_mary = Topic.all(:conditions => conditions, :order => 'id')
113
+ assert ! topics_by_mary.empty?
114
+
115
+ assert_difference('Topic.count', -topics_by_mary.size) do
116
+ destroyed = Topic.destroy_all(conditions).sort_by(&:id)
117
+ assert_equal topics_by_mary, destroyed
118
+ assert destroyed.all? { |topic| topic.frozen? }, "destroyed topics should be frozen"
119
+ end
120
+ end
121
+
122
+ def test_destroy_many
123
+ clients = Client.find([2, 3], :order => 'id')
124
+
125
+ assert_difference('Client.count', -2) do
126
+ destroyed = Client.destroy([2, 3]).sort_by(&:id)
127
+ assert_equal clients, destroyed
128
+ assert destroyed.all? { |client| client.frozen? }, "destroyed clients should be frozen"
129
+ end
130
+ end
131
+
132
+ def test_delete_many
133
+ original_count = Topic.count
134
+ Topic.delete(deleting = [1, 2])
135
+ assert_equal original_count - deleting.size, Topic.count
136
+ end
137
+
138
+ def test_decrement_attribute
139
+ assert_equal 50, accounts(:signals37).credit_limit
140
+
141
+ accounts(:signals37).decrement!(:credit_limit)
142
+ assert_equal 49, accounts(:signals37, :reload).credit_limit
143
+
144
+ accounts(:signals37).decrement(:credit_limit).decrement!(:credit_limit)
145
+ assert_equal 47, accounts(:signals37, :reload).credit_limit
146
+ end
147
+
148
+ def test_decrement_attribute_by
149
+ assert_equal 50, accounts(:signals37).credit_limit
150
+ accounts(:signals37).decrement! :credit_limit, 5
151
+ assert_equal 45, accounts(:signals37, :reload).credit_limit
152
+
153
+ accounts(:signals37).decrement(:credit_limit, 1).decrement!(:credit_limit, 3)
154
+ assert_equal 41, accounts(:signals37, :reload).credit_limit
155
+ end
156
+
157
+ def test_create
158
+ topic = Topic.new
159
+ topic.title = "New Topic"
160
+ topic.save
161
+ topic_reloaded = Topic.find(topic.id)
162
+ assert_equal("New Topic", topic_reloaded.title)
163
+ end
164
+
165
+ def test_save!
166
+ topic = Topic.new(:title => "New Topic")
167
+ assert topic.save!
168
+
169
+ reply = WrongReply.new
170
+ assert_raise(ActiveRecord::RecordInvalid) { reply.save! }
171
+ end
172
+
173
+ def test_save_null_string_attributes
174
+ topic = Topic.find(1)
175
+ topic.attributes = { "title" => "null", "author_name" => "null" }
176
+ topic.save!
177
+ topic.reload
178
+ assert_equal("null", topic.title)
179
+ assert_equal("null", topic.author_name)
180
+ end
181
+
182
+ def test_save_nil_string_attributes
183
+ topic = Topic.find(1)
184
+ topic.title = nil
185
+ topic.save!
186
+ topic.reload
187
+ assert_nil topic.title
188
+ end
189
+
190
+ def test_save_for_record_with_only_primary_key
191
+ minimalistic = Minimalistic.new
192
+ assert_nothing_raised { minimalistic.save }
193
+ end
194
+
195
+ def test_save_for_record_with_only_primary_key_that_is_provided
196
+ assert_nothing_raised { Minimalistic.create!(:id => 2) }
197
+ end
198
+
199
+ def test_create_many
200
+ topics = Topic.create([ { "title" => "first" }, { "title" => "second" }])
201
+ assert_equal 2, topics.size
202
+ assert_equal "first", topics.first.title
203
+ end
204
+
205
+ def test_create_columns_not_equal_attributes
206
+ topic = Topic.new
207
+ topic.title = 'Another New Topic'
208
+ topic.send :write_attribute, 'does_not_exist', 'test'
209
+ assert_nothing_raised { topic.save }
210
+ end
211
+
212
+ def test_create_through_factory_with_block
213
+ topic = Topic.create("title" => "New Topic") do |t|
214
+ t.author_name = "David"
215
+ end
216
+ assert_equal("New Topic", topic.title)
217
+ assert_equal("David", topic.author_name)
218
+ end
219
+
220
+ def test_create_many_through_factory_with_block
221
+ topics = Topic.create([ { "title" => "first" }, { "title" => "second" }]) do |t|
222
+ t.author_name = "David"
223
+ end
224
+ assert_equal 2, topics.size
225
+ topic1, topic2 = Topic.find(topics[0].id), Topic.find(topics[1].id)
226
+ assert_equal "first", topic1.title
227
+ assert_equal "David", topic1.author_name
228
+ assert_equal "second", topic2.title
229
+ assert_equal "David", topic2.author_name
230
+ end
231
+
232
+ def test_update
233
+ topic = Topic.new
234
+ topic.title = "Another New Topic"
235
+ topic.written_on = "2003-12-12 23:23:00"
236
+ topic.save
237
+ topicReloaded = Topic.find(topic.id)
238
+ assert_equal("Another New Topic", topicReloaded.title)
239
+
240
+ topicReloaded.title = "Updated topic"
241
+ topicReloaded.save
242
+
243
+ topicReloadedAgain = Topic.find(topic.id)
244
+
245
+ assert_equal("Updated topic", topicReloadedAgain.title)
246
+ end
247
+
248
+ def test_update_columns_not_equal_attributes
249
+ topic = Topic.new
250
+ topic.title = "Still another topic"
251
+ topic.save
252
+
253
+ topicReloaded = Topic.find(topic.id)
254
+ topicReloaded.title = "A New Topic"
255
+ topicReloaded.send :write_attribute, 'does_not_exist', 'test'
256
+ assert_nothing_raised { topicReloaded.save }
257
+ end
258
+
259
+ def test_update_for_record_with_only_primary_key
260
+ minimalistic = minimalistics(:first)
261
+ assert_nothing_raised { minimalistic.save }
262
+ end
263
+
264
+ def test_update_sti_type
265
+ assert_instance_of Reply, topics(:second)
266
+
267
+ topic = topics(:second).becomes(Topic)
268
+ assert_instance_of Topic, topic
269
+ topic.save!
270
+ assert_instance_of Topic, Topic.find(topic.id)
271
+ end
272
+
273
+ def test_delete
274
+ topic = Topic.find(1)
275
+ assert_equal topic, topic.delete, 'topic.delete did not return self'
276
+ assert topic.frozen?, 'topic not frozen after delete'
277
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
278
+ end
279
+
280
+ def test_delete_doesnt_run_callbacks
281
+ Topic.find(1).delete
282
+ assert_not_nil Topic.find(2)
283
+ end
284
+
285
+ def test_destroy
286
+ topic = Topic.find(1)
287
+ assert_equal topic, topic.destroy, 'topic.destroy did not return self'
288
+ assert topic.frozen?, 'topic not frozen after destroy'
289
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
290
+ end
291
+
292
+ def test_record_not_found_exception
293
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(99999) }
294
+ end
295
+
296
+ def test_update_all
297
+ assert_equal Topic.count, Topic.update_all("content = 'bulk updated!'")
298
+ assert_equal "bulk updated!", Topic.find(1).content
299
+ assert_equal "bulk updated!", Topic.find(2).content
300
+
301
+ assert_equal Topic.count, Topic.update_all(['content = ?', 'bulk updated again!'])
302
+ assert_equal "bulk updated again!", Topic.find(1).content
303
+ assert_equal "bulk updated again!", Topic.find(2).content
304
+
305
+ assert_equal Topic.count, Topic.update_all(['content = ?', nil])
306
+ assert_nil Topic.find(1).content
307
+ end
308
+
309
+ def test_update_all_with_hash
310
+ assert_not_nil Topic.find(1).last_read
311
+ assert_equal Topic.count, Topic.update_all(:content => 'bulk updated with hash!', :last_read => nil)
312
+ assert_equal "bulk updated with hash!", Topic.find(1).content
313
+ assert_equal "bulk updated with hash!", Topic.find(2).content
314
+ assert_nil Topic.find(1).last_read
315
+ assert_nil Topic.find(2).last_read
316
+ end
317
+
318
+ def test_update_all_with_non_standard_table_name
319
+ assert_equal 1, WarehouseThing.update_all(['value = ?', 0], ['id = ?', 1])
320
+ assert_equal 0, WarehouseThing.find(1).value
321
+ end
322
+
323
+ def test_delete_new_record
324
+ client = Client.new
325
+ client.delete
326
+ assert client.frozen?
327
+ end
328
+
329
+ def test_delete_record_with_associations
330
+ client = Client.find(3)
331
+ client.delete
332
+ assert client.frozen?
333
+ assert_kind_of Firm, client.firm
334
+ assert_raise(ActiveSupport::FrozenObjectError) { client.name = "something else" }
335
+ end
336
+
337
+ def test_destroy_new_record
338
+ client = Client.new
339
+ client.destroy
340
+ assert client.frozen?
341
+ end
342
+
343
+ def test_destroy_record_with_associations
344
+ client = Client.find(3)
345
+ client.destroy
346
+ assert client.frozen?
347
+ assert_kind_of Firm, client.firm
348
+ assert_raise(ActiveSupport::FrozenObjectError) { client.name = "something else" }
349
+ end
350
+
351
+ def test_update_attribute
352
+ assert !Topic.find(1).approved?
353
+ Topic.find(1).update_attribute("approved", true)
354
+ assert Topic.find(1).approved?
355
+
356
+ Topic.find(1).update_attribute(:approved, false)
357
+ assert !Topic.find(1).approved?
358
+ end
359
+
360
+ def test_update_attribute_does_not_choke_on_nil
361
+ assert Topic.find(1).update_attributes(nil)
362
+ end
363
+
364
+ def test_update_attribute_for_readonly_attribute
365
+ minivan = Minivan.find('m1')
366
+ assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, 'black') }
367
+ end
368
+
369
+ # This test is correct, but it is hard to fix it since
370
+ # update_attribute trigger simply call save! that triggers
371
+ # all callbacks.
372
+ # def test_update_attribute_with_one_changed_and_one_updated
373
+ # t = Topic.order('id').limit(1).first
374
+ # title, author_name = t.title, t.author_name
375
+ # t.author_name = 'John'
376
+ # t.update_attribute(:title, 'super_title')
377
+ # assert_equal 'John', t.author_name
378
+ # assert_equal 'super_title', t.title
379
+ # assert t.changed?, "topic should have changed"
380
+ # assert t.author_name_changed?, "author_name should have changed"
381
+ # assert !t.title_changed?, "title should not have changed"
382
+ # assert_nil t.title_change, 'title change should be nil'
383
+ # assert_equal ['author_name'], t.changed
384
+ #
385
+ # t.reload
386
+ # assert_equal 'David', t.author_name
387
+ # assert_equal 'super_title', t.title
388
+ # end
389
+
390
+ def test_update_attribute_with_one_updated
391
+ t = Topic.first
392
+ title = t.title
393
+ t.update_attribute(:title, 'super_title')
394
+ assert_equal 'super_title', t.title
395
+ assert !t.changed?, "topic should not have changed"
396
+ assert !t.title_changed?, "title should not have changed"
397
+ assert_nil t.title_change, 'title change should be nil'
398
+
399
+ t.reload
400
+ assert_equal 'super_title', t.title
401
+ end
402
+
403
+ def test_update_attribute_for_updated_at_on
404
+ developer = Developer.find(1)
405
+ prev_month = Time.now.prev_month
406
+
407
+ developer.update_attribute(:updated_at, prev_month)
408
+ assert_equal prev_month, developer.updated_at
409
+
410
+ developer.update_attribute(:salary, 80001)
411
+ assert_not_equal prev_month, developer.updated_at
412
+
413
+ developer.reload
414
+ assert_not_equal prev_month, developer.updated_at
415
+ end
416
+
417
+ def test_update_column
418
+ topic = Topic.find(1)
419
+ topic.update_column("approved", true)
420
+ assert topic.approved?
421
+ topic.reload
422
+ assert topic.approved?
423
+
424
+ topic.update_column(:approved, false)
425
+ assert !topic.approved?
426
+ topic.reload
427
+ assert !topic.approved?
428
+ end
429
+
430
+ def test_update_column_should_not_use_setter_method
431
+ dev = Developer.find(1)
432
+ dev.instance_eval { def salary=(value); write_attribute(:salary, value * 2); end }
433
+
434
+ dev.update_column(:salary, 80000)
435
+ assert_equal 80000, dev.salary
436
+
437
+ dev.reload
438
+ assert_equal 80000, dev.salary
439
+ end
440
+
441
+ def test_update_column_should_raise_exception_if_new_record
442
+ topic = Topic.new
443
+ assert_raises(ActiveRecord::ActiveRecordError) { topic.update_column("approved", false) }
444
+ end
445
+
446
+ def test_update_column_should_not_leave_the_object_dirty
447
+ topic = Topic.find(1)
448
+ topic.update_attribute("content", "Have a nice day")
449
+
450
+ topic.reload
451
+ topic.update_column(:content, "You too")
452
+ assert_equal [], topic.changed
453
+
454
+ topic.reload
455
+ topic.update_column("content", "Have a nice day")
456
+ assert_equal [], topic.changed
457
+ end
458
+
459
+ def test_update_column_with_model_having_primary_key_other_than_id
460
+ minivan = Minivan.find('m1')
461
+ new_name = 'sebavan'
462
+
463
+ minivan.update_column(:name, new_name)
464
+ assert_equal new_name, minivan.name
465
+ end
466
+
467
+ def test_update_column_for_readonly_attribute
468
+ minivan = Minivan.find('m1')
469
+ prev_color = minivan.color
470
+ assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_column(:color, 'black') }
471
+ assert_equal prev_color, minivan.color
472
+ end
473
+
474
+ def test_update_column_should_not_modify_updated_at
475
+ developer = Developer.find(1)
476
+ prev_month = Time.now.prev_month
477
+
478
+ developer.update_column(:updated_at, prev_month)
479
+ assert_equal prev_month, developer.updated_at
480
+
481
+ developer.update_column(:salary, 80001)
482
+ assert_equal prev_month, developer.updated_at
483
+
484
+ developer.reload
485
+ assert_equal prev_month.to_i, developer.updated_at.to_i
486
+ end
487
+
488
+ def test_update_column_with_one_changed_and_one_updated
489
+ t = Topic.order('id').limit(1).first
490
+ title, author_name = t.title, t.author_name
491
+ t.author_name = 'John'
492
+ t.update_column(:title, 'super_title')
493
+ assert_equal 'John', t.author_name
494
+ assert_equal 'super_title', t.title
495
+ assert t.changed?, "topic should have changed"
496
+ assert t.author_name_changed?, "author_name should have changed"
497
+
498
+ t.reload
499
+ assert_equal author_name, t.author_name
500
+ assert_equal 'super_title', t.title
501
+ end
502
+
503
+ def test_update_attributes
504
+ topic = Topic.find(1)
505
+ assert !topic.approved?
506
+ assert_equal "The First Topic", topic.title
507
+
508
+ topic.update_attributes("approved" => true, "title" => "The First Topic Updated")
509
+ topic.reload
510
+ assert topic.approved?
511
+ assert_equal "The First Topic Updated", topic.title
512
+
513
+ topic.update_attributes(:approved => false, :title => "The First Topic")
514
+ topic.reload
515
+ assert !topic.approved?
516
+ assert_equal "The First Topic", topic.title
517
+ end
518
+
519
+ def test_update_attributes_as_admin
520
+ person = TightPerson.create({ "first_name" => 'Joshua' })
521
+ person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
522
+ person.reload
523
+
524
+ assert_equal 'Josh', person.first_name
525
+ assert_equal 'm', person.gender
526
+ assert_equal 'from NZ', person.comments
527
+ end
528
+
529
+ def test_update_attributes_without_protection
530
+ person = TightPerson.create({ "first_name" => 'Joshua' })
531
+ person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
532
+ person.reload
533
+
534
+ assert_equal 'Josh', person.first_name
535
+ assert_equal 'm', person.gender
536
+ assert_equal 'from NZ', person.comments
537
+ end
538
+
539
+ def test_update_attributes!
540
+ Reply.validates_presence_of(:title)
541
+ reply = Reply.find(2)
542
+ assert_equal "The Second Topic of the day", reply.title
543
+ assert_equal "Have a nice day", reply.content
544
+
545
+ reply.update_attributes!("title" => "The Second Topic of the day updated", "content" => "Have a nice evening")
546
+ reply.reload
547
+ assert_equal "The Second Topic of the day updated", reply.title
548
+ assert_equal "Have a nice evening", reply.content
549
+
550
+ reply.update_attributes!(:title => "The Second Topic of the day", :content => "Have a nice day")
551
+ reply.reload
552
+ assert_equal "The Second Topic of the day", reply.title
553
+ assert_equal "Have a nice day", reply.content
554
+
555
+ assert_raise(ActiveRecord::RecordInvalid) { reply.update_attributes!(:title => nil, :content => "Have a nice evening") }
556
+ ensure
557
+ Reply.reset_callbacks(:validate)
558
+ end
559
+
560
+ def test_update_attributes_with_bang_as_admin
561
+ person = TightPerson.create({ "first_name" => 'Joshua' })
562
+ person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
563
+ person.reload
564
+
565
+ assert_equal 'Josh', person.first_name
566
+ assert_equal 'm', person.gender
567
+ assert_equal 'from NZ', person.comments
568
+ end
569
+
570
+ def test_update_attributestes_with_bang_without_protection
571
+ person = TightPerson.create({ "first_name" => 'Joshua' })
572
+ person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
573
+ person.reload
574
+
575
+ assert_equal 'Josh', person.first_name
576
+ assert_equal 'm', person.gender
577
+ assert_equal 'from NZ', person.comments
578
+ end
579
+
580
+ def test_destroyed_returns_boolean
581
+ developer = Developer.first
582
+ assert_equal false, developer.destroyed?
583
+ developer.destroy
584
+ assert_equal true, developer.destroyed?
585
+
586
+ developer = Developer.last
587
+ assert_equal false, developer.destroyed?
588
+ developer.delete
589
+ assert_equal true, developer.destroyed?
590
+ end
591
+
592
+ def test_persisted_returns_boolean
593
+ developer = Developer.new(:name => "Jose")
594
+ assert_equal false, developer.persisted?
595
+ developer.save!
596
+ assert_equal true, developer.persisted?
597
+
598
+ developer = Developer.first
599
+ assert_equal true, developer.persisted?
600
+ developer.destroy
601
+ assert_equal false, developer.persisted?
602
+
603
+ developer = Developer.last
604
+ assert_equal true, developer.persisted?
605
+ developer.delete
606
+ assert_equal false, developer.persisted?
607
+ end
608
+
609
+ def test_class_level_destroy
610
+ should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
611
+ Topic.find(1).replies << should_be_destroyed_reply
612
+
613
+ Topic.destroy(1)
614
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
615
+ assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) }
616
+ end
617
+
618
+ def test_class_level_delete
619
+ should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
620
+ Topic.find(1).replies << should_be_destroyed_reply
621
+
622
+ Topic.delete(1)
623
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
624
+ assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
625
+ end
626
+
627
+ def test_create_with_custom_timestamps
628
+ custom_datetime = 1.hour.ago.beginning_of_day
629
+
630
+ %w(created_at created_on updated_at updated_on).each do |attribute|
631
+ parrot = LiveParrot.create(:name => "colombian", attribute => custom_datetime)
632
+ assert_equal custom_datetime, parrot[attribute]
633
+ end
634
+ end
635
+
636
+ end