minitest-sequel 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,166 +1,446 @@
1
- # require "minitest/sequel"
1
+ # frozen_string_literal: false
2
+
3
+ require 'minitest/spec'
2
4
 
3
5
  # reopening to add validations functionality
4
- module Minitest::Assertions
5
-
6
- # Test if a model instance is timestamped via .plugin(:timestamps)
7
- #
8
- # let(:m) { Post.create(title: "Dummy") }
9
- # proc { assert_timestamped_model_instance(m) }.wont_have_error
10
- #
11
- # You can also test if an updated record is correctly timestamped
12
- #
13
- # m.title = "Updated"
14
- # m.save
15
- # proc { assert_timestamped_model_instance(m, updated_record: true) }.wont_have_error
16
- #
17
- # Or alternatively test if an updated record is wrongly timestamped
18
- #
19
- # let(:m) { Post.create(title: "Dummy", updated_at: Time.now) }
20
- # proc { assert_timestamped_model_instance(m, updated_record: false) }.must_have_error(/expected #.updated_at to be NIL on new record/)
21
- #
22
- #
23
- def assert_timestamped_model_instance(model, opts = {})
24
- model_class = model.class
25
- # 1. test for Timestamps plugin
26
- plugs = model_class.instance_variable_get("@plugins").map(&:to_s)
27
- if plugs.include?("Sequel::Plugins::Timestamps")
6
+ module Minitest
7
+ # add support for Assert syntax
8
+ module Assertions
9
+ # Test if a model instance is timestamped via .plugin(:timestamps)
10
+ #
11
+ # This assertion checks if a given model instance has been properly timestamped
12
+ # using the Sequel Timestamps plugin. It verifies the presence of the plugin,
13
+ # the existence of the required columns, and the correct behavior of timestamps
14
+ # for both new and updated records.
15
+ #
16
+ # @param model [Sequel::Model] The model instance to test
17
+ # @param opts [Hash] Options to modify the assertion behavior
18
+ # @option opts [Boolean] :updated_record Set to true to test an updated record
19
+ #
20
+ # @example Testing a new record
21
+ # let(:m) { Post.create(title: 'Dummy') }
22
+ # assert_no_error { assert_timestamped_model_instance(m) }
23
+ #
24
+ # @example Testing an updated record
25
+ # m.title = 'Updated'
26
+ # m.save
27
+ # assert_no_error { assert_timestamped_model_instance(m, updated_record: true) }
28
+ #
29
+ # @example Testing an incorrectly timestamped record
30
+ # let(:m) { Post.create(title: 'Dummy', updated_at: Time.now) }
31
+ #
32
+ # msg = /expected #.updated_at to be NIL on new record/
33
+ #
34
+ # assert_error_raised(msg) do
35
+ # assert_timestamped_model_instance(m, updated_record: false)
36
+ # end
37
+ #
38
+ # @raise [Minitest::Assertion] If the model instance does not meet the timestamped criteria
39
+ #
40
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
41
+ def assert_timestamped_model_instance(model, opts = {})
42
+ model_class = model.class
43
+
44
+ # 1. test for Timestamps plugin
45
+ plugs = model_class.instance_variable_get(:@plugins).map(&:to_s)
46
+
47
+ unless plugs.include?('Sequel::Plugins::Timestamps')
48
+ msg = "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}"
49
+ raise(Minitest::Assertion, msg)
50
+ end
51
+
52
+ str = 'AssertTimestampedModelInstance -'
53
+
28
54
  # 2. test for created_at / :updated_at columns
29
- assert_have_column(model, :created_at, {}, "AssertTimestampedModelInstance - expected model to have column :created_at, Debug: [#{model.inspect}]")
30
- assert_have_column(model, :updated_at, {}, "AssertTimestampedModelInstance - expected model to have column :updated_at, Debug: [#{model.inspect}]")
55
+ msg = "#{str} expected model to have column :created_at. Debug: [#{model.inspect}]"
56
+ assert_have_column(model, :created_at, {}, msg)
57
+
58
+ msg = "#{str} expected model to have column :updated_at. Debug: [#{model.inspect}]"
59
+ assert_have_column(model, :updated_at, {}, msg)
31
60
 
