ibm_db 2.5.5 → 2.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,46 +1,326 @@
1
1
  require "cases/helper"
2
- require 'models/topic'
3
2
  require 'models/minimalistic'
3
+ require 'models/developer'
4
+ require 'models/auto_id'
5
+ require 'models/boolean'
6
+ require 'models/computer'
7
+ require 'models/topic'
8
+ require 'models/company'
9
+ require 'models/category'
10
+ require 'models/reply'
4
11
 
5
12
  class AttributeMethodsTest < ActiveRecord::TestCase
6
- fixtures :topics
13
+ fixtures :topics, :developers, :companies, :computers
14
+
7
15
  def setup
8
- @old_suffixes = ActiveRecord::Base.send(:attribute_method_suffixes).dup
16
+ @old_matchers = ActiveRecord::Base.send(:attribute_method_matchers).dup
9
17
  @target = Class.new(ActiveRecord::Base)
10
18
  @target.table_name = 'topics'
11
19
  end
12
-
20
+
13
21
  def teardown
14
- ActiveRecord::Base.send(:attribute_method_suffixes).clear
15
- ActiveRecord::Base.attribute_method_suffix *@old_suffixes
16
- end
17
-
18
- def test_match_attribute_method_query_returns_match_data
19
- assert_not_nil md = @target.match_attribute_method?('title=')
20
- assert_equal 'title', md.pre_match
21
- assert_equal ['='], md.captures
22
-
23
- %w(_hello_world ist! _maybe?).each do |suffix|
24
- @target.class_eval "def attribute#{suffix}(*args) args end"
25
- @target.attribute_method_suffix suffix
26
-
27
- assert_not_nil md = @target.match_attribute_method?("title#{suffix}")
28
- assert_equal 'title', md.pre_match
29
- assert_equal [suffix], md.captures
22
+ ActiveRecord::Base.send(:attribute_method_matchers).clear
23
+ ActiveRecord::Base.send(:attribute_method_matchers).concat(@old_matchers)
24
+ end
25
+
26
+ def test_attribute_present
27
+ t = Topic.new
28
+ t.title = "hello there!"
29
+ t.written_on = Time.now
30
+ assert t.attribute_present?("title")
31
+ assert t.attribute_present?("written_on")
32
+ assert !t.attribute_present?("content")
33
+ end
34
+
35
+ def test_attribute_keys_on_new_instance
36
+ t = Topic.new
37
+ assert_equal nil, t.title, "The topics table has a title column, so it should be nil"
38
+ assert_raise(NoMethodError) { t.title2 }
39
+ end
40
+
41
+ def test_boolean_attributes
42
+ assert ! Topic.find(1).approved?
43
+ assert Topic.find(2).approved?
44
+ end
45
+
46
+ def test_set_attributes
47
+ topic = Topic.find(1)
48
+ topic.attributes = { "title" => "Budget", "author_name" => "Jason" }
49
+ topic.save
50
+ assert_equal("Budget", topic.title)
51
+ assert_equal("Jason", topic.author_name)
52
+ assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address)
53
+ end
54
+
55
+ def test_set_attributes_without_hash
56
+ topic = Topic.new
57
+ assert_nothing_raised { topic.attributes = '' }
58
+ end
59
+
60
+ def test_integers_as_nil
61
+ test = AutoId.create('value' => '')
62
+ assert_nil AutoId.find(test.id).value
63
+ end
64
+
65
+ def test_set_attributes_with_block
66
+ topic = Topic.new do |t|
67
+ t.title = "Budget"
68
+ t.author_name = "Jason"
30
69
  end
70
+
71
+ assert_equal("Budget", topic.title)
72
+ assert_equal("Jason", topic.author_name)
31
73
  end
