subroutine 4.1.3 → 4.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4fef2991f9d46da2fdbe6447c7e128042e8f60d6696a562f29b38e7cab2755d
4
- data.tar.gz: 4bd93645f7a6efbbaccfe2fd3c2049b0f6b4310cd959a9f75fc6c4d7a23d8e25
3
+ metadata.gz: ced171264f2691b06090ebb341c3bb2db51ec830ff1437ac40e6e043cfa855fc
4
+ data.tar.gz: '08979c16af5ed2659919f5ba6c273f4a49945f4b646d10d7da0752bc0701547a'
5
5
  SHA512:
6
- metadata.gz: cc3b421c2c645c7ca205efa89104d16805320c3a9407ad3aa34330545d62e6037f713998bb483da8bf59934b3e2b090e5add1254fe19f04f888457d4ac12aa38
7
- data.tar.gz: ee0734400bd7df20adadbbed1e565419995dca36f66e4f7d65664dac5c9ffb0a03041dc658842e307d3520825464cae6019b0e29fa843d01641e99eb35fc3bb2
6
+ metadata.gz: c41378df7c3f4ca1964a202473c7d4ad7eea0e820c1aba9368224011c9a475d3caff781a95754778c0963912a9d518b59e3abbbf4384ef0d2208425174f3f9db
7
+ data.tar.gz: a1085fff72c585454bb2f4278bada45706546553695bd291877e21100a435cc63fb0175934d83cf3b32e6592b9a4b3a08403c49d63715ae4636d66c561ccbe4b
data/CHANGELOG.MD CHANGED
@@ -1,3 +1,13 @@
1
+ ## Subroutine 4.1.4
2
+
3
+ Fields using the time/timestamp/datetime caster will now default back to the old behavior, and use a `precision:` option to opt-in to the new behavior introduced in `v4.1.1`.
4
+
5
+ `precision: :seconds` will retain the old behavior of always parsing to a new Time object
6
+ with floored sub-second precision, but applied more forcefully than before as it would have parsed whatever you passed to it. (This is the default, now.)
7
+
8
+ `precision: :high` will now use the new functionality of re-using Time objects when they
9
+ are passed in, or if not parsing exactly the provided string as to a Time object.
10
+
1
11
  ## Subroutine 4.1.1
2
12
 
3
13
  Fields using the time/timestamp/datetime caster will now return exactly the passed in value
@@ -4,11 +4,14 @@ require 'date'
4
4
  require 'time'
5
5
  require 'bigdecimal'
6
6
  require 'securerandom'
7
+ require 'active_support/core_ext/date_time/acts_like'
8
+ require 'active_support/core_ext/date_time/calculations'
7
9
  require 'active_support/core_ext/object/acts_like'
8
10
  require 'active_support/core_ext/object/blank'
9
11
  require 'active_support/core_ext/object/try'
10
12
  require 'active_support/core_ext/array/wrap'
11
13
  require 'active_support/core_ext/time/acts_like'
14
+ require 'active_support/core_ext/time/calculations'
12
15
 
13
16
  module Subroutine
14
17
  module TypeCaster
@@ -117,13 +120,23 @@ end
117
120
  ::Date.parse(String(value))
118
121
  end
119
122
 
120
- ::Subroutine::TypeCaster.register :time, :timestamp, :datetime do |value, _options = {}|
123
+ ::Subroutine::TypeCaster.register :time, :timestamp, :datetime do |value, options = {}|
121
124
  next nil unless value.present?
122
125
 
123
- if value.try(:acts_like?, :time)
124
- value
125
- else
126
- ::Time.parse(String(value))
126
+ if options[:precision] == :high
127
+ if value.try(:acts_like?, :time)
128
+ value.to_time
129
+ else
130
+ ::Time.parse(String(value))
131
+ end
132
+ else # precision == :seconds
133
+ time = if value.try(:acts_like?, :time)
134
+ value.to_time
135
+ else
136
+ ::Time.parse(String(value))
137
+ end
138
+
139
+ time.change(usec: 0)
127
140
  end
128
141
  end
129
142
 
@@ -4,7 +4,7 @@ module Subroutine
4
4
 
5
5
  MAJOR = 4
6
6
  MINOR = 1