32
61
  if opts[:updated_record]
33
62
  # 4. updated record
34
- assert_instance_of(Time, model.created_at, "AssertTimestampedModelInstance:created_at - expected #created_at to be an instance of Time on updated record")
35
- assert_instance_of(Time, model.updated_at, "AssertTimestampedModelInstance:updated_at - expected #updated_at to be an instance of Time on updated record")
63
+ msg = "#{str} expected #created_at to be an instance of Time on updated record"
64
+ assert_instance_of(Time, model.created_at, msg)
65
+
66
+ msg = "#{str} expected #updated_at to be an instance of Time on updated record"
67
+ assert_instance_of(Time, model.updated_at, msg)
36
68
  else
37
69
  # 3. initial record
38
- assert_instance_of(Time, model.created_at, "AssertTimestampedModelInstance:created_at - expected #created_at to be an instance of Time on new record")
39
- proc {
40
- assert_nil(model.updated_at, "AssertTimestampedModelInstance:updated - expected #updated_at to be NIL on new record")
41
- }.wont_have_error
70
+ msg = "#{str} expected #created_at to be an instance of Time on new record"
71
+ assert_instance_of(Time, model.created_at, msg)
72
+
73
+ msg = "#{str} expected #updated_at to be NIL on new record"
74
+ assert_no_error { assert_nil(model.updated_at, msg) }
42
75
  end
43
- else
44
- raise(Minitest::Assertion, "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}")
45
76
  end
46
- end
77
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
78
+
79
+ # Test if a model class is timestamped with .plugin(:timestamps)
80
+ #
81
+ # This assertion checks if a given model class has been properly configured
82
+ # with the Sequel Timestamps plugin. It verifies the presence of the plugin,
83
+ # the existence of the required columns, and the correct behavior of timestamps
84
+ # for both new and updated records.
85
+ #
86
+ # @param model [Class] The model class to test
87
+ # @param opts [Hash] Options to modify the assertion behavior
88
+ #
89
+ # @example Testing a timestamped model
90
+ # class Comment < Sequel::Model
91
+ # plugin(:timestamps)
92
+ # end
93
+ #
94
+ # assert_no_error { assert_timestamped_model(Comment) }
95
+ #
96
+ # @example Testing a non-timestamped model
97
+ # class Post < Sequel::Model; end
98
+ #
99
+ # msg = /Not a \.plugin\(:timestamps\) model, available plugins are/
100
+ #
101
+ # assert_error_raised(msg) { assert_timestamped_model(Post) }
102
+ #
103
+ # @example Testing with additional attributes to create a valid model instance
104
+ # assert_no_error do
105
+ # assert_timestamped_model(Comment, {body: "I think...", email: "e@email.com"})
106
+ # end
107
+ #
108
+ # @raise [Minitest::Assertion] If the model class does not meet the timestamped criteria
109
+ #
110
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
111
+ def assert_timestamped_model(model, opts = {})
112
+ m = opts.empty? ? model.send(:make) : model.send(:create, opts)
113
+
114
+ # 1. test for Timestamps plugin
115
+ plugs = model.instance_variable_get(:@plugins).map(&:to_s)
116
+
117
+ unless plugs.include?('Sequel::Plugins::Timestamps')
118
+ msg = "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}"
119
+ raise(Minitest::Assertion, msg)
120
+ end
121
+
122
+ str = 'AssertTimestampedModel - expected'
47
123
 
