~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activerecord/test/cases/dirty_test.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require 'cases/helper'
2
 
require 'models/topic'    # For booleans
3
 
require 'models/pirate'   # For timestamps
4
 
require 'models/parrot'
5
 
require 'models/person'   # For optimistic locking
6
 
 
7
 
class Pirate # Just reopening it, not defining it
8
 
  attr_accessor :detected_changes_in_after_update # Boolean for if changes are detected
9
 
  attr_accessor :changes_detected_in_after_update # Actual changes
10
 
 
11
 
  after_update :check_changes
12
 
 
13
 
private
14
 
  # after_save/update in sweepers, observers, and the model itself
15
 
  # can end up checking dirty status and acting on the results
16
 
  def check_changes
17
 
    if self.changed?
18
 
      self.detected_changes_in_after_update = true
19
 
      self.changes_detected_in_after_update = self.changes
20
 
    end
21
 
  end
22
 
end
23
 
 
24
 
class NumericData < ActiveRecord::Base
25
 
  self.table_name = 'numeric_data'
26
 
end
27
 
 
28
 
class DirtyTest < ActiveRecord::TestCase
29
 
  def test_attribute_changes
30
 
    # New record - no changes.
31
 
    pirate = Pirate.new
32
 
    assert !pirate.catchphrase_changed?
33
 
    assert_nil pirate.catchphrase_change
34
 
 
35
 
    # Change catchphrase.
36
 
    pirate.catchphrase = 'arrr'
37
 
    assert pirate.catchphrase_changed?
38
 
    assert_nil pirate.catchphrase_was
39
 
    assert_equal [nil, 'arrr'], pirate.catchphrase_change
40
 
 
41
 
    # Saved - no changes.
42
 
    pirate.save!
43
 
    assert !pirate.catchphrase_changed?
44
 
    assert_nil pirate.catchphrase_change
45
 
 
46
 
    # Same value - no changes.
47
 
    pirate.catchphrase = 'arrr'
48
 
    assert !pirate.catchphrase_changed?
49
 
    assert_nil pirate.catchphrase_change
50
 
  end
51
 
 
52
 
  def test_aliased_attribute_changes
53
 
    # the actual attribute here is name, title is an
54
 
    # alias setup via alias_attribute
55
 
    parrot = Parrot.new
56
 
    assert !parrot.title_changed?
57
 
    assert_nil parrot.title_change
58
 
 
59
 
    parrot.name = 'Sam'
60
 
    assert parrot.title_changed?
61
 
    assert_nil parrot.title_was
62
 
    assert_equal parrot.name_change, parrot.title_change
63
 
  end
64
 
 
65
 
  def test_nullable_number_not_marked_as_changed_if_new_value_is_blank
66
 
    pirate = Pirate.new
67
 
 
68
 
    ["", nil].each do |value|
69
 
      pirate.parrot_id = value
70
 
      assert !pirate.parrot_id_changed?
71
 
      assert_nil pirate.parrot_id_change
72
 
    end
73
 
  end
74
 
 
75
 
  def test_nullable_decimal_not_marked_as_changed_if_new_value_is_blank
76
 
    numeric_data = NumericData.new
77
 
 
78
 
    ["", nil].each do |value|
79
 
      numeric_data.bank_balance = value
80
 
      assert !numeric_data.bank_balance_changed?
81
 
      assert_nil numeric_data.bank_balance_change
82
 
    end
83
 
  end
84
 
 
85
 
  def test_nullable_float_not_marked_as_changed_if_new_value_is_blank
86
 
    numeric_data = NumericData.new
87
 
 
88
 
    ["", nil].each do |value|
89
 
      numeric_data.temperature = value
90
 
      assert !numeric_data.temperature_changed?
91
 
      assert_nil numeric_data.temperature_change
92
 
    end
93
 
  end
94
 
 
95
 
  def test_nullable_integer_zero_to_string_zero_not_marked_as_changed
96
 
    pirate = Pirate.new
97
 
    pirate.parrot_id = 0
98
 
    pirate.catchphrase = 'arrr'
99
 
    assert pirate.save!
100
 
 
101
 
    assert !pirate.changed?
102
 
 
103
 
    pirate.parrot_id = '0'
104
 
    assert !pirate.changed?
105
 
  end
106
 
 
107
 
  def test_zero_to_blank_marked_as_changed
108
 
    pirate = Pirate.new
109
 
    pirate.catchphrase = "Yarrrr, me hearties"