7
- PATCH = 3
7
+ PATCH = 4
8
8
  PRE = nil
9
9
 
10
10
  VERSION = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
@@ -269,7 +269,7 @@ module Subroutine
269
269
  assert_nil op.date_input
270
270
  end
271
271
 
272
- def test_time_inputs
272
+ def test_time_inputs__with_seconds_precision
273
273
  op.time_input = nil
274
274
  assert_nil op.time_input
275
275
 
@@ -284,22 +284,139 @@ module Subroutine
284
284
  assert_equal 0, op.time_input.min
285
285
  assert_equal 0, op.time_input.sec
286
286
 
287
+ op.time_input = ::DateTime.new(2022, 12, 22)
288
+ assert_equal ::Time, op.time_input.class
289
+ refute_equal ::DateTime, op.time_input.class
290
+
291
+ assert_equal 0, op.time_input.utc_offset
292
+ assert_equal 2022, op.time_input.year
293
+ assert_equal 12, op.time_input.month
294
+ assert_equal 22, op.time_input.day
295
+ assert_equal 0, op.time_input.hour
296
+ assert_equal 0, op.time_input.min
297
+ assert_equal 0, op.time_input.sec
298
+
287
299
  op.time_input = '2023-05-05T10:00:30.123456Z'
288
300
  assert_equal ::Time, op.time_input.class
289
301
  refute_equal ::DateTime, op.time_input.class
290
302
 
303
+ assert_equal 0, op.time_input.utc_offset
304
+ assert_equal 2023, op.time_input.year
305
+ assert_equal 5, op.time_input.month
306
+ assert_equal 5, op.time_input.day
307
+ assert_equal 10, op.time_input.hour
308
+ assert_equal 0, op.time_input.min
309
+ assert_equal 30, op.time_input.sec
310
+ assert_equal 0, op.time_input.usec
311
+
312
+ op.time_input = '2023-05-05T10:00:30Z'
313
+ assert_equal ::Time, op.time_input.class
314
+ assert_equal 0, op.time_input.utc_offset
291
315
  assert_equal 2023, op.time_input.year
292
316
  assert_equal 5, op.time_input.month
293
317
  assert_equal 5, op.time_input.day
294
318
  assert_equal 10, op.time_input.hour
295
319
  assert_equal 0, op.time_input.min
296
320
  assert_equal 30, op.time_input.sec
297
- assert_equal 123456, op.time_input.usec
321
+ assert_equal 0, op.time_input.usec
298
322
 
299
- time = Time.at(1678741605.123456)
323
+ op.time_input = '2024-11-11T16:42:23.246+0100'
324
+ assert_equal ::Time, op.time_input.class
325
+ assert_equal 3600, op.time_input.utc_offset
326
+ assert_equal 2024, op.time_input.year
327
+ assert_equal 11, op.time_input.month
328
+ assert_equal 11, op.time_input.day
329
+ assert_equal 16, op.time_input.hour
330
+ assert_equal 42, op.time_input.min
331
+ assert_equal 23, op.time_input.sec
332
+ assert_equal 0, op.time_input.usec
333
+
334
+ time = Time.at(1678741605.123456).utc
300
335
  op.time_input = time