48
- # Test if a model class is timestamped with .plugin(:timestamps)
49
- #
50
- # # Declared locally in the Model
51
- # class Comment < Sequel::Model
52
- # plugin(:timestamps)
53
- # end
54
- # proc { assert_timestamped_model(Comment) }.wont_have_error
55
- #
56
- # # on a non-timestamped model
57
- # class Post < Sequel::Model; end
58
- # proc { assert_timestamped_model(Post) }.must_have_error(/Not a \.plugin\(:timestamps\) model, available plugins are/)
59
- #
60
- #
61
- # NOTE!
62
- #
63
- # You can also pass attributes to the created model in the tests via the `opts` hash like this:
64
- #
65
- # proc { assert_timestamped_model(Comment, {body: "I think...", email: "e@email.com"}) }.wont_have_error
66
- #
67
- #
68
- def assert_timestamped_model(model, opts = {})
69
- m = model.create(opts)
70
- # 1. test for Timestamps plugin
71
- plugs = model.instance_variable_get("@plugins").map(&:to_s)
72
- if plugs.include?("Sequel::Plugins::Timestamps")
73
124
  # 2. test for created_at / :updated_at columns
74
- assert_have_column(m, :created_at, {}, "AssertTimestampedModel - expected model to have column :created_at. Debug: [#{m.inspect}]")
75
- assert_have_column(m, :updated_at, {}, "AssertTimestampedModel - expected model to have column :updated_at. Debug: [#{m.inspect}]")
125
+ msg = "#{str} model to have column :created_at. Debug: [#{m.inspect}]"
126
+ assert_have_column(m, :created_at, {}, msg)
127
+
128
+ msg = "#{str} model to have column :updated_at. Debug: [#{m.inspect}]"
129
+ assert_have_column(m, :updated_at, {}, msg)
76
130
 
77
131
  # 3. initial record
78
- assert_instance_of(Time, m.created_at, "AssertTimestampedModel:created_at - expected #created_at to be an instance of Time on new record. Debug: [#{m.inspect}]")
79
- assert_instance_of(NilClass, m.updated_at, "AssertTimestampedModel:updated_at - expected #updated_at to be an instance of NilClass on new record. Debug: [#{m.inspect}]")
132
+ msg = "#{str} :created_at to be an instance of Time on new record. Debug: [#{m.inspect}]"
133
+ assert_instance_of(Time, m.created_at, msg)
134
+
135
+ msg = "#{str} :updated_at to be an instance of Time on new record. Debug: [#{m.inspect}]"
136
+ assert_instance_of(NilClass, m.updated_at, msg)
80
137
 
81
138
  # 4. updated record
82
139
  # old_ts = m.created_at
83
140
  # sleep 1 # TODO: could this be converted to timecop or similar?
84
- m.title = "#{m.title} updated"
141
+ # m.title = "#{m.title} updated"
85
142
  assert(m.save, "AssertTimestampedModel:#save - updated model failed. Debug: [#{m.inspect}]")
86
- assert_instance_of(Time, m.created_at, "AssertTimestampedModel:created_at - expected #created_at to be an instance of Time on updated record. Debug: [#{m.inspect}]")
87
- assert_instance_of(Time, m.updated_at, "AssertTimestampedModel:updated_at - expected #updated_at to be an instance of Time on updated record. Debug: [#{m.inspect}]")
88
- # assert_equal(old_ts, m.created_at, "AssertTimestampedModel - expected the :created_at timestamp to be unchanged")
89
- else
90
- raise(Minitest::Assertion, "Not a plugin(:timestamps) model, available plugins are: #{plugs.inspect}")
143
+
144
+ msg = "#{str} :created_at to be an instance of Time on updated record. Debug: [#{m.inspect}]"
145
+ assert_instance_of(Time, m.created_at, msg)
146
+
147
+ msg = "#{str} :updated_at to be an instance of Time on updated record. Debug: [#{m.inspect}]"
148
+ assert_instance_of(Time, m.updated_at, msg)
149
+
150
+ # assert_equal(old_ts, m.created_at, "#{str} the :created_at timestamp to be unchanged")
91
151
  end
92
- end
152
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
153
+
154
+ # Test if a model class is paranoid with .plugin(:paranoid) via [Sequel-Paranoid](https://github.com/sdepold/sequel-paranoid)
155
+ #
156
+ # This assertion checks if a given model class has been properly configured
157
+ # with the Sequel Paranoid plugin. It verifies the presence of the plugin,
158
+ # the existence of the required column (:deleted_at), and the correct behavior
159
+ # of soft deletion for both new and updated records.
160
+ #
161
+ # @param model [Class] The model class to test
162
+ # @param opts [Hash] Options to modify the assertion behavior
163
+ #
164
+ # @example Testing a paranoid model
165
+ # class Comment < Sequel::Model
166
+ # plugin(:paranoid)
167
+ # end
168
+ # assert_no_error { assert_paranoid_model(Comment) }
169
+ #
170
+ # @example Testing a non-paranoid model
171
+ # class Post < Sequel::Model; end
172
+ #
173
+ # msg = /Not a plugin\(:paranoid\) model, available plugins are/
174
+ #
175
+ # assert_error_raised(msg) { assert_paranoid_model(Post) }
176
+ #
177
+ # @example Testing with additional attributes to create a valid model instance
178
+ # assert_no_error do
179
+ # assert_paranoid_model(Comment, {body: "I think...", email: "e@email.com"})
180
+ # end
181
+ #
182
+ # @raise [Minitest::Assertion] If the model class does not meet the paranoid criteria
183
+ #
184
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
185
+ def assert_paranoid_model(model, opts = {})
186
+ m = opts.empty? ? model.send(:make) : model.send(:create, opts)
187
+
188
+ # 1. test for Paranoid plugin
189
+ plugs = model.instance_variable_get(:@plugins).map(&:to_s)
190
+
191
+ unless plugs.include?('Sequel::Plugins::Paranoid')
192
+ raise(
193
+ Minitest::Assertion,
194
+ "Not a plugin(:paranoid) model, available plugins are: #{plugs.inspect}"
195
+ )
196
+ end
197
+
198
+ str = 'AssertParanoidModel - expected'
199
+
200
+ msg = "#{str} #deleted_at to be NIL on new model"
201
+ assert_nil(m.deleted_at, msg)
93
202
 
94
- # Test if a model class is paranoid with .plugin(:paranoid) via [Sequel-Paranoid](https://github.com/sdepold/sequel-paranoid)
95
- #
96
- # # Declared locally in the Model
97
- # class Comment < Sequel::Model
98
- # plugin(:paranoid)
99
- # end
100
- # proc { assert_paranoid_model(Comment) }.wont_have_error
101
- #
102
- # # on a non-paranoid model
103
- # class Post < Sequel::Model; end
104
- # proc { assert_paranoid_model(Post) }.must_have_error(/Not a plugin\(:paranoid\) model, available plugins are/)
105
- #
106
- #
107
- # NOTE!
108
- #
109
- # You can also pass attributes to the created model in the tests via the `opts` hash like this:
110
- #
111
- # proc { assert_timestamped_model(Comment, {body: "I think...", email: "e@email.com"}) }.wont_have_error
112
- #
113
- #
114
- def assert_paranoid_model(model, opts = {})
115
- m = model.create(opts)
116
- # 1. test for Paranoid plugin
117
- plugs = model.instance_variable_get("@plugins").map(&:to_s)
118
- if plugs.include?("Sequel::Plugins::Paranoid")
119
- assert_nil(m.deleted_at, "AssertParanoidModel:deleted_at - expected #deleted_at to be NIL on new model")
120
203
  # after update
121
204
  assert(m.save, "AssertParanoidModel:save - updated model failed. Debug: [#{m.inspect}]")
122
- assert_nil(m.deleted_at, "AssertParanoidModel:deleted_at - expected #deleted_at to be NIL on updated model")
205
+
206
+ msg = "#{str} #deleted_at to be NIL on updated model"
207
+ assert_nil(m.deleted_at, msg)
208
+
123
209
  # after destroy
124
210
  assert(m.destroy, "AssertParanoidModel:destroy - destroy model failed. Debug: [#{m.inspect}]")
125
- assert_instance_of(Time, m.deleted_at, "AssertParanoidModel:deleted_at - expected #deleted_at to be instance of Time on destroyed model, Debug: [#{m.inspect}]")
126
- else
127
- raise(Minitest::Assertion, "Not a plugin(:paranoid) model, available plugins are: #{plugs.inspect}")
211
+
212
+ # assert_instance_of(Time, m.deleted_at,
213
+ #
214
+ msg = "#{str} #deleted_at to be instance of Time on destroyed model, Debug: [#{m.inspect}]"
215
+ assert_instance_of(NilClass, m.deleted_at, msg)
216
+ end
217
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
218
+
219
+ # Test to ensure the current model is NOT a :timestamped model
220
+ #
221
+ # This assertion checks if a given model class has NOT been configured
222
+ # with the Sequel Timestamps plugin. It verifies the absence of the plugin
223
+ # in the model's list of plugins.
224
+ #
225
+ # @param model [Class] The model class to test
226
+ # @param _opts [Hash] Unused options parameter (kept for consistency with other methods)
227
+ #
228
+ # @example Testing a non-timestamped model
229
+ # class Post < Sequel::Model; end
230
+ # it { refute_timestamped_model(Post) }
231
+ #
232
+ # @example Testing a timestamped model (will fail)
233
+ # class Comment < Sequel::Model
234
+ # plugin :timestamps
235
+ # end
236
+ # it { refute_timestamped_model(Comment) } # This will fail
237
+ #
238
+ # @raise [Minitest::Assertion] If the model class is configured with the Timestamps plugin
239
+ #
240
+ def refute_timestamped_model(model, _opts = {})
241
+ plugs = model.instance_variable_get(:@plugins).map(&:to_s)
242
+
243
+ msg = "RefuteTimestampedModel - expected #{model} to NOT be a :timestamps model, but it was."
244
+ msg << " Debug: [#{plugs.inspect}]"
245
+
246
+ refute_includes(plugs, 'Sequel::Plugins::Timestamps', msg)
247
+ end
248
+
249
+ # Test to ensure the current model is NOT a :paranoid model
250
+ #
251
+ # This assertion checks if a given model class has NOT been configured
252
+ # with the Sequel Paranoid plugin. It verifies the absence of the plugin
253
+ # in the model's list of plugins.
254
+ #
255
+ # @param model [Class] The model class to test
256
+ #
257
+ # @example Testing a non-paranoid model
258
+ # class Post < Sequel::Model; end
259
+ # it { refute_paranoid_model(Post) }
260
+ #
261
+ # @example Testing a paranoid model (will fail)
262
+ # class Comment < Sequel::Model
263
+ # plugin :paranoid
264
+ # end
265
+ # it { refute_paranoid_model(Comment) } # This will fail
266
+ #
267
+ # @raise [Minitest::Assertion] If the model class is configured with the Paranoid plugin
268
+ #
269
+ def refute_paranoid_model(model)
270
+ plugs = model.instance_variable_get(:@plugins).map(&:to_s)
271
+
272
+ msg = "RefuteParanoidModel - expected #{model} to NOT be a :paranoid model, but it was. "
273
+ msg << "Debug: [#{plugs.inspect}]"
274
+
275
+ refute_includes(plugs, 'Sequel::Plugins::Paranoid', msg)
128
276
  end
129
277
  end
130
-
131
-
132
-
133
- # Test to ensure the current model is NOT a :timestamped model
278
+ # /module Assertions
279
+
280
+ # add support for Spec syntax
281
+ module Expectations
282
+ infect_an_assertion :assert_timestamped_model, :must_be_timestamped_model, :reverse
283
+ infect_an_assertion :assert_timestamped_model, :must_be_a_timestamped_model, :reverse
284
+ infect_an_assertion :assert_paranoid_model, :must_be_paranoid_model, :reverse
285
+ infect_an_assertion :assert_paranoid_model, :must_be_a_paranoid_model, :reverse
286
+
287
+ infect_an_assertion :refute_timestamped_model, :wont_be_timestamped_model, :reverse
288
+ infect_an_assertion :refute_timestamped_model, :wont_be_a_timestamped_model, :reverse
289
+ infect_an_assertion :refute_paranoid_model, :wont_be_paranoid_model, :reverse
290
+ infect_an_assertion :refute_paranoid_model, :wont_be_a_paranoid_model, :reverse
291
+ end
292
+ end
293
+
294
+ # reopening the class
295
+ # rubocop:disable Style/ClassAndModuleChildren
296
+ class Minitest::Spec < Minitest::Test
297
+ # Ensure that a given model is properly configured as a paranoid model
134
298
  #