32
-
33
- def test_declared_attribute_method_affects_respond_to_and_method_missing
74
+
75
+ def test_respond_to?
76
+ topic = Topic.find(1)
77
+ assert_respond_to topic, "title"
78
+ assert_respond_to topic, "title?"
79
+ assert_respond_to topic, "title="
80
+ assert_respond_to topic, :title
81
+ assert_respond_to topic, :title?
82
+ assert_respond_to topic, :title=
83
+ assert_respond_to topic, "author_name"
84
+ assert_respond_to topic, "attribute_names"
85
+ assert !topic.respond_to?("nothingness")
86
+ assert !topic.respond_to?(:nothingness)
87
+ end
88
+
89
+ def test_array_content
90
+ topic = Topic.new
91
+ topic.content = %w( one two three )
92
+ topic.save
93
+
94
+ assert_equal(%w( one two three ), Topic.find(topic.id).content)
95
+ end
96
+
97
+ def test_read_attributes_before_type_cast
98
+ category = Category.new({:name=>"Test categoty", :type => nil})
99
+ category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil}
100
+ assert_equal category_attrs , category.attributes_before_type_cast
101
+ end
102
+
103
+ if current_adapter?(:MysqlAdapter)
104
+ def test_read_attributes_before_type_cast_on_boolean
105
+ bool = Boolean.create({ "value" => false })
106
+ assert_equal "0", bool.reload.attributes_before_type_cast["value"]
107
+ end
108
+ end
109
+
110
+ unless current_adapter?(:Mysql2Adapter)
111
+ def test_read_attributes_before_type_cast_on_datetime
112
+ developer = Developer.find(:first)
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)
118
+
119
+ developer.created_at = "345643456"
120
+ assert_equal developer.created_at_before_type_cast, "345643456"
121
+ assert_equal developer.created_at, nil
122
+
123
+ developer.created_at = "2010-03-21 21:23:32"
124
+ assert_equal developer.created_at_before_type_cast, "2010-03-21 21:23:32"
125
+ assert_equal developer.created_at, Time.parse("2010-03-21 21:23:32")
126
+ end
127
+ end
128
+ end
129
+
130
+ def test_hash_content
131
+ topic = Topic.new
132
+ topic.content = { "one" => 1, "two" => 2 }
133
+ topic.save
134
+
135
+ assert_equal 2, Topic.find(topic.id).content["two"]
136
+
137
+ topic.content_will_change!
138
+ topic.content["three"] = 3
139
+ topic.save
140
+
141
+ assert_equal 3, Topic.find(topic.id).content["three"]
142
+ end
143
+
144
+ def test_update_array_content
145
+ topic = Topic.new
146
+ topic.content = %w( one two three )
147
+
148
+ topic.content.push "four"
149
+ assert_equal(%w( one two three four ), topic.content)
150
+
151
+ topic.save
152
+
153
+ topic = Topic.find(topic.id)
154
+ topic.content << "five"
155
+ assert_equal(%w( one two three four five ), topic.content)
156
+ end
157
+
158
+ def test_case_sensitive_attributes_hash
159
+ # DB2 is not case-sensitive
160
+ return true if current_adapter?(:DB2Adapter)
161
+
162
+ assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.find(:first).attributes
163
+ end
164
+
165
+ def test_hashes_not_mangled
166
+ new_topic = { :title => "New Topic" }
167
+ new_topic_values = { :title => "AnotherTopic" }
168
+
169
+ topic = Topic.new(new_topic)
170
+ assert_equal new_topic[:title], topic.title
171
+
172
+ topic.attributes= new_topic_values
173
+ assert_equal new_topic_values[:title], topic.title
174
+ end
175
+
176
+ def test_create_through_factory
177
+ topic = Topic.create("title" => "New Topic")
178
+ topicReloaded = Topic.find(topic.id)
179
+ assert_equal(topic, topicReloaded)
180
+ end
181
+
182
+ def test_write_attribute
183
+ topic = Topic.new
184
+ topic.send(:write_attribute, :title, "Still another topic")
185
+ assert_equal "Still another topic", topic.title
186
+
187
+ topic.send(:write_attribute, "title", "Still another topic: part 2")
188
+ assert_equal "Still another topic: part 2", topic.title
189
+ end
190
+
191
+ def test_read_attribute
192
+ topic = Topic.new
193
+ topic.title = "Don't change the topic"
194
+ assert_equal "Don't change the topic", topic.send(:read_attribute, "title")
195
+ assert_equal "Don't change the topic", topic["title"]
196
+
197
+ assert_equal "Don't change the topic", topic.send(:read_attribute, :title)
198
+ assert_equal "Don't change the topic", topic[:title]
199
+ end
200
+
201
+ def test_read_attribute_when_false
202
+ topic = topics(:first)
203
+ topic.approved = false
204
+ assert !topic.approved?, "approved should be false"
205
+ topic.approved = "false"
206
+ assert !topic.approved?, "approved should be false"
207
+ end
208
+
209
+ def test_read_attribute_when_true
210
+ topic = topics(:first)
211
+ topic.approved = true
212
+ assert topic.approved?, "approved should be true"
213
+ topic.approved = "true"
214
+ assert topic.approved?, "approved should be true"
215
+ end
216
+
217
+ def test_read_write_boolean_attribute
218
+ topic = Topic.new
219
+ # puts ""
220
+ # puts "New Topic"
221
+ # puts topic.inspect
222
+ topic.approved = "false"
223
+ # puts "Expecting false"
224
+ # puts topic.inspect
225
+ assert !topic.approved?, "approved should be false"
226
+ topic.approved = "false"
227
+ # puts "Expecting false"
228
+ # puts topic.inspect
229
+ assert !topic.approved?, "approved should be false"
230
+ topic.approved = "true"
231
+ # puts "Expecting true"
232
+ # puts topic.inspect
233
+ assert topic.approved?, "approved should be true"
234
+ topic.approved = "true"
235
+ # puts "Expecting true"
236
+ # puts topic.inspect
237
+ assert topic.approved?, "approved should be true"
238
+ # puts ""
239
+ end
240
+
241
+ def test_query_attribute_string
242
+ [nil, "", " "].each do |value|
243
+ assert_equal false, Topic.new(:author_name => value).author_name?
244
+ end
245
+
246
+ assert_equal true, Topic.new(:author_name => "Name").author_name?
247
+ end
248
+
249
+ def test_query_attribute_number
250
+ [nil, 0, "0"].each do |value|
251
+ assert_equal false, Developer.new(:salary => value).salary?
252
+ end
253
+
254
+ assert_equal true, Developer.new(:salary => 1).salary?
255
+ assert_equal true, Developer.new(:salary => "1").salary?
256
+ end
257
+
258
+ def test_query_attribute_boolean
259
+ [nil, "", false, "false", "f", 0].each do |value|
260
+ assert_equal false, Topic.new(:approved => value).approved?
261
+ end
262
+
263
+ [true, "true", "1", 1].each do |value|
264
+ assert_equal true, Topic.new(:approved => value).approved?
265
+ end
266
+ end
267
+
268
+ def test_query_attribute_with_custom_fields
269
+ object = Company.find_by_sql(<<-SQL).first
270
+ SELECT c1.*, c2.ruby_type as string_value, c2.rating as int_value
271
+ FROM companies c1, companies c2
272
+ WHERE c1.firm_id = c2.id
273
+ AND c1.id = 2
274
+ SQL
275
+
276
+ assert_equal "Firm", object.string_value
277
+ assert object.string_value?
278
+
279
+ object.string_value = " "
280
+ assert !object.string_value?
281
+
282
+ assert_equal 1, object.int_value.to_i
283
+ assert object.int_value?
284
+
285
+ object.int_value = "0"
286
+ assert !object.int_value?
287
+ end
288
+
289
+ def test_non_attribute_access_and_assignment
290
+ topic = Topic.new
291
+ assert !topic.respond_to?("mumbo")
292
+ assert_raise(NoMethodError) { topic.mumbo }
293
+ assert_raise(NoMethodError) { topic.mumbo = 5 }
294
+ end
295
+
296
+ def test_undeclared_attribute_method_does_not_affect_respond_to_and_method_missing
34
297
  topic = @target.new(:title => 'Budget')