301
- assert_equal time, op.time_input
302
- assert_equal time.object_id, op.time_input.object_id
336
+ refute_equal time, op.time_input
337
+ refute_equal time.object_id, op.time_input.object_id
338
+ assert_equal 2023, op.time_input.year
339
+ assert_equal 3, op.time_input.month
340
+ assert_equal 13, op.time_input.day
341
+ assert_equal 21, op.time_input.hour
342
+ assert_equal 6, op.time_input.min
343
+ assert_equal 45, op.time_input.sec
344
+ assert_equal 0, op.time_input.usec
345
+ end
346
+
347
+ def test_time_inputs__with_high_precision
348
+ op.precise_time_input = nil
349
+ assert_nil op.precise_time_input
350
+
351
+ op.precise_time_input = '2022-12-22'
352
+ assert_equal ::Time, op.precise_time_input.class
353
+ refute_equal ::DateTime, op.precise_time_input.class
354
+
355
+ assert_equal 2022, op.precise_time_input.year
356
+ assert_equal 12, op.precise_time_input.month
357
+ assert_equal 22, op.precise_time_input.day
358
+ assert_equal 0, op.precise_time_input.hour
359
+ assert_equal 0, op.precise_time_input.min
360
+ assert_equal 0, op.precise_time_input.sec
361
+
362
+ op.precise_time_input = ::DateTime.new(2022, 12, 22)
363
+ assert_equal ::Time, op.precise_time_input.class
364
+ refute_equal ::DateTime, op.precise_time_input.class
365
+
366
+ assert_equal 0, op.precise_time_input.utc_offset
367
+ assert_equal 2022, op.precise_time_input.year
368
+ assert_equal 12, op.precise_time_input.month
369
+ assert_equal 22, op.precise_time_input.day
370
+ assert_equal 0, op.precise_time_input.hour
371
+ assert_equal 0, op.precise_time_input.min
372
+ assert_equal 0, op.precise_time_input.sec
373
+
374
+ op.precise_time_input = '2023-05-05T10:00:30.123456Z'
375
+ assert_equal ::Time, op.precise_time_input.class
376
+ refute_equal ::DateTime, op.precise_time_input.class
377
+
378
+ assert_equal 0, op.precise_time_input.utc_offset
379
+ assert_equal 2023, op.precise_time_input.year
380
+ assert_equal 5, op.precise_time_input.month
381
+ assert_equal 5, op.precise_time_input.day
382
+ assert_equal 10, op.precise_time_input.hour
383
+ assert_equal 0, op.precise_time_input.min
384
+ assert_equal 30, op.precise_time_input.sec
385
+ assert_equal 123456, op.precise_time_input.usec
386
+
387
+ op.precise_time_input = '2023-05-05T10:00:30Z'
388
+ assert_equal ::Time, op.precise_time_input.class
389
+ assert_equal 0, op.precise_time_input.utc_offset
390
+ assert_equal 2023, op.precise_time_input.year
391
+ assert_equal 5, op.precise_time_input.month
392
+ assert_equal 5, op.precise_time_input.day
393
+ assert_equal 10, op.precise_time_input.hour
394
+ assert_equal 0, op.precise_time_input.min
395
+ assert_equal 30, op.precise_time_input.sec
396
+ assert_equal 0, op.precise_time_input.usec
397
+
398
+ op.precise_time_input = '2024-11-11T16:42:23.246+0100'
399
+ assert_equal ::Time, op.precise_time_input.class
400
+ assert_equal 3600, op.precise_time_input.utc_offset
401
+ assert_equal 2024, op.precise_time_input.year
402
+ assert_equal 11, op.precise_time_input.month
403
+ assert_equal 11, op.precise_time_input.day
404
+ assert_equal 16, op.precise_time_input.hour
405
+ assert_equal 42, op.precise_time_input.min
406
+ assert_equal 23, op.precise_time_input.sec
407
+ assert_equal 246000, op.precise_time_input.usec
408
+
409
+ time = Time.at(1678741605.123456).utc
410
+ op.precise_time_input = time
411
+ assert_equal time, op.precise_time_input
412
+ assert_equal time.object_id, op.precise_time_input.object_id
413
+ assert_equal 2023, op.precise_time_input.year
414
+ assert_equal 3, op.precise_time_input.month
415
+ assert_equal 13, op.precise_time_input.day
416
+ assert_equal 21, op.precise_time_input.hour
417
+ assert_equal 6, op.precise_time_input.min
418
+ assert_equal 45, op.precise_time_input.sec
419
+ assert_equal 123456, op.precise_time_input.usec
303
420
  end
304
421
 
305
422
  def test_iso_date_inputs
data/test/support/ops.rb CHANGED
@@ -173,6 +173,7 @@ class TypeCastOp < ::Subroutine::Op
173
173
  boolean :boolean_input
174
174
  date :date_input
175
175
  time :time_input, default: -> { Time.now }
176
+ time :precise_time_input, precision: :high
176
177
  iso_date :iso_date_input
177
178
  iso_time :iso_time_input
178
179
  object :object_input
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subroutine
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.3
4
+ version: 4.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-05 00:00:00.000000000 Z
11
+ date: 2024-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel