mr 0.35.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/bench/all.rb +4 -0
  7. data/bench/factory.rb +68 -0
  8. data/bench/fake_record.rb +174 -0
  9. data/bench/model.rb +201 -0
  10. data/bench/read_model.rb +191 -0
  11. data/bench/results/factory.txt +21 -0
  12. data/bench/results/fake_record.txt +37 -0
  13. data/bench/results/model.txt +44 -0
  14. data/bench/results/read_model.txt +46 -0
  15. data/bench/setup.rb +132 -0
  16. data/lib/mr.rb +11 -0
  17. data/lib/mr/after_commit.rb +49 -0
  18. data/lib/mr/after_commit/fake_record.rb +39 -0
  19. data/lib/mr/after_commit/record.rb +48 -0
  20. data/lib/mr/after_commit/record_procs_methods.rb +82 -0
  21. data/lib/mr/factory.rb +82 -0
  22. data/lib/mr/factory/config.rb +240 -0
  23. data/lib/mr/factory/model_factory.rb +103 -0
  24. data/lib/mr/factory/model_stack.rb +28 -0
  25. data/lib/mr/factory/read_model_factory.rb +104 -0
  26. data/lib/mr/factory/record_factory.rb +130 -0
  27. data/lib/mr/factory/record_stack.rb +219 -0
  28. data/lib/mr/fake_query.rb +53 -0
  29. data/lib/mr/fake_record.rb +58 -0
  30. data/lib/mr/fake_record/associations.rb +257 -0
  31. data/lib/mr/fake_record/attributes.rb +168 -0
  32. data/lib/mr/fake_record/persistence.rb +116 -0
  33. data/lib/mr/json_field.rb +180 -0
  34. data/lib/mr/json_field/fake_record.rb +31 -0
  35. data/lib/mr/json_field/record.rb +38 -0
  36. data/lib/mr/model.rb +67 -0
  37. data/lib/mr/model/associations.rb +161 -0
  38. data/lib/mr/model/configuration.rb +67 -0
  39. data/lib/mr/model/fields.rb +177 -0
  40. data/lib/mr/model/persistence.rb +79 -0
  41. data/lib/mr/query.rb +126 -0
  42. data/lib/mr/read_model.rb +83 -0
  43. data/lib/mr/read_model/data.rb +38 -0
  44. data/lib/mr/read_model/fields.rb +218 -0
  45. data/lib/mr/read_model/query_expression.rb +188 -0
  46. data/lib/mr/read_model/querying.rb +214 -0
  47. data/lib/mr/read_model/set_querying.rb +82 -0
  48. data/lib/mr/read_model/subquery.rb +98 -0
  49. data/lib/mr/record.rb +35 -0
  50. data/lib/mr/test_helpers.rb +229 -0
  51. data/lib/mr/type_converter.rb +85 -0
  52. data/lib/mr/version.rb +3 -0
  53. data/log/.gitkeep +0 -0
  54. data/mr.gemspec +29 -0
  55. data/test/helper.rb +21 -0
  56. data/test/support/db.rb +10 -0
  57. data/test/support/factory.rb +13 -0
  58. data/test/support/factory/area.rb +6 -0
  59. data/test/support/factory/comment.rb +14 -0
  60. data/test/support/factory/image.rb +6 -0
  61. data/test/support/factory/user.rb +6 -0
  62. data/test/support/models/area.rb +58 -0
  63. data/test/support/models/comment.rb +60 -0
  64. data/test/support/models/image.rb +53 -0
  65. data/test/support/models/user.rb +96 -0
  66. data/test/support/read_model/querying.rb +150 -0
  67. data/test/support/read_models/comment_with_user_data.rb +27 -0
  68. data/test/support/read_models/set_data.rb +49 -0
  69. data/test/support/read_models/subquery_data.rb +41 -0
  70. data/test/support/read_models/user_with_area_data.rb +15 -0
  71. data/test/support/schema.rb +39 -0
  72. data/test/support/setup_test_db.rb +10 -0
  73. data/test/system/factory/model_factory_tests.rb +87 -0
  74. data/test/system/factory/model_stack_tests.rb +30 -0
  75. data/test/system/factory/record_factory_tests.rb +84 -0
  76. data/test/system/factory/record_stack_tests.rb +51 -0
  77. data/test/system/factory_tests.rb +32 -0
  78. data/test/system/read_model_tests.rb +199 -0
  79. data/test/system/with_model_tests.rb +275 -0
  80. data/test/unit/after_commit/fake_record_tests.rb +110 -0
  81. data/test/unit/after_commit/record_procs_methods_tests.rb +177 -0
  82. data/test/unit/after_commit/record_tests.rb +134 -0
  83. data/test/unit/after_commit_tests.rb +113 -0
  84. data/test/unit/factory/config_tests.rb +651 -0
  85. data/test/unit/factory/model_factory_tests.rb +473 -0
  86. data/test/unit/factory/model_stack_tests.rb +97 -0
  87. data/test/unit/factory/read_model_factory_tests.rb +195 -0
  88. data/test/unit/factory/record_factory_tests.rb +446 -0
  89. data/test/unit/factory/record_stack_tests.rb +549 -0
  90. data/test/unit/factory_tests.rb +213 -0
  91. data/test/unit/fake_query_tests.rb +137 -0
  92. data/test/unit/fake_record/associations_tests.rb +585 -0
  93. data/test/unit/fake_record/attributes_tests.rb +265 -0
  94. data/test/unit/fake_record/persistence_tests.rb +239 -0
  95. data/test/unit/fake_record_tests.rb +106 -0
  96. data/test/unit/json_field/fake_record_tests.rb +75 -0
  97. data/test/unit/json_field/record_tests.rb +80 -0
  98. data/test/unit/json_field_tests.rb +302 -0
  99. data/test/unit/model/associations_tests.rb +346 -0
  100. data/test/unit/model/configuration_tests.rb +92 -0
  101. data/test/unit/model/fields_tests.rb +278 -0
  102. data/test/unit/model/persistence_tests.rb +114 -0
  103. data/test/unit/model_tests.rb +137 -0
  104. data/test/unit/query_tests.rb +300 -0
  105. data/test/unit/read_model/data_tests.rb +56 -0
  106. data/test/unit/read_model/fields_tests.rb +416 -0
  107. data/test/unit/read_model/query_expression_tests.rb +381 -0
  108. data/test/unit/read_model/querying_tests.rb +613 -0
  109. data/test/unit/read_model/set_querying_tests.rb +149 -0
  110. data/test/unit/read_model/subquery_tests.rb +242 -0
  111. data/test/unit/read_model_tests.rb +187 -0
  112. data/test/unit/record_tests.rb +45 -0
  113. data/test/unit/test_helpers_tests.rb +431 -0
  114. data/test/unit/type_converter_tests.rb +207 -0
  115. metadata +285 -0
