ibm_db 2.5.9 → 2.5.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -0
- data/README +79 -141
- data/ext/extconf.rb +74 -13
- data/ext/ibm_db.c +20 -5
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +45 -8
- data/test/cases/adapter_test.rb +162 -160
- data/test/cases/associations/belongs_to_associations_test.rb +23 -0
- data/test/cases/associations/cascaded_eager_loading_test.rb +3 -7
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +40 -10
- data/test/cases/associations/join_model_test.rb +4 -4
- data/test/cases/attribute_methods_test.rb +169 -33
- data/test/cases/base_test.rb +302 -77
- data/test/cases/calculations_test.rb +37 -1
- data/test/cases/migration_test.rb +183 -115
- data/test/cases/persistence_test.rb +17 -11
- data/test/cases/query_cache_test.rb +18 -3
- data/test/cases/relations_test.rb +178 -15
- data/test/cases/schema_dumper_test.rb +5 -1
- data/test/cases/transaction_callbacks_test.rb +2 -2
- data/test/cases/xml_serialization_test.rb +133 -1
- data/test/schema/schema.rb +22 -3
- metadata +4 -20
@@ -13,6 +13,7 @@ require 'models/comment'
|
|
13
13
|
require 'models/sponsor'
|
14
14
|
require 'models/member'
|
15
15
|
require 'models/essay'
|
16
|
+
require 'models/toy'
|
16
17
|
|
17
18
|
class BelongsToAssociationsTest < ActiveRecord::TestCase
|
18
19
|
fixtures :accounts, :companies, :developers, :projects, :topics,
|
@@ -300,6 +301,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
300
301
|
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
301
302
|
end
|
302
303
|
|
304
|
+
def test_belongs_to_counter_when_update_column
|
305
|
+
topic = Topic.create!(:title => "37s")
|
306
|
+
topic.replies.create!(:title => "re: 37s", :content => "rails")
|
307
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
308
|
+
|
309
|
+
topic.update_column(:content, "rails is wonderfull")
|
310
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
311
|
+
end
|
312
|
+
|
303
313
|
def test_assignment_before_child_saved
|
304
314
|
final_cut = Client.new("name" => "Final Cut")
|
305
315
|
firm = Firm.find(1)
|
@@ -347,6 +357,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
347
357
|
assert_equal members(:groucho), sponsor.sponsorable
|
348
358
|
end
|
349
359
|
|
360
|
+
def test_dont_find_target_when_foreign_key_is_null
|
361
|
+
tagging = taggings(:thinking_general)
|
362
|
+
queries = assert_sql { tagging.super_tag }
|
363
|
+
assert_equal 0, queries.length
|
364
|
+
end
|
365
|
+
|
350
366
|
def test_field_name_same_as_foreign_key
|
351
367
|
computer = Computer.find(1)
|
352
368
|
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
|
@@ -685,4 +701,11 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
685
701
|
assert_equal nil, comment.reload.parent
|
686
702
|
assert_equal 0, comments(:greetings).reload.children_count
|
687
703
|
end
|
704
|
+
|
705
|
+
def test_polymorphic_with_custom_primary_key
|
706
|
+
toy = Toy.create!
|
707
|
+
sponsor = Sponsor.create!(:sponsorable => toy)
|
708
|
+
|
709
|
+
assert_equal toy, sponsor.reload.sponsorable
|
710
|
+
end
|
688
711
|
end
|
@@ -8,10 +8,12 @@ require 'models/company'
|
|
8
8
|
require 'models/topic'
|
9
9
|
require 'models/reply'
|
10
10
|
require 'models/person'
|
11
|
+
require 'models/vertex'
|
12
|
+
require 'models/edge'
|
11
13
|
|
12
14
|
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
13
15
|
fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments,
|
14
|
-
:categorizations, :people, :categories
|
16
|
+
:categorizations, :people, :categories, :edges, :vertices
|
15
17
|
|
16
18
|
def test_eager_association_loading_with_cascaded_two_levels
|
17
19
|
authors = Author.find(:all, :include=>{:posts=>:comments}, :order=>"authors.id")
|
@@ -166,12 +168,6 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
166
168
|
authors[2].post_about_thinking.comments.first
|
167
169
|
end
|
168
170
|
end
|
169
|
-
end
|
170
|
-
|
171
|
-
require 'models/vertex'
|
172
|
-
require 'models/edge'
|
173
|
-
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
174
|
-
fixtures :edges, :vertices
|
175
171
|
|
176
172
|
def test_eager_association_loading_with_recursive_cascading_four_levels_has_many_through
|
177
173
|
source = Vertex.find(:first, :include=>{:sinks=>{:sinks=>{:sinks=>:sinks}}}, :order => 'vertices.id')
|
@@ -23,7 +23,7 @@ require 'models/treaty'
|
|
23
23
|
require 'active_support/core_ext/string/conversions'
|
24
24
|
|
25
25
|
class ProjectWithAfterCreateHook < ActiveRecord::Base
|
26
|
-
|
26
|
+
self.table_name = 'projects'
|
27
27
|
has_and_belongs_to_many :developers,
|
28
28
|
:class_name => "DeveloperForProjectWithAfterCreateHook",
|
29
29
|
:join_table => "developers_projects",
|
@@ -39,7 +39,7 @@ class ProjectWithAfterCreateHook < ActiveRecord::Base
|
|
39
39
|
end
|
40
40
|
|
41
41
|
class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
42
|
-
|
42
|
+
self.table_name = 'developers'
|
43
43
|
has_and_belongs_to_many :projects,
|
44
44
|
:class_name => "ProjectWithAfterCreateHook",
|
45
45
|
:join_table => "developers_projects",
|
@@ -48,7 +48,7 @@ class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
|
48
48
|
end
|
49
49
|
|
50
50
|
class ProjectWithSymbolsForKeys < ActiveRecord::Base
|
51
|
-
|
51
|
+
self.table_name = 'projects'
|
52
52
|
has_and_belongs_to_many :developers,
|
53
53
|
:class_name => "DeveloperWithSymbolsForKeys",
|
54
54
|
:join_table => :developers_projects,
|
@@ -57,7 +57,7 @@ class ProjectWithSymbolsForKeys < ActiveRecord::Base
|
|
57
57
|
end
|
58
58
|
|
59
59
|
class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
60
|
-
|
60
|
+
self.table_name = 'developers'
|
61
61
|
has_and_belongs_to_many :projects,
|
62
62
|
:class_name => "ProjectWithSymbolsForKeys",
|
63
63
|
:join_table => :developers_projects,
|
@@ -66,7 +66,7 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
|
66
66
|
end
|
67
67
|
|
68
68
|
class DeveloperWithCounterSQL < ActiveRecord::Base
|
69
|
-
|
69
|
+
self.table_name = 'developers'
|
70
70
|
has_and_belongs_to_many :projects,
|
71
71
|
:class_name => "DeveloperWithCounterSQL",
|
72
72
|
:join_table => "developers_projects",
|
@@ -77,7 +77,7 @@ end
|
|
77
77
|
|
78
78
|
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
79
79
|
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
|
80
|
-
:parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
|
80
|
+
:parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings
|
81
81
|
|
82
82
|
def setup_data_for_habtm_case
|
83
83
|
ActiveRecord::Base.connection.execute('delete from countries_treaties')
|
@@ -100,10 +100,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
100
100
|
assert_equal 'c1', record[0]
|
101
101
|
assert_equal 't1', record[1]
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
def test_proper_usage_of_primary_keys_and_join_table
|
105
105
|
setup_data_for_habtm_case
|
106
106
|
|
107
|
+
assert_equal 'country_id', Country.primary_key
|
108
|
+
assert_equal 'treaty_id', Treaty.primary_key
|
109
|
+
|
107
110
|
country = Country.first
|
108
111
|
assert_equal 1, country.treaties.count
|
109
112
|
end
|
@@ -442,6 +445,26 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
442
445
|
assert david.projects(true).empty?
|
443
446
|
end
|
444
447
|
|
448
|
+
def test_destroy_associations_destroys_multiple_associations
|
449
|
+
george = parrots(:george)
|
450
|
+
assert !george.pirates.empty?
|
451
|
+
assert !george.treasures.empty?
|
452
|
+
|
453
|
+
assert_no_difference "Pirate.count" do
|
454
|
+
assert_no_difference "Treasure.count" do
|
455
|
+
george.destroy_associations
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
join_records = Parrot.connection.select_all("SELECT * FROM parrots_pirates WHERE parrot_id = #{george.id}")
|
460
|
+
assert join_records.empty?
|
461
|
+
assert george.pirates(true).empty?
|
462
|
+
|
463
|
+
join_records = Parrot.connection.select_all("SELECT * FROM parrots_treasures WHERE parrot_id = #{george.id}")
|
464
|
+
assert join_records.empty?
|
465
|
+
assert george.treasures(true).empty?
|
466
|
+
end
|
467
|
+
|
445
468
|
def test_deprecated_push_with_attributes_was_removed
|
446
469
|
jamis = developers(:jamis)
|
447
470
|
assert_raise(NoMethodError) do
|
@@ -647,6 +670,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
647
670
|
assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
|
648
671
|
end
|
649
672
|
|
673
|
+
def test_habtm_selects_all_columns_by_default
|
674
|
+
assert_equal Project.column_names.sort, developers(:david).projects.first.attributes.keys.sort
|
675
|
+
end
|
676
|
+
|
677
|
+
def test_habtm_respects_select_query_method
|
678
|
+
assert_equal ['id'], developers(:david).projects.select(:id).first.attributes.keys
|
679
|
+
end
|
680
|
+
|
650
681
|
def test_join_table_alias
|
651
682
|
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
|
652
683
|
end
|
@@ -794,12 +825,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
794
825
|
# clear cache possibly created by other tests
|
795
826
|
david.projects.reset_column_information
|
796
827
|
|
797
|
-
|
798
|
-
assert_queries(2) { david.projects.columns; david.projects.columns }
|
828
|
+
assert_queries(1) { david.projects.columns; david.projects.columns }
|
799
829
|
|
800
830
|
## and again to verify that reset_column_information clears the cache correctly
|
801
831
|
david.projects.reset_column_information
|
802
|
-
assert_queries(
|
832
|
+
assert_queries(1) { david.projects.columns; david.projects.columns }
|
803
833
|
end
|
804
834
|
|
805
835
|
def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
|
@@ -403,7 +403,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
403
403
|
end
|
404
404
|
|
405
405
|
def test_has_many_through_polymorphic_has_one
|
406
|
-
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)
|
407
407
|
end
|
408
408
|
|
409
409
|
def test_has_many_through_polymorphic_has_many
|
@@ -455,7 +455,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
455
455
|
end
|
456
456
|
|
457
457
|
def test_has_many_through_uses_conditions_specified_on_the_has_many_association
|
458
|
-
author = Author.
|
458
|
+
author = Author.order(:id).first
|
459
459
|
assert_present author.comments
|
460
460
|
assert_blank author.nonexistant_comments
|
461
461
|
end
|
@@ -652,7 +652,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
652
652
|
end
|
653
653
|
|
654
654
|
def test_preload_polymorph_many_types
|
655
|
-
taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel']
|
655
|
+
taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel'], :order => 'id'
|
656
656
|
assert_no_queries do
|
657
657
|
taggings.first.taggable.id
|
658
658
|
taggings[1].taggable.id
|
@@ -736,7 +736,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
|
736
736
|
class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
|
737
737
|
Post.find(post_id).update_column :type, class_name
|
738
738
|
klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
|
739
|
-
klass.
|
739
|
+
klass.table_name = 'posts'
|
740
740
|
klass.send(association, association_name, :as => :taggable, :dependent => dependency)
|
741
741
|
klass.find(post_id)
|
742
742
|
end
|
@@ -30,9 +30,36 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
30
30
|
t = Topic.new
|
31
31
|
t.title = "hello there!"
|
32
32
|
t.written_on = Time.now
|
33
|
+
t.author_name = ""
|
33
34
|
assert t.attribute_present?("title")
|
34
35
|
assert t.attribute_present?("written_on")
|
35
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 }
|
36
63
|
end
|
37
64
|
|
38
65
|
def test_attribute_keys_on_new_instance
|
@@ -90,6 +117,11 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
90
117
|
assert !topic.respond_to?(:nothingness)
|
91
118
|
end
|
92
119
|
|
120
|
+
def test_deprecated_underscore_method
|
121
|
+
topic = Topic.find(1)
|
122
|
+
assert_equal topic.title, assert_deprecated { topic._title }
|
123
|
+
end
|
124
|
+
|
93
125
|
def test_respond_to_with_custom_primary_key
|
94
126
|
keyboard = Keyboard.create
|
95
127
|
assert_not_nil keyboard.key_number
|
@@ -109,6 +141,15 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
109
141
|
assert_respond_to topic, :title
|
110
142
|
end
|
111
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
|
+
|
112
153
|
def test_array_content
|
113
154
|
topic = Topic.new
|
114
155
|
topic.content = %w( one two three )
|
@@ -228,8 +269,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
228
269
|
topic.send(:write_attribute, :title, "Still another topic")
|
229
270
|
assert_equal "Still another topic", topic.title
|
230
271
|
|
231
|
-
topic
|
272
|
+
topic[:title] = "Still another topic: part 2"
|
232
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
|
233
280
|
end
|
234
281
|
|
235
282
|
def test_read_attribute
|
@@ -282,6 +329,39 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
282
329
|
# puts ""
|
283
330
|
end
|
284
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
|
+
|
285
365
|
def test_read_overridden_attribute
|
286
366
|
topic = Topic.new(:title => 'a')
|
287
367
|
def topic.title() 'b' end
|
@@ -422,30 +502,6 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
422
502
|
assert topic.is_test?
|
423
503
|
end
|
424
504
|
|
425
|
-
def test_kernel_methods_not_implemented_in_activerecord
|
426
|
-
%w(test name display y).each do |method|
|
427
|
-
assert !ActiveRecord::Base.instance_method_already_implemented?(method), "##{method} is defined"
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
def test_defined_kernel_methods_implemented_in_model
|
432
|
-
%w(test name display y).each do |method|
|
433
|
-
klass = Class.new ActiveRecord::Base
|
434
|
-
klass.class_eval "def #{method}() 'defined #{method}' end"
|
435
|
-
assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
def test_defined_kernel_methods_implemented_in_model_abstract_subclass
|
440
|
-
%w(test name display y).each do |method|
|
441
|
-
abstract = Class.new ActiveRecord::Base
|
442
|
-
abstract.class_eval "def #{method}() 'defined #{method}' end"
|
443
|
-
abstract.abstract_class = true
|
444
|
-
klass = Class.new abstract
|
445
|
-
assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
|
446
|
-
end
|
447
|
-
end
|
448
|
-
|
449
505
|
def test_raises_dangerous_attribute_error_when_defining_activerecord_method_in_model
|
450
506
|
%w(save create_or_update).each do |method|
|
451
507
|
klass = Class.new ActiveRecord::Base
|
@@ -539,6 +595,17 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
539
595
|
end
|
540
596
|
end
|
541
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
|
+
|
542
609
|
def test_setting_time_zone_aware_attribute_with_string
|
543
610
|
utc_time = Time.utc(2008, 1, 1)
|
544
611
|
(-11..13).each do |timezone_offset|
|
@@ -558,6 +625,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
558
625
|
record = @target.new
|
559
626
|
record.written_on = ' '
|
560
627
|
assert_nil record.written_on
|
628
|
+
assert_nil record[:written_on]
|
561
629
|
end
|
562
630
|
end
|
563
631
|
|
@@ -599,7 +667,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
599
667
|
topic = @target.new(:title => "The pros and cons of programming naked.")
|
600
668
|
assert !topic.respond_to?(:title)
|
601
669
|
exception = assert_raise(NoMethodError) { topic.title }
|
602
|
-
|
670
|
+
assert exception.message.include?("private method")
|
603
671
|
assert_equal "I'm private", topic.send(:title)
|
604
672
|
end
|
605
673
|
|
@@ -609,7 +677,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
609
677
|
topic = @target.new
|
610
678
|
assert !topic.respond_to?(:title=)
|
611
679
|
exception = assert_raise(NoMethodError) { topic.title = "Pants"}
|
612
|
-
|
680
|
+
assert exception.message.include?("private method")
|
613
681
|
topic.send(:title=, "Very large pants")
|
614
682
|
end
|
615
683
|
|
@@ -619,7 +687,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
619
687
|
topic = @target.new(:title => "Isaac Newton's pants")
|
620
688
|
assert !topic.respond_to?(:title?)
|
621
689
|
exception = assert_raise(NoMethodError) { topic.title? }
|
622
|
-
|
690
|
+
assert exception.message.include?("private method")
|
623
691
|
assert topic.send(:title?)
|
624
692
|
end
|
625
693
|
|
@@ -650,19 +718,87 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|
650
718
|
assert_equal %w(preferences), Contact.serialized_attributes.keys
|
651
719
|
end
|
652
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
|
792
|
+
|
653
793
|
private
|
654
794
|
def cached_columns
|
655
|
-
@cached_columns ||=
|
795
|
+
@cached_columns ||= time_related_columns_on_topic.map(&:name)
|
656
796
|
end
|
657
797
|
|
658
798
|
def time_related_columns_on_topic
|
659
799
|
Topic.columns.select { |c| c.type.in?([:time, :date, :datetime, :timestamp]) }
|
660
800
|
end
|
661
801
|
|
662
|
-
def serialized_columns_on_topic
|
663
|
-
Topic.columns.select { |c| Topic.serialized_attributes.include?(c.name) }
|
664
|
-
end
|
665
|
-
|
666
802
|
def in_time_zone(zone)
|
667
803
|
old_zone = Time.zone
|
668
804
|
old_tz = ActiveRecord::Base.time_zone_aware_attributes
|