minitest-sequel 0.3.1 → 0.4.0

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.
@@ -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