135
- # it { refute_timestamped_model(Post) }
299
+ # This method sets up a series of tests to verify that a model
300
+ # is correctly using the Sequel Paranoid plugin. It checks the behavior
301
+ # of the :deleted_at column in various scenarios.
136
302
  #
137
- def refute_timestamped_model(model, opts = {})
138
- plugs = model.instance_variable_get("@plugins").map(&:to_s)
139
- refute_includes(plugs, "Sequel::Plugins::Timestamps", "RefuteTimestampedModel - expected #{model} to NOT be a :timestamped model, but it was, Debug: [#{plugs.inspect}]")
140
- end
141
-
142
- # Test to ensure the current model is NOT a :paranoid model
303
+ # @param model [Class] The model class to test
304
+ #
305
+ # @example Testing a paranoid model
306
+ # class Comment < Sequel::Model
307
+ # plugin :paranoid
308
+ # end
143
309
  #
144
- # it { refute_paranoid_model(Post) }
310
+ # describe Comment do
311
+ # ensure_paranoid_model(Comment)
312
+ # end
145
313
  #
146
- def refute_paranoid_model(model)
147
- plugs = model.instance_variable_get("@plugins").map(&:to_s)
148
- refute_includes(plugs, "Sequel::Plugins::Paranoid", "RefuteParanoidModel - expected #{model} to NOT be a :paranoid model, but it was, Debug: [#{plugs.inspect}]")
314
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
315
+ def self.ensure_paranoid_model(model)
316
+ # rubocop:disable Metrics/BlockLength
317
+ describe 'a paranoid model with .plugin(:paranoid)' do
318
+ let(:m) { model.send(:make) }
319
+
320
+ describe 'on a new record' do
321
+ it '#:deleted_at should be NULL (empty)' do
322
+ msg = 'EnsureParanoidModel#new - expected #deleted_at to be nil on new record. '
323
+ msg << "Debug: [#{m.inspect}]"
324
+
325
+ assert_nil(m.deleted_at, msg)
326
+ end
327
+ end
328
+
329
+ describe 'on an updated record' do
330
+ it '#:deleted_at should be NULL (empty)' do
331
+ m.save
332
+
333
+ msg = 'EnsureParanoidModel#update - expected #deleted_at to be nil on updated record. '
334
+ msg << "Debug: [#{m.inspect}]"
335
+
336
+ assert_nil(m.deleted_at, msg)
337
+ end
338
+ end
339
+
340
+ describe 'after a record#destroy' do
341
+ it "#:deleted_at should be NULL (empty) on a delete'd record" do
342
+ m.destroy
343
+
344
+ msg = 'EnsureParanoidModel#destroy - expected #deleted_at to be nil on destroyed record. '
345
+ msg << "Debug: [#{m.inspect}]"
346
+
347
+ assert_nil(m.deleted_at, msg)
348
+ end
349
+ end
350
+
351
+ describe 'after a record#delete' do
352
+ it "#:deleted_at should be NULL (empty) on a delete'd record" do
353
+ m.delete
354
+
355
+ msg = 'EnsureParanoidModel#delete - expected #deleted_at to be nil on deleted record. '
356
+ msg << "Debug: [#{m.inspect}]"
357
+
358
+ assert_nil(m.deleted_at, msg)
359
+ end
360
+ end
361
+
362
+ describe 'after a record#soft_delete' do
363
+ it '#:deleted_at should be a timestamp' do
364
+ refute(m.deleted?)
365
+ assert_no_error { m.soft_delete }
366
+ assert(m.deleted?)
367
+
368
+ msg = 'EnsureParanoidModel#destroy - expected #deleted_at to be instance of Time '
369
+ msg << "on deleted model. Debug: [#{m.inspect}]"
370
+
371
+ assert_instance_of(Time, m.deleted_at, msg)
372
+ end
373
+ end
374
+ end
375
+ # rubocop:enable Metrics/BlockLength
149
376
  end
150
-
151
-
152
- end
377
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
378
+
379
+ # Ensure that a given model is properly configured as a timestamped model
380
+ #
381
+ # This method sets up a series of tests to verify that a model
382
+ # is correctly using the aequel-timestamps plugin. It checks the behavior
383
+ # of the :created_at and :updated_at columns in various scenarios.
384
+ #
385
+ # @param model [Class] The model class to test
386
+ #
387
+ # @example Testing a timestamped model
388
+ # class Comment < Sequel::Model
389
+ # plugin :timestamps
390
+ # end
391
+ #
392
+ # describe Comment do
393
+ # ensure_timestamped_model(Comment)
394
+ # end
395
+ #
396
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
397
+ def self.ensure_timestamped_model(model)
398
+ # rubocop:disable Metrics/BlockLength
399
+ describe 'a timestamped model with .plugin(:timestamps)' do
400
+ let(:m) { model.send(:make) }
153
401
 
402
+ describe 'a new record' do
403
+ it '#:created_at should be a timestamp' do
404
+ msg = 'EnsureTimestampedModel#new - expected #created_at to be an instance of Time '
405
+ msg << "on new record. Debug: [#{m.inspect}]"
154
406
 
155
- # add support for Spec syntax
156
- module Minitest::Expectations
407
+ assert_instance_of(Time, m.created_at, msg)
408
+ end
157
409
 
158
- infect_an_assertion :assert_timestamped_model, :must_be_timestamped_model, :reverse
159
- infect_an_assertion :assert_paranoid_model, :must_be_paranoid_model, :reverse
160
- infect_an_assertion :assert_paranoid_model, :must_be_a_paranoid_model, :reverse
410
+ it '#:updated_at should be nil (empty)' do
411
+ msg = 'EnsureTimestampedModel#new - expected #updated_at to be nil on new record. '
412
+ msg << "Debug: [#{m.inspect}]"
161
413
 
162
- infect_an_assertion :refute_timestamped_model, :wont_be_timestamped_model, :reverse
163
- infect_an_assertion :refute_timestamped_model, :wont_be_a_timestamped_model, :reverse
164
- infect_an_assertion :refute_paranoid_model, :wont_be_paranoid_model, :reverse
165
- infect_an_assertion :refute_paranoid_model, :wont_be_a_paranoid_model, :reverse
414
+ assert_nil(m.updated_at, msg)
415
+ end
416
+ end
417
+
418
+ describe 'after an update' do
419
+ it '#:created_at should remain unchanged ' do
420
+ assert_instance_of(Time, m.created_at)
421
+ old_ts = m.created_at
422
+
423
+ sleep 1 # TODO: convert this with time_cop or similar one day.
424
+ m.save
425
+
426
+ msg = 'EnsureTimestampedModel#update - expected #created_at to be unchanged '
427
+ msg << "on update record. Debug: [#{m.inspect}]"
428
+
429
+ assert_equal(old_ts, m.created_at, msg)
430
+ end
431
+
432
+ it '#:updated_at should be a timestamp' do
433
+ m.save
434
+
435
+ msg = 'EnsureTimestampedModel#new - expected #updated_at to be an instance of Time '
436
+ msg << "on updated record. Debug: [#{m.inspect}]"
437
+
438
+ assert_instance_of(Time, m.updated_at, msg)
439
+ end
440
+ end
441
+ end
442
+ # rubocop:enable Metrics/BlockLength
443
+ end
444
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
166
445
  end
446
+ # rubocop:enable Style/ClassAndModuleChildren