@@ -0,0 +1,265 @@
1
+ require 'assert'
2
+ require 'mr/fake_record/attributes'
3
+
4
+ require 'much-plugin'
5
+
6
+ module MR::FakeRecord::Attributes
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "MR::FakeRecord::Attributes"
10
+ setup do
11
+ @fake_record_class = Class.new do
12
+ include MR::FakeRecord::Attributes
13
+ end
14
+ end
15
+ subject{ @fake_record_class }
16
+
17
+ should have_imeths :attributes, :attribute, :columns
18
+
19
+ should "use much-plugin" do
20
+ assert_includes MuchPlugin, MR::FakeRecord::Attributes
21
+ end
22
+
23
+ should "return an instance of a AttributeSet using `attributes`" do
24
+ attributes = subject.attributes
25
+ assert_instance_of MR::FakeRecord::AttributeSet, attributes
26
+ assert_same attributes, subject.attributes
27
+ end
28
+
29
+ should "add attribute methods with `attribute`" do
30
+ subject.attribute :name, :string, :null => false
31
+ fake_record = subject.new
32
+
33
+ assert_respond_to :name, fake_record
34
+ assert_respond_to :name=, fake_record
35
+ assert_respond_to :name_was, fake_record
36
+ assert_respond_to :name_changed?, fake_record
37
+ fake_record.name = 'test'
38
+ assert_equal 'test', fake_record.name
39
+ attribute = subject.attributes.find(:name)
40
+ assert_equal false, attribute.null
41
+ end
42
+
43
+ should "return an array of fake record attributes with `columns`" do
44
+ subject.attribute :name, :string
45
+ subject.attribute :active, :boolean
46
+ columns = subject.columns
47
+
48
+ expected = [
49
+ MR::FakeRecord::Attribute.new(:name, :string),
50
+ MR::FakeRecord::Attribute.new(:active, :boolean)
51
+ ].sort
52
+ assert_equal expected, columns
53
+ end
54
+
55
+ end
56
+
57
+ class InstanceTests < UnitTests
58
+ desc "for a fake record instance"
59
+ setup do
60
+ @fake_record_class.attribute :name, :string
61
+ @fake_record_class.attribute :active, :boolean
62
+ @fake_record = @fake_record_class.new
63
+ end
64
+ subject{ @fake_record }
65
+
66
+ should have_writers :saved_attributes
67
+ should have_imeths :saved_attributes
68
+ should have_imeths :attributes, :attributes=
69
+ should have_imeths :column_for_attribute
70
+
71
+ should "return an empty hash using `saved_attributes`" do
72
+ assert_equal({}, subject.saved_attributes)
73
+ end
74
+
75
+ should "return a hash of attribute values using `attributes`" do
76
+ subject.name = 'test'
77
+ subject.active = true
78
+ expected = { 'name' => 'test', 'active' => true }
79
+ assert_equal expected, subject.attributes
80
+ end
81
+
82
+ should "allow writing multiple attribute values using `attributes=`" do
83
+ subject.attributes = { 'name' => 'test', 'active' => true }
84
+ assert_equal 'test', subject.name
85
+ assert_equal true, subject.active
86
+ end
87
+
88
+ should "ignore non hash arguments passed to `attributes=`" do
89
+ assert_nothing_raised{ subject.attributes = 'test' }
90
+ end
91
+
92
+ should "return the matching attribute column using `column_for_attribute`" do
93
+ expected = @fake_record_class.columns.detect{ |c| c.name == 'name' }
94
+ assert_equal expected, subject.column_for_attribute('name')
95
+ assert_nil subject.column_for_attribute('doesnt_exist')
96
+ end
97
+
98
+ end
99
+
100
+ class AttributeSetTests < UnitTests
101
+ desc "AttributeSet"
102
+ setup do
103
+ @fake_record = @fake_record_class.new
104
+ @attribute_set = MR::FakeRecord::AttributeSet.new
105
+ end
106
+ subject{ @attribute_set }
107
+
108
+ should have_imeths :add, :find
109
+ should have_imeths :read_all, :batch_write
110
+ should have_imeths :each, :to_a
111
+
112
+ should "be enumerable" do
113
+ assert_includes Enumerable, subject.class
114
+ end
115
+
116
+ should "add an attribute to the set with `add` and return it using `find`" do
117
+ subject.add @fake_record_class, :created_at, :timestamp, :null => false
118
+
119
+ attribute = subject.find(:created_at)
120
+ assert_instance_of MR::FakeRecord::Attribute, attribute
121
+ assert_equal 'created_at', attribute.name
122
+ assert_equal :timestamp, attribute.type
123
+ assert_equal false, attribute.null
124
+ end
125
+
126
+ should "allow mass reading and writing using `read_all` and `batch_write`" do
127
+ subject.add @fake_record_class, :name, :string
128
+ subject.add @fake_record_class, :active, :boolean
129
+ values = { 'name' => 'test', 'active' => true }
130
+ subject.batch_write(values, @fake_record)
131
+ assert_equal 'test', @fake_record.name
132
+ assert_equal true, @fake_record.active
133
+ assert_equal values, subject.read_all(@fake_record)
134
+ end
135
+
136
+ should "yield each attribute using `each`" do
137
+ yielded = []
138
+ subject.each{ |a| yielded << a }
139
+ assert_equal yielded.sort, subject.to_a
140
+ end
141
+
142
+ should "return it's attributes sorted using `to_a`" do
143
+ subject.add @fake_record_class, :name, :string
144
+ subject.add @fake_record_class, :active, :boolean
145
+ array = subject.to_a
146
+
147
+ expected = [
148
+ MR::FakeRecord::Attribute.new(:name, :string),
149
+ MR::FakeRecord::Attribute.new(:active, :boolean)
150
+ ].sort
151
+ assert_equal expected, array
152
+ end
153
+
154
+ should "raise a NoAttributeError using `find` with an invalid name" do
155
+ assert_raises(MR::FakeRecord::NoAttributeError) do
156
+ subject.find(:doesnt_exist)
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+ class AttributeTests < UnitTests
163
+ desc "Attribute"
164
+ setup do
165
+ @fake_record_class.attribute :name, :string
166
+ @fake_record = @fake_record_class.new
167
+ @attribute = MR::FakeRecord::Attribute.new(:name, :string)
168
+ end
169
+ subject{ @attribute }
170
+
171
+ should have_readers :name, :type, :primary, :null
172
+ should have_readers :reader_method_name, :writer_method_name
173
+ should have_readers :was_method_name, :changed_method_name
174
+ should have_imeths :read, :write, :was, :changed?
175
+
176
+ should "know it's name and type" do
177
+ assert_equal 'name', subject.name
178
+ assert_equal :string, subject.type
179
+ end
180
+
181
+ should "know if it's a primary attribute or not" do
182
+ attribute = MR::FakeRecord::Attribute.new(:name, :string)
183
+ assert_equal false, attribute.primary
184
+ attribute = MR::FakeRecord::Attribute.new(:id, :primary_key)
185
+ assert_equal true, attribute.primary
186
+ end
187
+
188
+ should "default its null attribute to true" do
189
+ assert_equal true, subject.null
190
+ end
191
+
192
+ should "allow setting its null attribute using an options hash" do
193
+ attribute = MR::FakeRecord::Attribute.new(:name, :string, :null => false)
194
+ assert_equal false, attribute.null
195
+ attribute = MR::FakeRecord::Attribute.new(:name, :string, :null => true)
196
+ assert_equal true, attribute.null
197
+ end
198
+
199
+ should "know it's method names" do
200
+ assert_equal "name", subject.reader_method_name
201
+ assert_equal "name=", subject.writer_method_name
202
+ assert_equal "name_was", subject.was_method_name
203
+ assert_equal "name_changed?", subject.changed_method_name
204
+ end
205
+
206
+ should "read an attribute's value using `read`" do
207
+ assert_nil subject.read(@fake_record)
208
+ @fake_record.name = 'test'
209
+ assert_equal 'test', subject.read(@fake_record)
210
+ end
211
+
212
+ should "write an attribute's value using `write`" do
213
+ subject.write('test', @fake_record)
214
+ assert_equal 'test', @fake_record.name
215
+ end
216
+
217
+ should "read an attribute's previous value using `was`" do
218
+ @fake_record.saved_attributes = {}
219
+ assert_nil subject.was(@fake_record)
220
+ @fake_record.saved_attributes = { 'name' => 'test' }
221
+ assert_equal 'test', subject.was(@fake_record)
222
+ end
223
+
224
+ should "detect if an attribute's changed using `changed?`" do
225
+ @fake_record.saved_attributes = {}
226
+ assert_equal false, subject.changed?(@fake_record)
227
+ subject.write('test', @fake_record)
228
+ assert_equal true, subject.changed?(@fake_record)
229
+ @fake_record.saved_attributes = { 'name' => 'test' }
230
+ assert_equal false, subject.changed?(@fake_record)
231
+ end
232
+
233
+ should "be comparable" do
234
+ attribute = MR::FakeRecord::Attribute.new(:name, :string)
235
+ assert_equal attribute, subject
236
+ attribute = MR::FakeRecord::Attribute.new(:id, :string)
237
+ assert_not_equal attribute, subject
238
+ attribute = MR::FakeRecord::Attribute.new(:name, :boolean)
239
+ assert_not_equal attribute, subject
240
+ attribute = MR::FakeRecord::Attribute.new(:name, :string, :null => false)
241
+ assert_not_equal attribute, subject
242
+ end
243
+
244
+ should "be sortable" do
245
+ attributes = [
246
+ MR::FakeRecord::Attribute.new(:id, :primary_key),
247
+ MR::FakeRecord::Attribute.new(:name, :string),
248
+ MR::FakeRecord::Attribute.new(:active, :boolean)
249
+ ].sort
250
+ assert_equal [ 'active', 'id', 'name' ], attributes.map(&:name)
251
+ end
252
+
253
+ should "define attribute methods using `define_on`" do
254
+ subject.define_on(@fake_record_class)
255
+ fake_record = @fake_record_class.new
256
+
257
+ assert_respond_to :name, fake_record
258
+ assert_respond_to :name=, fake_record
259
+ assert_respond_to :name_was, fake_record
260
+ assert_respond_to :name_changed?, fake_record
261
+ end
262
+
263
+ end
264
+
265
+ end
@@ -0,0 +1,239 @@
1
+ require 'assert'
2
+ require 'mr/fake_record/persistence'
3
+
4
+ require 'much-plugin'
5
+
6
+ module MR::FakeRecord::Persistence
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "MR::FakeRecord::Persistence"
10
+ setup do
11
+ @module = MR::FakeRecord::Persistence
12
+ end
13
+ subject{ @module }
14
+
15
+ should "use much-plugin" do
16
+ assert_includes MuchPlugin, subject
17
+ end
18
+
19
+ end
20
+
21
+ class TransactionMethodsTests < UnitTests
22
+ desc "TransactionMethods"
23
+ setup do
24
+ @module = Module.new{ extend TransactionMethods }
25
+ end
26
+
27
+ should have_imeths :transaction
28
+
29
+ should "yield to a block and rescue rollback exceptions using `transaction`" do
30
+ block_called = false
31
+ assert_nothing_raised do
32
+ subject.transaction do
33
+ block_called = true
34
+ raise ActiveRecord::Rollback
35
+ end
36
+ end
37
+ assert_true block_called
38
+ end
39
+
40
+ should "allow calling transaction with no block" do
41
+ assert_nil subject.transaction
42
+ end
43
+
44
+ end
45
+
46
+ class MixinTests < UnitTests
47
+ desc "when mixed in"
48
+ setup do
49
+ @fake_record_class = Class.new do
50
+ include MR::FakeRecord::Persistence
51
+ attribute :name, :string
52
+ attribute :active, :boolean
53
+ end
54
+ end
55
+ subject{ @fake_record_class }
56
+
57
+ should have_imeths :human_attribute_name
58
+
59
+ should "include FakeRecord Attributes mixin" do
60
+ assert_includes MR::FakeRecord::Attributes, subject
61
+ end
62
+
63
+ should "extend the transaction methods mixin" do
64
+ metaclass = class << subject; self; end
65
+ assert_includes TransactionMethods, metaclass
66
+ end
67
+
68
+ should "add an id primary key attribute" do
69
+ attribute = subject.attributes.find(:id)
70
+ assert_not_nil attribute
71
+ assert attribute.primary
72
+ end
73
+
74
+ should "return the default option using `human_attribute_name`" do
75
+ attribute_name = subject.human_attribute_name(:name, :default => "Name")
76
+ assert_equal "Name", attribute_name
77
+ end
78
+
79
+ should "return the last part of the attribute name as a string when " \
80
+ "no default option is passed using `human_attribute_name`" do
81
+ attribute_name = subject.human_attribute_name('a.i18n.translation.name')
82
+ assert_equal "name", attribute_name
83
+ end
84
+
85
+ end
86
+
87
+ class InstanceTests < MixinTests
88
+ desc "for a fake record instance"
89
+ setup do
90
+ @primary_key = 1
91
+ Assert.stub(MR::Factory, :primary_key).with(@fake_record_class){ @primary_key }
92
+ @fake_record = @fake_record_class.new
93
+ end
94
+ subject{ @fake_record }
95
+
96
+ should have_accessors :id
97
+ should have_imeths :save!, :destroy
98
+ should have_imeths :transaction
99
+ should have_imeths :new_record?, :destroyed?
100
+ should have_imeths :errors, :valid?
101
+ should have_imeths :save_called, :reset_save_called
102
+
103
+ should "default it's save called to `false`" do
104
+ assert_false subject.save_called
105
+ end
106
+
107
+ should "not raise an invalid record error using `save!` when its valid" do
108
+ subject.errors.clear
109
+ assert_nothing_raised{ subject.save! }
110
+ end
111
+
112
+ should "raise a invalid record error using `save!` when its invalid" do
113
+ subject.errors.add(:name, 'invalid')
114
+ exception = nil
115
+ begin; subject.save!; rescue StandardError => exception; end
116
+
117
+ assert_instance_of ActiveRecord::RecordInvalid, exception
118
+ assert_equal 'Validation failed: Name invalid', exception.message
119
+ end
120
+
121
+ should "set it's id when saved for the first time using `save!`" do
122
+ assert_nil subject.id
123
+ subject.save!
124
+ id = subject.id
125
+ assert_equal @primary_key, id
126
+ subject.save!
127
+ assert_same id, subject.id
128
+ end
129
+
130
+ should "copy it's attributes to it's saved attributes using `save!`" do
131
+ expected = { 'id' => @primary_key, 'name' => nil, 'active' => nil }
132
+ assert_not_equal expected, subject.saved_attributes
133
+ subject.save!
134
+ assert_equal expected, subject.saved_attributes
135
+ end
136
+
137
+ should "set its save called to `true` using `save!`" do
138
+ subject.save!
139
+ assert_true subject.save_called
140
+ end
141
+
142
+ should "mark the fake record as destroyed using `destroy`" do
143
+ assert_not subject.destroyed?
144
+ subject.destroy
145
+ assert subject.destroyed?
146
+ end
147
+
148
+ should "know how to run a block in a transaction" do
149
+ transaction_called_with = nil
150
+ Assert.stub(@fake_record_class, :transaction) do |&block|
151
+ transaction_called_with = block
152
+ end
153
+
154
+ block = proc{ Factory.string }
155
+ subject.transaction(&block)
156
+ assert_equal block, transaction_called_with
157
+ end
158
+
159
+ should "return whether a record has been saved or not using `new_record?`" do
160
+ assert subject.new_record?
161
+ subject.save!
162
+ assert_not subject.new_record?
163
+ end
164
+
165
+ should "return an instance of ActiveModel::Errors using `errors`" do
166
+ assert_instance_of ActiveModel::Errors, subject.errors
167
+ end
168
+
169
+ should "return whether a record has any errors or not using `valid?`" do
170
+ subject.errors.clear
171
+ assert subject.valid?
172
+ subject.errors.add(:test, 'invalid')
173
+ assert_not subject.valid?
174
+ end
175
+
176
+ should "allow resetting save called to `false` using `reset_save_called`" do
177
+ subject.save!
178
+ subject.reset_save_called
179
+ assert_false subject.save_called
180
+ end
181
+
182
+ end
183
+
184
+ class WithTimestampsTests < MixinTests
185
+ desc "with timestamp attributes"
186
+ setup do
187
+ @default_timezone = ActiveRecord::Base.default_timezone
188
+ @current_time = Time.now
189
+ Assert.stub(Time, :now){ @current_time }
190
+ @fake_record_class.attribute :created_at, :datetime
191
+ @fake_record_class.attribute :updated_at, :datetime
192
+ @fake_record = @fake_record_class.new
193
+ end
194
+ teardown do
195
+ ActiveRecord::Base.default_timezone = @default_timezone
196
+ end
197
+ subject{ @fake_record }
198
+
199
+ should "set it's created at when saved for the first time using `save!`" do
200
+ assert_nil subject.created_at
201
+ subject.save!
202
+ created_at = subject.created_at
203
+ assert_equal @current_time, created_at
204
+ subject.save!
205
+ assert_same created_at, subject.created_at
206
+ end
207
+
208
+ should "set it's updated at everytime `save!` is called" do
209
+ assert_nil subject.updated_at
210
+ subject.save!
211
+ updated_at = subject.updated_at
212
+ assert_equal @current_time, updated_at
213
+ new_time = Time.local(2013, 1, 1)
214
+ Assert.stub(Time, :now){ new_time }
215
+ subject.save!
216
+ assert_equal new_time, subject.updated_at
217
+ end
218
+
219
+ should "not overwrite updated at when its manually set" do
220
+ expected = Time.local(2013, 1, 1)
221
+ subject.updated_at = expected
222
+ subject.save!
223
+ assert_equal expected, subject.updated_at
224
+ subject.save!
225
+ assert_equal @current_time, subject.updated_at
226
+ end
227
+
228
+ should "use ActiveRecord's configured default timezone" do
229
+ ActiveRecord::Base.default_timezone = :local
230
+ subject.save!
231
+ assert_equal Time.now.zone, subject.updated_at.zone
232
+ ActiveRecord::Base.default_timezone = :utc
233
+ subject.save!
234
+ assert_equal Time.now.utc.zone, subject.updated_at.zone
235
+ end
236
+
237
+ end
238
+
239
+ end