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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +13 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/bench/all.rb +4 -0
- data/bench/factory.rb +68 -0
- data/bench/fake_record.rb +174 -0
- data/bench/model.rb +201 -0
- data/bench/read_model.rb +191 -0
- data/bench/results/factory.txt +21 -0
- data/bench/results/fake_record.txt +37 -0
- data/bench/results/model.txt +44 -0
- data/bench/results/read_model.txt +46 -0
- data/bench/setup.rb +132 -0
- data/lib/mr.rb +11 -0
- data/lib/mr/after_commit.rb +49 -0
- data/lib/mr/after_commit/fake_record.rb +39 -0
- data/lib/mr/after_commit/record.rb +48 -0
- data/lib/mr/after_commit/record_procs_methods.rb +82 -0
- data/lib/mr/factory.rb +82 -0
- data/lib/mr/factory/config.rb +240 -0
- data/lib/mr/factory/model_factory.rb +103 -0
- data/lib/mr/factory/model_stack.rb +28 -0
- data/lib/mr/factory/read_model_factory.rb +104 -0
- data/lib/mr/factory/record_factory.rb +130 -0
- data/lib/mr/factory/record_stack.rb +219 -0
- data/lib/mr/fake_query.rb +53 -0
- data/lib/mr/fake_record.rb +58 -0
- data/lib/mr/fake_record/associations.rb +257 -0
- data/lib/mr/fake_record/attributes.rb +168 -0
- data/lib/mr/fake_record/persistence.rb +116 -0
- data/lib/mr/json_field.rb +180 -0
- data/lib/mr/json_field/fake_record.rb +31 -0
- data/lib/mr/json_field/record.rb +38 -0
- data/lib/mr/model.rb +67 -0
- data/lib/mr/model/associations.rb +161 -0
- data/lib/mr/model/configuration.rb +67 -0
- data/lib/mr/model/fields.rb +177 -0
- data/lib/mr/model/persistence.rb +79 -0
- data/lib/mr/query.rb +126 -0
- data/lib/mr/read_model.rb +83 -0
- data/lib/mr/read_model/data.rb +38 -0
- data/lib/mr/read_model/fields.rb +218 -0
- data/lib/mr/read_model/query_expression.rb +188 -0
- data/lib/mr/read_model/querying.rb +214 -0
- data/lib/mr/read_model/set_querying.rb +82 -0
- data/lib/mr/read_model/subquery.rb +98 -0
- data/lib/mr/record.rb +35 -0
- data/lib/mr/test_helpers.rb +229 -0
- data/lib/mr/type_converter.rb +85 -0
- data/lib/mr/version.rb +3 -0
- data/log/.gitkeep +0 -0
- data/mr.gemspec +29 -0
- data/test/helper.rb +21 -0
- data/test/support/db.rb +10 -0
- data/test/support/factory.rb +13 -0
- data/test/support/factory/area.rb +6 -0
- data/test/support/factory/comment.rb +14 -0
- data/test/support/factory/image.rb +6 -0
- data/test/support/factory/user.rb +6 -0
- data/test/support/models/area.rb +58 -0
- data/test/support/models/comment.rb +60 -0
- data/test/support/models/image.rb +53 -0
- data/test/support/models/user.rb +96 -0
- data/test/support/read_model/querying.rb +150 -0
- data/test/support/read_models/comment_with_user_data.rb +27 -0
- data/test/support/read_models/set_data.rb +49 -0
- data/test/support/read_models/subquery_data.rb +41 -0
- data/test/support/read_models/user_with_area_data.rb +15 -0
- data/test/support/schema.rb +39 -0
- data/test/support/setup_test_db.rb +10 -0
- data/test/system/factory/model_factory_tests.rb +87 -0
- data/test/system/factory/model_stack_tests.rb +30 -0
- data/test/system/factory/record_factory_tests.rb +84 -0
- data/test/system/factory/record_stack_tests.rb +51 -0
- data/test/system/factory_tests.rb +32 -0
- data/test/system/read_model_tests.rb +199 -0
- data/test/system/with_model_tests.rb +275 -0
- data/test/unit/after_commit/fake_record_tests.rb +110 -0
- data/test/unit/after_commit/record_procs_methods_tests.rb +177 -0
- data/test/unit/after_commit/record_tests.rb +134 -0
- data/test/unit/after_commit_tests.rb +113 -0
- data/test/unit/factory/config_tests.rb +651 -0
- data/test/unit/factory/model_factory_tests.rb +473 -0
- data/test/unit/factory/model_stack_tests.rb +97 -0
- data/test/unit/factory/read_model_factory_tests.rb +195 -0
- data/test/unit/factory/record_factory_tests.rb +446 -0
- data/test/unit/factory/record_stack_tests.rb +549 -0
- data/test/unit/factory_tests.rb +213 -0
- data/test/unit/fake_query_tests.rb +137 -0
- data/test/unit/fake_record/associations_tests.rb +585 -0
- data/test/unit/fake_record/attributes_tests.rb +265 -0
- data/test/unit/fake_record/persistence_tests.rb +239 -0
- data/test/unit/fake_record_tests.rb +106 -0
- data/test/unit/json_field/fake_record_tests.rb +75 -0
- data/test/unit/json_field/record_tests.rb +80 -0
- data/test/unit/json_field_tests.rb +302 -0
- data/test/unit/model/associations_tests.rb +346 -0
- data/test/unit/model/configuration_tests.rb +92 -0
- data/test/unit/model/fields_tests.rb +278 -0
- data/test/unit/model/persistence_tests.rb +114 -0
- data/test/unit/model_tests.rb +137 -0
- data/test/unit/query_tests.rb +300 -0
- data/test/unit/read_model/data_tests.rb +56 -0
- data/test/unit/read_model/fields_tests.rb +416 -0
- data/test/unit/read_model/query_expression_tests.rb +381 -0
- data/test/unit/read_model/querying_tests.rb +613 -0
- data/test/unit/read_model/set_querying_tests.rb +149 -0
- data/test/unit/read_model/subquery_tests.rb +242 -0
- data/test/unit/read_model_tests.rb +187 -0
- data/test/unit/record_tests.rb +45 -0
- data/test/unit/test_helpers_tests.rb +431 -0
- data/test/unit/type_converter_tests.rb +207 -0
- 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
|