110
 
    pirate.parrot_id = 1
111
 
    pirate.save
112
 
 
113
 
    # check the change from 1 to ''
114
 
    pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
115
 
    pirate.parrot_id = ''
116
 
    assert pirate.parrot_id_changed?
117
 
    assert_equal([1, nil], pirate.parrot_id_change)
118
 
    pirate.save
119
 
 
120
 
    # check the change from nil to 0
121
 
    pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
122
 
    pirate.parrot_id = 0
123
 
    assert pirate.parrot_id_changed?
124
 
    assert_equal([nil, 0], pirate.parrot_id_change)
125
 
    pirate.save
126
 
 
127
 
    # check the change from 0 to ''
128
 
    pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
129
 
    pirate.parrot_id = ''
130
 
    assert pirate.parrot_id_changed?
131
 
    assert_equal([0, nil], pirate.parrot_id_change)
132
 
  end
133
 
 
134
 
  def test_object_should_be_changed_if_any_attribute_is_changed
135
 
    pirate = Pirate.new
136
 
    assert !pirate.changed?
137
 
    assert_equal [], pirate.changed
138
 
    assert_equal Hash.new, pirate.changes
139
 
 
140
 
    pirate.catchphrase = 'arrr'
141
 
    assert pirate.changed?
142
 
    assert_nil pirate.catchphrase_was
143
 
    assert_equal %w(catchphrase), pirate.changed
144
 
    assert_equal({'catchphrase' => [nil, 'arrr']}, pirate.changes)
145
 
 
146
 
    pirate.save
147
 
    assert !pirate.changed?
148
 
    assert_equal [], pirate.changed
149
 
    assert_equal Hash.new, pirate.changes
150
 
  end
151
 
 
152
 
  def test_attribute_will_change!
153
 
    pirate = Pirate.create!(:catchphrase => 'arr')
154
 
 
155
 
    pirate.catchphrase << ' matey'
156
 
    assert !pirate.catchphrase_changed?
157
 
 
158
 
    assert pirate.catchphrase_will_change!
159
 
    assert pirate.catchphrase_changed?
160
 
    assert_equal ['arr matey', 'arr matey'], pirate.catchphrase_change
161
 
 
162
 
    pirate.catchphrase << '!'
163
 
    assert pirate.catchphrase_changed?
164
 
    assert_equal ['arr matey', 'arr matey!'], pirate.catchphrase_change
165
 
  end
166
 
 
167
 
  def test_association_assignment_changes_foreign_key
168
 
    pirate = Pirate.create!(:catchphrase => 'jarl')
169
 
    pirate.parrot = Parrot.create!(:name => 'Lorre')
170
 
    assert pirate.changed?
171
 
    assert_equal %w(parrot_id), pirate.changed
172
 
  end
173
 
 
174
 
  def test_attribute_should_be_compared_with_type_cast
175
 
    topic = Topic.new
176
 
    assert topic.approved?
177
 
    assert !topic.approved_changed?
178
 
 
179
 
    # Coming from web form.
180
 
    params = {:topic => {:approved => 1}}
181
 
    # In the controller.
182
 
    topic.attributes = params[:topic]
183
 
    assert topic.approved?
184
 
    assert !topic.approved_changed?
185
 
  end
186
 
 
187
 
  def test_partial_update
188
 
    pirate = Pirate.new(:catchphrase => 'foo')
189
 
    old_updated_on = 1.hour.ago.beginning_of_day
190
 
 
191
 
    with_partial_updates Pirate, false do
192
 
      assert_queries(2) { 2.times { pirate.save! } }
193
 
      Pirate.update_all({ :updated_on => old_updated_on }, :id => pirate.id)
194
 
    end
195
 
 
196
 
    with_partial_updates Pirate, true do
197
 
      assert_queries(0) { 2.times { pirate.save! } }
198
 
      assert_equal old_updated_on, pirate.reload.updated_on
199
 
 
200
 
      assert_queries(1) { pirate.catchphrase = 'bar'; pirate.save! }
201
 
      assert_not_equal old_updated_on, pirate.reload.updated_on
202
 
    end
203
 
  end
204
 
 
205
 
  def test_partial_update_with_optimistic_locking
206
 
    person = Person.new(:first_name => 'foo')
207
 
    old_lock_version = 1
208
 
 
209
 
    with_partial_updates Person, false do
210
 
      assert_queries(2) { 2.times { person.save! } }
211
 
      Person.update_all({ :first_name => 'baz' }, :id => person.id)