35
298
  assert topic.respond_to?('title')
36
299
  assert_equal 'Budget', topic.title
37
300
  assert !topic.respond_to?('title_hello_world')
38
301
  assert_raise(NoMethodError) { topic.title_hello_world }
39
-
40
- %w(_hello_world _it! _candidate= able?).each do |suffix|
302
+ end
303
+
304
+ def test_declared_prefixed_attribute_method_affects_respond_to_and_method_missing
305
+ topic = @target.new(:title => 'Budget')
306
+ %w(default_ title_).each do |prefix|
307
+ @target.class_eval "def #{prefix}attribute(*args) args end"
308
+ @target.attribute_method_prefix prefix
309
+
310
+ meth = "#{prefix}title"
311
+ assert topic.respond_to?(meth)
312
+ assert_equal ['title'], topic.send(meth)
313
+ assert_equal ['title', 'a'], topic.send(meth, 'a')
314
+ assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3)
315
+ end
316
+ end
317
+
318
+ def test_declared_suffixed_attribute_method_affects_respond_to_and_method_missing
319
+ topic = @target.new(:title => 'Budget')
320
+ %w(_default _title_default _it! _candidate= able?).each do |suffix|
41
321
  @target.class_eval "def attribute#{suffix}(*args) args end"
42
322
  @target.attribute_method_suffix suffix
43
-
323
+
44
324
  meth = "title#{suffix}"
45
325
  assert topic.respond_to?(meth)
46
326
  assert_equal ['title'], topic.send(meth)
@@ -48,43 +328,56 @@ class AttributeMethodsTest < ActiveRecord::TestCase
48
328
  assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3)
49
329
  end
50
330
  end
51
-
331
+
332
+ def test_declared_affixed_attribute_method_affects_respond_to_and_method_missing
333
+ topic = @target.new(:title => 'Budget')
334
+ [['mark_', '_for_update'], ['reset_', '!'], ['default_', '_value?']].each do |prefix, suffix|
335
+ @target.class_eval "def #{prefix}attribute#{suffix}(*args) args end"
336
+ @target.attribute_method_affix({ :prefix => prefix, :suffix => suffix })
337
+
338
+ meth = "#{prefix}title#{suffix}"
339
+ assert topic.respond_to?(meth)
340
+ assert_equal ['title'], topic.send(meth)
341
+ assert_equal ['title', 'a'], topic.send(meth, 'a')
342
+ assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3)
343
+ end
344
+ end
345
+
52
346
  def test_should_unserialize_attributes_for_frozen_records
53
347
  myobj = {:value1 => :value2}
54
348
  topic = Topic.create("content" => myobj)
55
349
  topic.freeze
56
350
  assert_equal myobj, topic.content
57
351
  end
58
-
352
+
59
353
  def test_typecast_attribute_from_select_to_false
60
354
  topic = Topic.create(:title => 'Budget')
61
- unless current_adapter?(:IBM_DBAdapter)
62
- topic = Topic.find(:first, :select => "topics.*, 1=2 as is_test")
63
- assert !topic.is_test?
355
+ # Oracle does not support boolean expressions in SELECT
356
+ if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
357
+ topic = Topic.find(:first, :select => "topics.*, 0 as is_test")
64
358
  else
65
- topic = Topic.find(:first, :select => "topics.approved as is_test")
66
- assert topic.is_test?
359
+ topic = Topic.find(:first, :select => "topics.*, 1=2 as is_test")
67
360
  end
361
+ assert !topic.is_test?
68
362
  end
69
-
70
- unless current_adapter?(:IBM_DBAdapter)
71
- def test_typecast_attribute_from_select_to_true
72
- topic = Topic.create(:title => 'Budget')
363
+
364
+ def test_typecast_attribute_from_select_to_true
365
+ topic = Topic.create(:title => 'Budget')
366
+ # Oracle does not support boolean expressions in SELECT
367
+ if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
368
+ topic = Topic.find(:first, :select => "topics.*, 1 as is_test")
369
+ else
73
370
  topic = Topic.find(:first, :select => "topics.*, 2=2 as is_test")
74
- assert topic.is_test?
75
371
  end
372
+ assert topic.is_test?
76
373
  end
77
-
374
+
78
375
  def test_kernel_methods_not_implemented_in_activerecord
79
376
  %w(test name display y).each do |method|
80
377
  assert !ActiveRecord::Base.instance_method_already_implemented?(method), "##{method} is defined"
81
378
  end
82
379
  end
83
-
84
- def test_primary_key_implemented
85
- assert Class.new(ActiveRecord::Base).instance_method_already_implemented?('id')
86
- end
87
-
380
+
88
381
  def test_defined_kernel_methods_implemented_in_model
89
382
  %w(test name display y).each do |method|
90
383
  klass = Class.new ActiveRecord::Base
@@ -92,7 +385,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
92
385
  assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
93
386
  end
94
387
  end
95
-
388
+
96
389
  def test_defined_kernel_methods_implemented_in_model_abstract_subclass
97
390
  %w(test name display y).each do |method|
98
391
  abstract = Class.new ActiveRecord::Base
@@ -102,7 +395,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
102
395
  assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
103
396
  end
104
397
  end
105
-
398
+
106
399
  def test_raises_dangerous_attribute_error_when_defining_activerecord_method_in_model
107
400
  %w(save create_or_update).each do |method|
108
401
  klass = Class.new ActiveRecord::Base
@@ -112,12 +405,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase
112
405
  end
113
406
  end
114
407
  end
115
-
408
+
116
409
  def test_only_time_related_columns_are_meant_to_be_cached_by_default
117
410
  expected = %w(datetime timestamp time date).sort
118
411
  assert_equal expected, ActiveRecord::Base.attribute_types_cached_by_default.map(&:to_s).sort
119
412
  end
120
-
413
+
121
414
  def test_declaring_attributes_as_cached_adds_them_to_the_attributes_cached_by_default
122
415
  default_attributes = Topic.cached_attributes
123
416
  Topic.cache_attributes :replies_count
@@ -125,26 +418,26 @@ class AttributeMethodsTest < ActiveRecord::TestCase
125
418
  assert_equal expected.sort, Topic.cached_attributes.sort
126
419
  Topic.instance_variable_set "@cached_attributes", nil
127
420
  end
128
-
421
+
129
422
  def test_time_related_columns_are_actually_cached
130
423
  column_types = %w(datetime timestamp time date).map(&:to_sym)
131
424
  column_names = Topic.columns.select{|c| column_types.include?(c.type) }.map(&:name)
132
-
425
+
133
426
  assert_equal column_names.sort, Topic.cached_attributes.sort
134
427
  assert_equal time_related_columns_on_topic.sort, Topic.cached_attributes.sort
135
428
  end
136
-
429
+
137
430
  def test_accessing_cached_attributes_caches_the_converted_values_and_nothing_else
138
431
  t = topics(:first)
139
432
  cache = t.instance_variable_get "@attributes_cache"
140
-
433
+
141
434
  assert_not_nil cache
142
435
  assert cache.empty?
143
-
436
+
144
437
  all_columns = Topic.columns.map(&:name)
145
438
  cached_columns = time_related_columns_on_topic
146
439
  uncached_columns = all_columns - cached_columns
147
-
440
+
148
441
  all_columns.each do |attr_name|
149
442
  attribute_gets_cached = Topic.cache_attribute?(attr_name)
150
443
  val = t.send attr_name unless attr_name == "type"
@@ -157,7 +450,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
157
450
  end
158
451
  end
159
452
  end
160
-
453
+
161
454
  def test_time_attributes_are_retrieved_in_current_time_zone
162
455
  in_time_zone "Pacific Time (US & Canada)" do
163
456
  utc_time = Time.utc(2008, 1, 1)
@@ -169,7 +462,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
169
462
  assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time # and represents time values adjusted accordingly
170
463
  end
171
464
  end
172
-
465
+
173
466
  def test_setting_time_zone_aware_attribute_to_utc
174
467
  in_time_zone "Pacific Time (US & Canada)" do
175
468
  utc_time = Time.utc(2008, 1, 1)
@@ -180,7 +473,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
180
473
  assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
181
474
  end
182
475
  end
183
-
476
+
184
477
  def test_setting_time_zone_aware_attribute_in_other_time_zone
185
478
  utc_time = Time.utc(2008, 1, 1)
186
479
  cst_time = utc_time.in_time_zone("Central Time (US & Canada)")
@@ -192,10 +485,10 @@ class AttributeMethodsTest < ActiveRecord::TestCase
192
485
  assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
193
486
  end
194
487
  end
195
-
488
+
196
489
  def test_setting_time_zone_aware_attribute_with_string
197
490
  utc_time = Time.utc(2008, 1, 1)
198
- (-11..13).each do |timezone_offset|
491
+ (-11..13).each do |timezone_offset|
199
492
  time_string = utc_time.in_time_zone(timezone_offset).to_s
200
493
  in_time_zone "Pacific Time (US & Canada)" do
201
494
  record = @target.new
@@ -206,7 +499,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
206
499
  end
207
500
  end
208
501
  end
209
-
502
+
210
503
  def test_setting_time_zone_aware_attribute_to_blank_string_returns_nil
211
504
  in_time_zone "Pacific Time (US & Canada)" do
212
505
  record = @target.new
@@ -214,10 +507,10 @@ class AttributeMethodsTest < ActiveRecord::TestCase
214
507
  assert_nil record.written_on
215
508
  end
216
509
  end
217
-
510
+
218
511
  def test_setting_time_zone_aware_attribute_interprets_time_zone_unaware_string_in_time_zone
219
512
  time_string = 'Tue Jan 01 00:00:00 2008'
220
- (-11..13).each do |timezone_offset|
513
+ (-11..13).each do |timezone_offset|
221
514
  in_time_zone timezone_offset do
222
515
  record = @target.new
223
516
  record.written_on = time_string
@@ -227,7 +520,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
227
520
  end
228
521
  end
229
522
  end
230
-
523
+
231
524
  def test_setting_time_zone_aware_attribute_in_current_time_zone
232
525
  utc_time = Time.utc(2008, 1, 1)
233
526
  in_time_zone "Pacific Time (US & Canada)" do
@@ -238,61 +531,77 @@ class AttributeMethodsTest < ActiveRecord::TestCase
238
531
  assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
239
532
  end
240
533
  end
241
-
534
+
242
535
  def test_setting_time_zone_conversion_for_attributes_should_write_value_on_class_variable
243
536
  Topic.skip_time_zone_conversion_for_attributes = [:field_a]
244
537
  Minimalistic.skip_time_zone_conversion_for_attributes = [:field_b]
245
-
246
- assert_equal [:field_a], Topic.skip_time_zone_conversion_for_attributes
247
- assert_equal [:field_b], Minimalistic.skip_time_zone_conversion_for_attributes
538
+
539
+ assert_equal [:field_a], Topic.skip_time_zone_conversion_for_attributes
540
+ assert_equal [:field_b], Minimalistic.skip_time_zone_conversion_for_attributes
248
541
  end
249
-
542
+
250
543
  def test_read_attributes_respect_access_control
251
544
  privatize("title")
252
-
545
+
253
546
  topic = @target.new(:title => "The pros and cons of programming naked.")
254
547
  assert !topic.respond_to?(:title)
255
548
  exception = assert_raise(NoMethodError) { topic.title }
256
549
  assert_equal "Attempt to call private method", exception.message
257
550
  assert_equal "I'm private", topic.send(:title)
258
551
  end
259
-
552
+
260
553
  def test_write_attributes_respect_access_control
261
554
  privatize("title=(value)")
262
-
555
+
263
556
  topic = @target.new
264
557
  assert !topic.respond_to?(:title=)
265
558
  exception = assert_raise(NoMethodError) { topic.title = "Pants"}
266
559
  assert_equal "Attempt to call private method", exception.message
267
560
  topic.send(:title=, "Very large pants")
268
561
  end
269
-
562
+
270
563
  def test_question_attributes_respect_access_control
271
564
  privatize("title?")
272
-
565
+
273
566
  topic = @target.new(:title => "Isaac Newton's pants")
274
567
  assert !topic.respond_to?(:title?)
275
568
  exception = assert_raise(NoMethodError) { topic.title? }
276
569
  assert_equal "Attempt to call private method", exception.message
277
570
  assert topic.send(:title?)
278
571
  end
279
-
572
+
280
573
  def test_bulk_update_respects_access_control
281
574
  privatize("title=(value)")
282
-
575
+
283
576
  assert_raise(ActiveRecord::UnknownAttributeError) { topic = @target.new(:title => "Rants about pants") }
284
577
  assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } }
285
578
  end
286
-
579
+
580
+ def test_read_attribute_overwrites_private_method_not_considered_implemented
581
+ # simulate a model with a db column that shares its name an inherited
582
+ # private method (e.g. Object#system)
583
+ #
584
+ Object.class_eval do
585
+ private
586
+ def title; "private!"; end
587
+ end
588
+ assert !@target.instance_method_already_implemented?(:title)
589
+ topic = @target.new
590
+ assert_nil topic.title
591
+
592
+ Object.send(:undef_method, :title) # remove test method from object
593
+ end
594
+
595
+
287
596
  private
288
597
  def time_related_columns_on_topic
289
598
  Topic.columns.select{|c| [:time, :date, :datetime, :timestamp].include?(c.type)}.map(&:name)
290
599
  end
291
-
600
+
292
601
  def in_time_zone(zone)
293
602
  old_zone = Time.zone
294
603
  old_tz = ActiveRecord::Base.time_zone_aware_attributes
295
-
604
+
296
605
  Time.zone = zone ? ActiveSupport::TimeZone[zone] : nil
297
606
  ActiveRecord::Base.time_zone_aware_attributes = !zone.nil?
298
607
  yield
@@ -300,7 +609,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
300
609
  Time.zone = old_zone
301
610
  ActiveRecord::Base.time_zone_aware_attributes = old_tz
302
611
  end
303
-
612
+
304
613
  def privatize(method_signature)
305
614
  @target.class_eval <<-private_method
306
615
  private