db2 2.6.2 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +17 -0
- data/README +79 -141
- data/ext/Makefile.nt32 +3 -3
- data/ext/Makefile.nt32.191 +212 -0
- data/ext/extconf.rb +75 -14
- data/ext/ibm_db.c +504 -47
- data/ext/ruby_ibm_db.h +4 -1
- data/ext/ruby_ibm_db_cli.c +108 -1
- data/ext/ruby_ibm_db_cli.h +54 -1
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +423 -124
- data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1 -1
- data/test/cases/adapter_test.rb +169 -164
- data/test/cases/associations/belongs_to_associations_test.rb +268 -43
- data/test/cases/associations/cascaded_eager_loading_test.rb +31 -33
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +90 -156
- data/test/cases/associations/join_model_test.rb +100 -150
- data/test/cases/attribute_methods_test.rb +259 -58
- data/test/cases/base_test.rb +785 -138
- data/test/cases/calculations_test.rb +128 -8
- data/test/cases/migration_test.rb +680 -286
- data/test/cases/persistence_test.rb +642 -0
- data/test/cases/query_cache_test.rb +257 -0
- data/test/cases/relations_test.rb +1182 -0
- data/test/cases/schema_dumper_test.rb +41 -17
- data/test/cases/transaction_callbacks_test.rb +300 -0
- data/test/cases/validations/uniqueness_validation_test.rb +38 -22
- data/test/cases/xml_serialization_test.rb +408 -0
- data/test/config.yml +154 -0
- data/test/connections/native_ibm_db/connection.rb +2 -0
- data/test/models/warehouse_thing.rb +4 -4
- data/test/schema/i5/ibm_db_specific_schema.rb +3 -1
- data/test/schema/ids/ibm_db_specific_schema.rb +3 -1
- data/test/schema/luw/ibm_db_specific_schema.rb +2 -0
- data/test/schema/schema.rb +196 -92
- data/test/schema/zOS/ibm_db_specific_schema.rb +3 -1
- metadata +73 -68
- data/.gitignore +0 -1
- data/test/cases/associations/eager_test.rb +0 -862
- data/test/cases/associations/has_many_through_associations_test.rb +0 -461
- data/test/cases/finder_test.rb +0 -1088
- data/test/cases/fixtures_test.rb +0 -684
@@ -1,7 +1,9 @@
|
|
1
1
|
require "cases/helper"
|
2
|
+
require 'active_support/core_ext/object/inclusion'
|
2
3
|
require 'models/tag'
|
3
4
|
require 'models/tagging'
|
4
5
|
require 'models/post'
|
6
|
+
require 'models/rating'
|
5
7
|
require 'models/item'
|
6
8
|
require 'models/comment'
|
7
9
|
require 'models/author'
|
@@ -11,9 +13,13 @@ require 'models/vertex'
|
|
11
13
|
require 'models/edge'
|
12
14
|
require 'models/book'
|
13
15
|
require 'models/citation'
|
16
|
+
require 'models/aircraft'
|
17
|
+
require 'models/engine'
|
18
|
+
require 'models/car'
|
14
19
|
|
15
20
|
class AssociationsJoinModelTest < ActiveRecord::TestCase
|
16
|
-
self.use_transactional_fixtures = false
|
21
|
+
self.use_transactional_fixtures = false unless supports_savepoints?
|
22
|
+
|
17
23
|
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
|
18
24
|
# Reload edges table from fixtures as otherwise repeated test was failing
|
19
25
|
:edges
|
@@ -43,43 +49,14 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
43
49
|
assert_queries(1) { assert_equal 0, author.unique_categorized_posts.count(:title, :conditions => "title is NULL") }
|
44
50
|
assert !authors(:mary).unique_categorized_posts.loaded?
|
45
51
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
# LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
|
56
|
-
# An expression in the ORDER BY clause in the following position,
|
57
|
-
# or starting with "DEVELOPERS" in the "ORDER BY" clause is not valid.
|
58
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
59
|
-
# SELECT DISTINCT projects.id FROM projects
|
60
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
61
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
62
|
-
# ORDER BY developers.created_at
|
63
|
-
#
|
64
|
-
# i5: [IBM][CLI Driver][AS] SQL0214N
|
65
|
-
# An expression in the ORDER BY clause in the following position,
|
66
|
-
# or starting with "1" in the "CREATED_AT" clause is not valid.
|
67
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
68
|
-
# SELECT DISTINCT projects.id FROM projects
|
69
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
70
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
71
|
-
# ORDER BY developers.created_at
|
72
|
-
#
|
73
|
-
# zOS 9:[IBM][CLI Driver][DB2] SQL0214N
|
74
|
-
# An expression in the ORDER BY clause in the following position,
|
75
|
-
# or starting with "CREATED_AT" in the "ORDER BY" clause is not valid.
|
76
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
77
|
-
# SELECT DISTINCT projects.id FROM projects
|
78
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
79
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
80
|
-
# ORDER BY developers.created_at
|
81
|
-
#
|
82
|
-
end
|
52
|
+
|
53
|
+
def test_has_many_uniq_through_find
|
54
|
+
assert_equal 1, authors(:mary).unique_categorized_posts.find(:all).size
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_has_many_uniq_through_dynamic_find
|
58
|
+
assert_equal 1, authors(:mary).unique_categorized_posts.find_all_by_title("So I was thinking").size
|
59
|
+
end
|
83
60
|
|
84
61
|
def test_polymorphic_has_many_going_through_join_model
|
85
62
|
assert_equal tags(:general), tag = posts(:welcome).tags.first
|
@@ -114,16 +91,9 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
114
91
|
end
|
115
92
|
end
|
116
93
|
|
117
|
-
def test_polymorphic_has_many_going_through_join_model_with_disabled_include
|
118
|
-
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
|
119
|
-
assert_queries 1 do
|
120
|
-
tag.tagging
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
94
|
def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
|
125
95
|
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
|
126
|
-
tag.author_id
|
96
|
+
assert_nothing_raised(NoMethodError) { tag.author_id }
|
127
97
|
end
|
128
98
|
|
129
99
|
def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
|
@@ -169,7 +139,21 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
169
139
|
def test_set_polymorphic_has_one
|
170
140
|
tagging = tags(:misc).taggings.create
|
171
141
|
posts(:thinking).tagging = tagging
|
172
|
-
|
142
|
+
|
143
|
+
assert_equal "Post", tagging.taggable_type
|
144
|
+
assert_equal posts(:thinking).id, tagging.taggable_id
|
145
|
+
assert_equal posts(:thinking), tagging.taggable
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_set_polymorphic_has_one_on_new_record
|
149
|
+
tagging = tags(:misc).taggings.create
|
150
|
+
post = Post.new :title => "foo", :body => "bar"
|
151
|
+
post.tagging = tagging
|
152
|
+
post.save!
|
153
|
+
|
154
|
+
assert_equal "Post", tagging.taggable_type
|
155
|
+
assert_equal post.id, tagging.taggable_id
|
156
|
+
assert_equal post, tagging.taggable
|
173
157
|
end
|
174
158
|
|
175
159
|
def test_create_polymorphic_has_many_with_scope
|
@@ -188,14 +172,14 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
188
172
|
|
189
173
|
def test_create_polymorphic_has_one_with_scope
|
190
174
|
old_count = Tagging.count
|
191
|
-
tagging = posts(:welcome).
|
175
|
+
tagging = posts(:welcome).create_tagging(:tag => tags(:misc))
|
192
176
|
assert_equal "Post", tagging.taggable_type
|
193
177
|
assert_equal old_count+1, Tagging.count
|
194
178
|
end
|
195
179
|
|
196
180
|
def test_delete_polymorphic_has_many_with_delete_all
|
197
181
|
assert_equal 1, posts(:welcome).taggings.count
|
198
|
-
posts(:welcome).taggings.first.
|
182
|
+
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyDeleteAll'
|
199
183
|
post = find_post_with_dependency(1, :has_many, :taggings, :delete_all)
|
200
184
|
|
201
185
|
old_count = Tagging.count
|
@@ -206,7 +190,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
206
190
|
|
207
191
|
def test_delete_polymorphic_has_many_with_destroy
|
208
192
|
assert_equal 1, posts(:welcome).taggings.count
|
209
|
-
posts(:welcome).taggings.first.
|
193
|
+
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyDestroy'
|
210
194
|
post = find_post_with_dependency(1, :has_many, :taggings, :destroy)
|
211
195
|
|
212
196
|
old_count = Tagging.count
|
@@ -217,7 +201,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
217
201
|
|
218
202
|
def test_delete_polymorphic_has_many_with_nullify
|
219
203
|
assert_equal 1, posts(:welcome).taggings.count
|
220
|
-
posts(:welcome).taggings.first.
|
204
|
+
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyNullify'
|
221
205
|
post = find_post_with_dependency(1, :has_many, :taggings, :nullify)
|
222
206
|
|
223
207
|
old_count = Tagging.count
|
@@ -228,7 +212,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
228
212
|
|
229
213
|
def test_delete_polymorphic_has_one_with_destroy
|
230
214
|
assert posts(:welcome).tagging
|
231
|
-
posts(:welcome).tagging.
|
215
|
+
posts(:welcome).tagging.update_column :taggable_type, 'PostWithHasOneDestroy'
|
232
216
|
post = find_post_with_dependency(1, :has_one, :tagging, :destroy)
|
233
217
|
|
234
218
|
old_count = Tagging.count
|
@@ -239,7 +223,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
239
223
|
|
240
224
|
def test_delete_polymorphic_has_one_with_nullify
|
241
225
|
assert posts(:welcome).tagging
|
242
|
-
posts(:welcome).tagging.
|
226
|
+
posts(:welcome).tagging.update_column :taggable_type, 'PostWithHasOneNullify'
|
243
227
|
post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
|
244
228
|
|
245
229
|
old_count = Tagging.count
|
@@ -249,7 +233,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
249
233
|
end
|
250
234
|
|
251
235
|
def test_has_many_with_piggyback
|
252
|
-
assert_equal "2", categories(:sti_test).
|
236
|
+
assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
|
253
237
|
end
|
254
238
|
|
255
239
|
def test_include_has_many_through
|
@@ -323,10 +307,26 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
323
307
|
end
|
324
308
|
|
325
309
|
def test_has_many_going_through_join_model_with_custom_foreign_key
|
326
|
-
assert_equal [], posts(:thinking).authors
|
310
|
+
assert_equal [authors(:bob)], posts(:thinking).authors
|
327
311
|
assert_equal [authors(:mary)], posts(:authorless).authors
|
328
312
|
end
|
329
313
|
|
314
|
+
def test_has_many_going_through_join_model_with_custom_primary_key
|
315
|
+
assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
|
319
|
+
assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_has_many_through_with_custom_primary_key_on_belongs_to_source
|
323
|
+
assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
|
324
|
+
end
|
325
|
+
|
326
|
+
def test_has_many_through_with_custom_primary_key_on_has_many_source
|
327
|
+
assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
|
328
|
+
end
|
329
|
+
|
330
330
|
def test_both_scoped_and_explicit_joins_should_be_respected
|
331
331
|
assert_nothing_raised do
|
332
332
|
Post.send(:with_scope, :find => {:joins => "left outer join comments on comments.id = posts.id"}) do
|
@@ -353,11 +353,16 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
353
353
|
end
|
354
354
|
|
355
355
|
def test_has_many_polymorphic
|
356
|
-
assert_raise ActiveRecord::
|
357
|
-
|
356
|
+
assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
|
357
|
+
tags(:general).taggables
|
358
|
+
end
|
359
|
+
|
360
|
+
assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
|
361
|
+
taggings(:welcome_general).things
|
358
362
|
end
|
363
|
+
|
359
364
|
assert_raise ActiveRecord::EagerLoadPolymorphicError do
|
360
|
-
|
365
|
+
tags(:general).taggings.find(:all, :include => :taggable, :conditions => 'bogus_table.column = 1')
|
361
366
|
end
|
362
367
|
end
|
363
368
|
|
@@ -398,7 +403,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
398
403
|
end
|
399
404
|
|
400
405
|
def test_has_many_through_polymorphic_has_one
|
401
|
-
assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging
|
406
|
+
assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging.order(:id)
|
402
407
|
end
|
403
408
|
|
404
409
|
def test_has_many_through_polymorphic_has_many
|
@@ -413,50 +418,16 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
413
418
|
end
|
414
419
|
end
|
415
420
|
|
416
|
-
|
417
|
-
|
418
|
-
end
|
419
|
-
|
420
|
-
def test_has_many_through_habtm
|
421
|
-
assert_raise(ActiveRecord::HasManyThroughSourceAssociationMacroError) { authors(:david).post_categories }
|
422
|
-
end
|
423
|
-
|
424
|
-
unless current_adapter?(:IBM_DBAdapter)
|
421
|
+
unless current_adapter?(:IBM_DBAdapter)
|
422
|
+
# DB2 throws SQL0214N
|
425
423
|
def test_eager_load_has_many_through_has_many
|
426
424
|
author = Author.find :first, :conditions => ['name = ?', 'David'], :include => :comments, :order => 'comments.id'
|
427
425
|
SpecialComment.new; VerySpecialComment.new
|
428
426
|
assert_no_queries do
|
429
|
-
assert_equal [1,2,3,5,6,7,8,9,10], author.comments.collect(&:id)
|
427
|
+
assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
|
430
428
|
end
|
431
429
|
end
|
432
|
-
|
433
|
-
# An expression in the ORDER BY clause in the following position,
|
434
|
-
# or starting with "DEVELOPERS" in the "ORDER BY" clause is not valid.
|
435
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
436
|
-
# SELECT DISTINCT projects.id FROM projects
|
437
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
438
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
439
|
-
# ORDER BY developers.created_at
|
440
|
-
#
|
441
|
-
# i5: [IBM][CLI Driver][AS] SQL0214N
|
442
|
-
# An expression in the ORDER BY clause in the following position,
|
443
|
-
# or starting with "1" in the "CREATED_AT" clause is not valid.
|
444
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
445
|
-
# SELECT DISTINCT projects.id FROM projects
|
446
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
447
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
448
|
-
# ORDER BY developers.created_at
|
449
|
-
#
|
450
|
-
# zOS 9:[IBM][CLI Driver][DB2] SQL0214N
|
451
|
-
# An expression in the ORDER BY clause in the following position,
|
452
|
-
# or starting with "CREATED_AT" in the "ORDER BY" clause is not valid.
|
453
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
454
|
-
# SELECT DISTINCT projects.id FROM projects
|
455
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
456
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
457
|
-
# ORDER BY developers.created_at
|
458
|
-
#
|
459
|
-
end
|
430
|
+
end
|
460
431
|
|
461
432
|
def test_eager_load_has_many_through_has_many_with_conditions
|
462
433
|
post = Post.find(:first, :include => :invalid_tags)
|
@@ -484,7 +455,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
484
455
|
end
|
485
456
|
|
486
457
|
def test_has_many_through_uses_conditions_specified_on_the_has_many_association
|
487
|
-
author = Author.
|
458
|
+
author = Author.order(:id).first
|
488
459
|
assert_present author.comments
|
489
460
|
assert_blank author.nonexistant_comments
|
490
461
|
end
|
@@ -503,7 +474,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
503
474
|
assert saved_post.tags.include?(new_tag)
|
504
475
|
|
505
476
|
assert new_tag.persisted?
|
506
|
-
assert saved_post.reload.tags(true)
|
477
|
+
assert new_tag.in?(saved_post.reload.tags(true))
|
507
478
|
|
508
479
|
|
509
480
|
new_post = Post.new(:title => "Association replacmenet works!", :body => "You best believe it.")
|
@@ -516,7 +487,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
516
487
|
|
517
488
|
new_post.save!
|
518
489
|
assert new_post.persisted?
|
519
|
-
assert new_post.reload.tags(true)
|
490
|
+
assert saved_tag.in?(new_post.reload.tags(true))
|
520
491
|
|
521
492
|
assert !posts(:thinking).tags.build.persisted?
|
522
493
|
assert !posts(:thinking).tags.new.persisted?
|
@@ -554,17 +525,21 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
554
525
|
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
555
526
|
end
|
556
527
|
|
528
|
+
def test_add_to_join_table_with_no_id
|
529
|
+
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
530
|
+
end
|
531
|
+
|
557
532
|
def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
|
558
533
|
author = authors(:david)
|
559
|
-
assert_equal
|
534
|
+
assert_equal 10, author.comments.size
|
560
535
|
assert !author.comments.loaded?
|
561
536
|
end
|
562
537
|
|
563
538
|
def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
|
564
|
-
|
565
|
-
|
566
|
-
assert_equal 100,
|
567
|
-
assert !
|
539
|
+
c = categories(:general)
|
540
|
+
c.categorizations_count = 100
|
541
|
+
assert_equal 100, c.categorizations.size
|
542
|
+
assert !c.categorizations.loaded?
|
568
543
|
end
|
569
544
|
|
570
545
|
def test_adding_junk_to_has_many_through_should_raise_type_mismatch
|
@@ -645,37 +620,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
645
620
|
def test_uniq_has_many_through_should_retain_order
|
646
621
|
comment_ids = authors(:david).comments.map(&:id)
|
647
622
|
assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
|
648
|
-
|
649
|
-
unless current_adapter?(:IBM_DBAdapter)
|
650
|
-
assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
|
651
|
-
# LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
|
652
|
-
# An expression in the ORDER BY clause in the following position,
|
653
|
-
# or starting with "DEVELOPERS" in the "ORDER BY" clause is not valid.
|
654
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
655
|
-
# SELECT DISTINCT projects.id FROM projects
|
656
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
657
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
658
|
-
# ORDER BY developers.created_at
|
659
|
-
#
|
660
|
-
# i5: [IBM][CLI Driver][AS] SQL0214N
|
661
|
-
# An expression in the ORDER BY clause in the following position,
|
662
|
-
# or starting with "1" in the "CREATED_AT" clause is not valid.
|
663
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
664
|
-
# SELECT DISTINCT projects.id FROM projects
|
665
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
666
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
667
|
-
# ORDER BY developers.created_at
|
668
|
-
#
|
669
|
-
# zOS 9:[IBM][CLI Driver][DB2] SQL0214N
|
670
|
-
# An expression in the ORDER BY clause in the following position,
|
671
|
-
# or starting with "CREATED_AT" in the "ORDER BY" clause is not valid.
|
672
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
673
|
-
# SELECT DISTINCT projects.id FROM projects
|
674
|
-
# LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
|
675
|
-
# LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
|
676
|
-
# ORDER BY developers.created_at
|
677
|
-
#
|
678
|
-
end
|
623
|
+
assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
|
679
624
|
end
|
680
625
|
|
681
626
|
def test_polymorphic_has_many
|
@@ -707,7 +652,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
707
652
|
end
|
708
653
|
|
709
654
|
def test_preload_polymorph_many_types
|
710
|
-
taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel']
|
655
|
+
taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel'], :order => 'id'
|
711
656
|
assert_no_queries do
|
712
657
|
taggings.first.taggable.id
|
713
658
|
taggings[1].taggable.id
|
@@ -720,7 +665,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
720
665
|
|
721
666
|
def test_preload_nil_polymorphic_belongs_to
|
722
667
|
assert_nothing_raised do
|
723
|
-
|
668
|
+
Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL'])
|
724
669
|
end
|
725
670
|
end
|
726
671
|
|
@@ -763,16 +708,15 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
763
708
|
end
|
764
709
|
assert ! david.categories.loaded?
|
765
710
|
end
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
end
|
711
|
+
|
712
|
+
def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
|
713
|
+
david = authors(:david)
|
714
|
+
category = Category.create!(:name => 'Not Associated')
|
715
|
+
|
716
|
+
assert ! david.categories.loaded?
|
717
|
+
assert ! david.categories.include?(category)
|
718
|
+
end
|
719
|
+
|
776
720
|
def test_has_many_through_goes_through_all_sti_classes
|
777
721
|
sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
|
778
722
|
new_comment = sub_sti_post.comments.create(:body => 'test')
|
@@ -780,13 +724,19 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
780
724
|
assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
|
781
725
|
end
|
782
726
|
|
727
|
+
def test_has_many_with_pluralize_table_names_false
|
728
|
+
aircraft = Aircraft.create!(:name => "Airbus 380")
|
729
|
+
engine = Engine.create!(:car_id => aircraft.id)
|
730
|
+
assert_equal aircraft.engines, [engine]
|
731
|
+
end
|
732
|
+
|
783
733
|
private
|
784
734
|
# create dynamic Post models to allow different dependency options
|
785
735
|
def find_post_with_dependency(post_id, association, association_name, dependency)
|
786
736
|
class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
|
787
|
-
Post.find(post_id).
|
737
|
+
Post.find(post_id).update_column :type, class_name
|
788
738
|
klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
|
789
|
-
klass.
|
739
|
+
klass.table_name = 'posts'
|
790
740
|
klass.send(association, association_name, :as => :taggable, :dependent => dependency)
|
791
741
|
klass.find(post_id)
|
792
742
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "cases/helper"
|
2
|
+
require 'active_support/core_ext/object/inclusion'
|
2
3
|
require 'models/minimalistic'
|
3
4
|
require 'models/developer'
|
4
5
|
require 'models/auto_id'
|
@@ -8,6 +9,8 @@ require 'models/topic'
|
|
8
9
|
require 'models/company'
|
9
10
|
require 'models/category'
|
10
11
|
require 'models/reply'
|
12
|
+
require 'models/contact'
|
13
|
+
require 'models/keyboard'
|
11
14
|
|
12
15
|
class AttributeMethodsTest < ActiveRecord::TestCase
|
13
16
|
fixtures :topics, :developers, :companies, :computers
|
@@ -27,9 +30,36 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
27
30
|
t = Topic.new
|
28
31
|
t.title = "hello there!"
|
29
32
|
t.written_on = Time.now
|
33
|
+
t.author_name = ""
|
30
34
|
assert t.attribute_present?("title")
|
31
35
|
assert t.attribute_present?("written_on")
|
32
36
|
assert !t.attribute_present?("content")
|
37
|
+
assert !t.attribute_present?("author_name")
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_attribute_present_with_booleans
|
42
|
+
b1 = Boolean.new
|
43
|
+
b1.value = false
|
44
|
+
assert b1.attribute_present?(:value)
|
45
|
+
|
46
|
+
b2 = Boolean.new
|
47
|
+
b2.value = true
|
48
|
+
assert b2.attribute_present?(:value)
|
49
|
+
|
50
|
+
b3 = Boolean.new
|
51
|
+
assert !b3.attribute_present?(:value)
|
52
|
+
|
53
|
+
b4 = Boolean.new
|
54
|
+
b4.value = false
|
55
|
+
b4.save!
|
56
|
+
assert Boolean.find(b4.id).attribute_present?(:value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_caching_nil_primary_key
|
60
|
+
klass = Class.new(Minimalistic)
|
61
|
+
klass.expects(:reset_primary_key).returns(nil).once
|
62
|
+
2.times { klass.primary_key }
|
33
63
|
end
|
34
64
|
|
35
65
|
def test_attribute_keys_on_new_instance
|
@@ -75,6 +105,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
75
105
|
def test_respond_to?
|
76
106
|
topic = Topic.find(1)
|
77
107
|
assert_respond_to topic, "title"
|
108
|
+
assert_respond_to topic, "_title"
|
78
109
|
assert_respond_to topic, "title?"
|
79
110
|
assert_respond_to topic, "title="
|
80
111
|
assert_respond_to topic, :title
|
@@ -86,6 +117,39 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
86
117
|
assert !topic.respond_to?(:nothingness)
|
87
118
|
end
|
88
119
|
|
120
|
+
def test_deprecated_underscore_method
|
121
|
+
topic = Topic.find(1)
|
122
|
+
assert_equal topic.title, assert_deprecated { topic._title }
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_respond_to_with_custom_primary_key
|
126
|
+
keyboard = Keyboard.create
|
127
|
+
assert_not_nil keyboard.key_number
|
128
|
+
assert_equal keyboard.key_number, keyboard.id
|
129
|
+
assert keyboard.respond_to?('key_number')
|
130
|
+
assert keyboard.respond_to?('_key_number')
|
131
|
+
assert keyboard.respond_to?('id')
|
132
|
+
assert keyboard.respond_to?('_id')
|
133
|
+
end
|
134
|
+
|
135
|
+
# Syck calls respond_to? before actually calling initialize
|
136
|
+
def test_respond_to_with_allocated_object
|
137
|
+
topic = Topic.allocate
|
138
|
+
assert !topic.respond_to?("nothingness")
|
139
|
+
assert !topic.respond_to?(:nothingness)
|
140
|
+
assert_respond_to topic, "title"
|
141
|
+
assert_respond_to topic, :title
|
142
|
+
end
|
143
|
+
|
144
|
+
# IRB inspects the return value of "MyModel.allocate"
|
145
|
+
# by inspecting it.
|
146
|
+
def test_allocated_object_can_be_inspected
|
147
|
+
topic = Topic.allocate
|
148
|
+
topic.instance_eval { @attributes = nil }
|
149
|
+
assert_nothing_raised { topic.inspect }
|
150
|
+
assert topic.inspect, "#<Topic not initialized>"
|
151
|
+
end
|
152
|
+
|
89
153
|
def test_array_content
|
90
154
|
topic = Topic.new
|
91
155
|
topic.content = %w( one two three )
|
@@ -96,34 +160,55 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
96
160
|
|
97
161
|
def test_read_attributes_before_type_cast
|
98
162
|
category = Category.new({:name=>"Test categoty", :type => nil})
|
99
|
-
category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil}
|
163
|
+
category_attrs = {"name"=>"Test categoty", "id" => nil, "type" => nil, "categorizations_count" => nil}
|
100
164
|
assert_equal category_attrs , category.attributes_before_type_cast
|
101
165
|
end
|
102
166
|
|
103
167
|
if current_adapter?(:MysqlAdapter)
|
104
168
|
def test_read_attributes_before_type_cast_on_boolean
|
105
169
|
bool = Boolean.create({ "value" => false })
|
106
|
-
|
170
|
+
if RUBY_PLATFORM =~ /java/
|
171
|
+
# JRuby will return the value before typecast as string
|
172
|
+
assert_equal "0", bool.reload.attributes_before_type_cast["value"]
|
173
|
+
else
|
174
|
+
assert_equal 0, bool.reload.attributes_before_type_cast["value"]
|
175
|
+
end
|
107
176
|
end
|
108
177
|
end
|
109
178
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# Oracle adapter returns Time before type cast
|
114
|
-
unless current_adapter?(:OracleAdapter)
|
115
|
-
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"]
|
116
|
-
else
|
117
|
-
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db)
|
179
|
+
def test_read_attributes_before_type_cast_on_datetime
|
180
|
+
in_time_zone "Pacific Time (US & Canada)" do
|
181
|
+
record = @target.new
|
118
182
|
|
119
|
-
|
120
|
-
|
121
|
-
|
183
|
+
record.written_on = "345643456"
|
184
|
+
assert_equal "345643456", record.written_on_before_type_cast
|
185
|
+
assert_equal nil, record.written_on
|
122
186
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
187
|
+
record.written_on = "2009-10-11 12:13:14"
|
188
|
+
assert_equal "2009-10-11 12:13:14", record.written_on_before_type_cast
|
189
|
+
assert_equal Time.zone.parse("2009-10-11 12:13:14"), record.written_on
|
190
|
+
assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_read_attributes_after_type_cast_on_datetime
|
195
|
+
tz = "Pacific Time (US & Canada)"
|
196
|
+
|
197
|
+
in_time_zone tz do
|
198
|
+
record = @target.new
|
199
|
+
|
200
|
+
date_string = "2011-03-24"
|
201
|
+
time = Time.zone.parse date_string
|
202
|
+
|
203
|
+
record.written_on = date_string
|
204
|
+
assert_equal date_string, record.written_on_before_type_cast
|
205
|
+
assert_equal time, record.written_on
|
206
|
+
assert_equal ActiveSupport::TimeZone[tz], record.written_on.time_zone
|
207
|
+
|
208
|
+
record.save
|
209
|
+
record.reload
|
210
|
+
|
211
|
+
assert_equal time, record.written_on
|
127
212
|
end
|
128
213
|
end
|
129
214
|
|
@@ -157,7 +242,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
157
242
|
|
158
243
|
def test_case_sensitive_attributes_hash
|
159
244
|
# DB2 is not case-sensitive
|
160
|
-
return true if current_adapter?(:DB2Adapter)
|
245
|
+
return true if current_adapter?(:DB2Adapter,:IBM_DBAdapter)
|
161
246
|
|
162
247
|
assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.find(:first).attributes
|
163
248
|
end
|
@@ -184,8 +269,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
184
269
|
topic.send(:write_attribute, :title, "Still another topic")
|
185
270
|
assert_equal "Still another topic", topic.title
|
186
271
|
|
187
|
-
topic
|
272
|
+
topic[:title] = "Still another topic: part 2"
|
188
273
|
assert_equal "Still another topic: part 2", topic.title
|
274
|
+
|
275
|
+
topic.send(:write_attribute, "title", "Still another topic: part 3")
|
276
|
+
assert_equal "Still another topic: part 3", topic.title
|
277
|
+
|
278
|
+
topic["title"] = "Still another topic: part 4"
|
279
|
+
assert_equal "Still another topic: part 4", topic.title
|
189
280
|
end
|
190
281
|
|
191
282
|
def test_read_attribute
|
@@ -238,6 +329,45 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
238
329
|
# puts ""
|
239
330
|
end
|
240
331
|
|
332
|
+
def test_overridden_write_attribute
|
333
|
+
topic = Topic.new
|
334
|
+
def topic.write_attribute(attr_name, value)
|
335
|
+
super(attr_name, value.downcase)
|
336
|
+
end
|
337
|
+
|
338
|
+
topic.send(:write_attribute, :title, "Yet another topic")
|
339
|
+
assert_equal "yet another topic", topic.title
|
340
|
+
|
341
|
+
topic[:title] = "Yet another topic: part 2"
|
342
|
+
assert_equal "yet another topic: part 2", topic.title
|
343
|
+
|
344
|
+
topic.send(:write_attribute, "title", "Yet another topic: part 3")
|
345
|
+
assert_equal "yet another topic: part 3", topic.title
|
346
|
+
|
347
|
+
topic["title"] = "Yet another topic: part 4"
|
348
|
+
assert_equal "yet another topic: part 4", topic.title
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_overridden_read_attribute
|
352
|
+
topic = Topic.new
|
353
|
+
topic.title = "Stop changing the topic"
|
354
|
+
def topic.read_attribute(attr_name)
|
355
|
+
super(attr_name).upcase
|
356
|
+
end
|
357
|
+
|
358
|
+
assert_equal "STOP CHANGING THE TOPIC", topic.send(:read_attribute, "title")
|
359
|
+
assert_equal "STOP CHANGING THE TOPIC", topic["title"]
|
360
|
+
|
361
|
+
assert_equal "STOP CHANGING THE TOPIC", topic.send(:read_attribute, :title)
|
362
|
+
assert_equal "STOP CHANGING THE TOPIC", topic[:title]
|
363
|
+
end
|
364
|
+
|
365
|
+
def test_read_overridden_attribute
|
366
|
+
topic = Topic.new(:title => 'a')
|
367
|
+
def topic.title() 'b' end
|
368
|
+
assert_equal 'a', topic[:title]
|
369
|
+
end
|
370
|
+
|
241
371
|
def test_query_attribute_string
|
242
372
|
[nil, "", " "].each do |value|
|
243
373
|
assert_equal false, Topic.new(:author_name => value).author_name?
|
@@ -352,7 +482,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
352
482
|
|
353
483
|
def test_typecast_attribute_from_select_to_false
|
354
484
|
topic = Topic.create(:title => 'Budget')
|
355
|
-
# Oracle does not support boolean expressions in SELECT
|
485
|
+
# Oracle and DB2 does not support boolean expressions in SELECT
|
356
486
|
if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
|
357
487
|
topic = Topic.find(:first, :select => "topics.*, 0 as is_test")
|
358
488
|
else
|
@@ -363,7 +493,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
363
493
|
|
364
494
|
def test_typecast_attribute_from_select_to_true
|
365
495
|
topic = Topic.create(:title => 'Budget')
|
366
|
-
# Oracle does not support boolean expressions in SELECT
|
496
|
+
# Oracle and DB2 does not support boolean expressions in SELECT
|
367
497
|
if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
|
368
498
|
topic = Topic.find(:first, :select => "topics.*, 1 as is_test")
|
369
499
|
else
|
@@ -372,30 +502,6 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
372
502
|
assert topic.is_test?
|
373
503
|
end
|
374
504
|
|
375
|
-
def test_kernel_methods_not_implemented_in_activerecord
|
376
|
-
%w(test name display y).each do |method|
|
377
|
-
assert !ActiveRecord::Base.instance_method_already_implemented?(method), "##{method} is defined"
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
def test_defined_kernel_methods_implemented_in_model
|
382
|
-
%w(test name display y).each do |method|
|
383
|
-
klass = Class.new ActiveRecord::Base
|
384
|
-
klass.class_eval "def #{method}() 'defined #{method}' end"
|
385
|
-
assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
|
-
def test_defined_kernel_methods_implemented_in_model_abstract_subclass
|
390
|
-
%w(test name display y).each do |method|
|
391
|
-
abstract = Class.new ActiveRecord::Base
|
392
|
-
abstract.class_eval "def #{method}() 'defined #{method}' end"
|
393
|
-
abstract.abstract_class = true
|
394
|
-
klass = Class.new abstract
|
395
|
-
assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
505
|
def test_raises_dangerous_attribute_error_when_defining_activerecord_method_in_model
|
400
506
|
%w(save create_or_update).each do |method|
|
401
507
|
klass = Class.new ActiveRecord::Base
|
@@ -419,12 +525,8 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
419
525
|
Topic.instance_variable_set "@cached_attributes", nil
|
420
526
|
end
|
421
527
|
|
422
|
-
def
|
423
|
-
|
424
|
-
column_names = Topic.columns.select{|c| column_types.include?(c.type) }.map(&:name)
|
425
|
-
|
426
|
-
assert_equal column_names.sort, Topic.cached_attributes.sort
|
427
|
-
assert_equal time_related_columns_on_topic.sort, Topic.cached_attributes.sort
|
528
|
+
def test_cacheable_columns_are_actually_cached
|
529
|
+
assert_equal cached_columns.sort, Topic.cached_attributes.sort
|
428
530
|
end
|
429
531
|
|
430
532
|
def test_accessing_cached_attributes_caches_the_converted_values_and_nothing_else
|
@@ -435,8 +537,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
435
537
|
assert cache.empty?
|
436
538
|
|
437
539
|
all_columns = Topic.columns.map(&:name)
|
438
|
-
|
439
|
-
uncached_columns = all_columns - cached_columns
|
540
|
+
uncached_columns = all_columns - cached_columns
|
440
541
|
|
441
542
|
all_columns.each do |attr_name|
|
442
543
|
attribute_gets_cached = Topic.cache_attribute?(attr_name)
|
@@ -451,6 +552,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
451
552
|
end
|
452
553
|
end
|
453
554
|
|
555
|
+
def test_write_nil_to_time_attributes
|
556
|
+
in_time_zone "Pacific Time (US & Canada)" do
|
557
|
+
record = @target.new
|
558
|
+
record.written_on = nil
|
559
|
+
assert_nil record.written_on
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
454
563
|
def test_time_attributes_are_retrieved_in_current_time_zone
|
455
564
|
in_time_zone "Pacific Time (US & Canada)" do
|
456
565
|
utc_time = Time.utc(2008, 1, 1)
|
@@ -486,6 +595,17 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
486
595
|
end
|
487
596
|
end
|
488
597
|
|
598
|
+
def test_setting_time_zone_aware_read_attribute
|
599
|
+
utc_time = Time.utc(2008, 1, 1)
|
600
|
+
cst_time = utc_time.in_time_zone("Central Time (US & Canada)")
|
601
|
+
in_time_zone "Pacific Time (US & Canada)" do
|
602
|
+
record = @target.create(:written_on => cst_time).reload
|
603
|
+
assert_equal utc_time, record[:written_on]
|
604
|
+
assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record[:written_on].time_zone
|
605
|
+
assert_equal Time.utc(2007, 12, 31, 16), record[:written_on].time
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
489
609
|
def test_setting_time_zone_aware_attribute_with_string
|
490
610
|
utc_time = Time.utc(2008, 1, 1)
|
491
611
|
(-11..13).each do |timezone_offset|
|
@@ -505,6 +625,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
505
625
|
record = @target.new
|
506
626
|
record.written_on = ' '
|
507
627
|
assert_nil record.written_on
|
628
|
+
assert_nil record[:written_on]
|
508
629
|
end
|
509
630
|
end
|
510
631
|
|
@@ -546,7 +667,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
546
667
|
topic = @target.new(:title => "The pros and cons of programming naked.")
|
547
668
|
assert !topic.respond_to?(:title)
|
548
669
|
exception = assert_raise(NoMethodError) { topic.title }
|
549
|
-
|
670
|
+
assert exception.message.include?("private method")
|
550
671
|
assert_equal "I'm private", topic.send(:title)
|
551
672
|
end
|
552
673
|
|
@@ -556,7 +677,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
556
677
|
topic = @target.new
|
557
678
|
assert !topic.respond_to?(:title=)
|
558
679
|
exception = assert_raise(NoMethodError) { topic.title = "Pants"}
|
559
|
-
|
680
|
+
assert exception.message.include?("private method")
|
560
681
|
topic.send(:title=, "Very large pants")
|
561
682
|
end
|
562
683
|
|
@@ -566,14 +687,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
566
687
|
topic = @target.new(:title => "Isaac Newton's pants")
|
567
688
|
assert !topic.respond_to?(:title?)
|
568
689
|
exception = assert_raise(NoMethodError) { topic.title? }
|
569
|
-
|
690
|
+
assert exception.message.include?("private method")
|
570
691
|
assert topic.send(:title?)
|
571
692
|
end
|
572
693
|
|
573
694
|
def test_bulk_update_respects_access_control
|
574
695
|
privatize("title=(value)")
|
575
696
|
|
576
|
-
assert_raise(ActiveRecord::UnknownAttributeError) {
|
697
|
+
assert_raise(ActiveRecord::UnknownAttributeError) { @target.new(:title => "Rants about pants") }
|
577
698
|
assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } }
|
578
699
|
end
|
579
700
|
|
@@ -592,10 +713,90 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
592
713
|
Object.send(:undef_method, :title) # remove test method from object
|
593
714
|
end
|
594
715
|
|
716
|
+
def test_list_of_serialized_attributes
|
717
|
+
assert_equal %w(content), Topic.serialized_attributes.keys
|
718
|
+
assert_equal %w(preferences), Contact.serialized_attributes.keys
|
719
|
+
end
|
720
|
+
|
721
|
+
def test_instance_method_should_be_defined_on_the_base_class
|
722
|
+
subklass = Class.new(Topic)
|
723
|
+
|
724
|
+
Topic.define_attribute_methods
|
725
|
+
|
726
|
+
instance = subklass.new
|
727
|
+
instance.id = 5
|
728
|
+
assert_equal 5, instance.id
|
729
|
+
assert subklass.method_defined?(:id), "subklass is missing id method"
|
730
|
+
|
731
|
+
Topic.undefine_attribute_methods
|
732
|
+
|
733
|
+
assert_equal 5, instance.id
|
734
|
+
assert subklass.method_defined?(:id), "subklass is missing id method"
|
735
|
+
end
|
736
|
+
|
737
|
+
def test_dispatching_column_attributes_through_method_missing_deprecated
|
738
|
+
Topic.define_attribute_methods
|
739
|
+
|
740
|
+
topic = Topic.new(:id => 5)
|
741
|
+
topic.id = 5
|
742
|
+
|
743
|
+
topic.method(:id).owner.send(:undef_method, :id)
|
744
|
+
|
745
|
+
assert_deprecated do
|
746
|
+
assert_equal 5, topic.id
|
747
|
+
end
|
748
|
+
ensure
|
749
|
+
Topic.undefine_attribute_methods
|
750
|
+
end
|
751
|
+
|
752
|
+
def test_read_attribute_with_nil_should_not_asplode
|
753
|
+
assert_equal nil, Topic.new.read_attribute(nil)
|
754
|
+
end
|
755
|
+
|
756
|
+
# If B < A, and A defines an accessor for 'foo', we don't want to override
|
757
|
+
# that by defining a 'foo' method in the generated methods module for B.
|
758
|
+
# (That module will be inserted between the two, e.g. [B, <GeneratedAttributes>, A].)
|
759
|
+
def test_inherited_custom_accessors
|
760
|
+
klass = Class.new(ActiveRecord::Base) do
|
761
|
+
self.table_name = "topics"
|
762
|
+
self.abstract_class = true
|
763
|
+
def title; "omg"; end
|
764
|
+
def title=(val); self.author_name = val; end
|
765
|
+
end
|
766
|
+
subklass = Class.new(klass)
|
767
|
+
[klass, subklass].each(&:define_attribute_methods)
|
768
|
+
|
769
|
+
topic = subklass.find(1)
|
770
|
+
assert_equal "omg", topic.title
|
771
|
+
|
772
|
+
topic.title = "lol"
|
773
|
+
assert_equal "lol", topic.author_name
|
774
|
+
end
|
775
|
+
|
776
|
+
def test_inherited_hook_removed
|
777
|
+
parent = Class.new(ActiveRecord::Base)
|
778
|
+
parent.table_name = "posts"
|
779
|
+
def parent.inherited(k)
|
780
|
+
end
|
781
|
+
|
782
|
+
klass = Class.new(parent)
|
783
|
+
assert_deprecated { klass.define_attribute_methods }
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_setting_new_attributes_deprecated
|
787
|
+
t = Topic.new
|
788
|
+
assert_deprecated { t[:foo] = "bar" }
|
789
|
+
assert_equal "bar", t.foo
|
790
|
+
assert_equal "bar", t[:foo]
|
791
|
+
end
|
595
792
|
|
596
793
|
private
|
794
|
+
def cached_columns
|
795
|
+
@cached_columns ||= time_related_columns_on_topic.map(&:name)
|
796
|
+
end
|
797
|
+
|
597
798
|
def time_related_columns_on_topic
|
598
|
-
Topic.columns.select{|c| [:time, :date, :datetime, :timestamp]
|
799
|
+
Topic.columns.select { |c| c.type.in?([:time, :date, :datetime, :timestamp]) }
|
599
800
|
end
|
600
801
|
|
601
802
|
def in_time_zone(zone)
|