212
 
    end
213
 
 
214
 
    with_partial_updates Person, true do
215
 
      assert_queries(0) { 2.times { person.save! } }
216
 
      assert_equal old_lock_version, person.reload.lock_version
217
 
 
218
 
      assert_queries(1) { person.first_name = 'bar'; person.save! }
219
 
      assert_not_equal old_lock_version, person.reload.lock_version
220
 
    end
221
 
  end
222
 
 
223
 
  def test_changed_attributes_should_be_preserved_if_save_failure
224
 
    pirate = Pirate.new
225
 
    pirate.parrot_id = 1
226
 
    assert !pirate.save
227
 
    check_pirate_after_save_failure(pirate)
228
 
 
229
 
    pirate = Pirate.new
230
 
    pirate.parrot_id = 1
231
 
    assert_raise(ActiveRecord::RecordInvalid) { pirate.save! }
232
 
    check_pirate_after_save_failure(pirate)
233
 
  end
234
 
 
235
 
  def test_reload_should_clear_changed_attributes
236
 
    pirate = Pirate.create!(:catchphrase => "shiver me timbers")
237
 
    pirate.catchphrase = "*hic*"
238
 
    assert pirate.changed?
239
 
    pirate.reload
240
 
    assert !pirate.changed?
241
 
  end
242
 
 
243
 
  def test_reverted_changes_are_not_dirty
244
 
    phrase = "shiver me timbers"
245
 
    pirate = Pirate.create!(:catchphrase => phrase)
246
 
    pirate.catchphrase = "*hic*"
247
 
    assert pirate.changed?
248
 
    pirate.catchphrase = phrase
249
 
    assert !pirate.changed?
250
 
  end
251
 
 
252
 
  def test_reverted_changes_are_not_dirty_after_multiple_changes
253
 
    phrase = "shiver me timbers"
254
 
    pirate = Pirate.create!(:catchphrase => phrase)
255
 
    10.times do |i|
256
 
      pirate.catchphrase = "*hic*" * i
257
 
      assert pirate.changed?
258
 
    end
259
 
    assert pirate.changed?
260
 
    pirate.catchphrase = phrase
261
 
    assert !pirate.changed?
262
 
  end
263
 
 
264
 
 
265
 
  def test_reverted_changes_are_not_dirty_going_from_nil_to_value_and_back
266
 
    pirate = Pirate.create!(:catchphrase => "Yar!")
267
 
 
268
 
    pirate.parrot_id = 1
269
 
    assert pirate.changed?
270
 
    assert pirate.parrot_id_changed?
271
 
    assert !pirate.catchphrase_changed?
272
 
 
273
 
    pirate.parrot_id = nil
274
 
    assert !pirate.changed?
275
 
    assert !pirate.parrot_id_changed?
276
 
    assert !pirate.catchphrase_changed?
277
 
  end
278
 
 
279
 
  def test_save_should_store_serialized_attributes_even_with_partial_updates
280
 
    with_partial_updates(Topic) do
281
 
      topic = Topic.create!(:content => {:a => "a"})
282
 
      topic.content[:b] = "b"
283
 
      #assert topic.changed? # Known bug, will fail
284
 
      topic.save!
285
 
      assert_equal "b", topic.content[:b]
286
 
      topic.reload
287
 
      assert_equal "b", topic.content[:b]
288
 
    end
289
 
  end
290
 
 
291
 
  def test_save_should_not_save_serialized_attribute_with_partial_updates_if_not_present
292
 
    with_partial_updates(Topic) do
293
 
      Topic.create!(:author_name => 'Bill', :content => {:a => "a"})
294
 
      topic = Topic.first(:select => 'id, author_name')
295
 
      topic.update_attribute :author_name, 'John'
296
 
      topic = Topic.first
297
 
      assert_not_nil topic.content
298
 
    end
299
 
  end
300
 
 
301
 
  private
302
 
    def with_partial_updates(klass, on = true)
303
 
      old = klass.partial_updates?
304
 
      klass.partial_updates = on
305
 
      yield
306
 
    ensure
307
 
      klass.partial_updates = old
308
 
    end
309
 
 
310
 
    def check_pirate_after_save_failure(pirate)
311
 
      assert pirate.changed?
312
 
      assert pirate.parrot_id_changed?
313
 
      assert_equal %w(parrot_id), pirate.changed
314
 
      assert_nil pirate.parrot_id_was
315
 
    end
316
 
end