sorbet-coerce 0.3.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3a8032d0ba46f76ce47d4ec30e3e486005028d61a06c4f1047d6691f3e995f4
4
- data.tar.gz: 6ec0fd090fbce8cb3889d69ce10bfa07b74b928425af2f9a4ca47bf60d1d1889
3
+ metadata.gz: 07b8a2f1d773bf25d7abda4c1bfc6de014a7b41c9dde01b58ff27e4aaa5952a7
4
+ data.tar.gz: ea45ba6647ed640581243698193f9c7e24520d1ab2b2dea9009bf97ddee5309b
5
5
  SHA512:
6
- metadata.gz: 4ec5337779c9eece9610d73a037662d36d2dc9e50cfc77dd2762fb323f90dcb6edca41ee1337c12074243b1a1587450753a8afce49f5923aaf4ee1f88cc0bb2b
7
- data.tar.gz: 84a9967bac7c2fb07d7c0f7530f1c4063a687019cc66e5787d0d69b1973884cf7e32d245ff2e99cb258abb963ae037f68e7dcc84c78d5c8f1b253d5b2f0b123a
6
+ metadata.gz: d4052f15f7b98b91dcbc3e1eb086dd1a8f74694f73889d04f578af0cefae29ac87fb9f5d3ddc67d275f23b98335fa9865ddd0c483aba80788c3b41ebbb1b5f3b
7
+ data.tar.gz: 7d4145c0966431329cf292c6c7347db7dfbd6db3870ef44f0d5f876ecaf0e8e4395c466c5138556bc5972d439d08947d0de245334e7e618a7324edd3eaa22418
@@ -25,12 +25,12 @@ class TypeCoerce::Converter
25
25
  "#{name}#[#{@type.to_s}]"
26
26
  end
27
27
 
28
- def from(args, raise_coercion_error: nil)
28
+ def from(args, raise_coercion_error: nil, coerce_empty_to_nil: false)
29
29
  if raise_coercion_error.nil?
30
30
  raise_coercion_error = TypeCoerce::Configuration.raise_coercion_error
31
31
  end
32
32
 
33
- T.let(_convert(args, @type, raise_coercion_error), @type)
33
+ T.let(_convert(args, @type, raise_coercion_error, coerce_empty_to_nil), @type)
34
34
  end
35
35
 
36
36
  private
@@ -45,15 +45,19 @@ class TypeCoerce::Converter
45
45
  Time,
46
46
  ], T.untyped)
47
47
 
48
- def _convert(value, type, raise_coercion_error)
48
+ def _convert(value, type, raise_coercion_error, coerce_empty_to_nil)
49
49
  if type.is_a?(T::Types::Untyped)
50
50
  value
51
+ elsif type.is_a?(T::Types::ClassOf)
52
+ value
51
53
  elsif type.is_a?(T::Types::TypedArray)
52
- _convert_to_a(value, type.type, raise_coercion_error)
54
+ _convert_to_a(value, type.type, raise_coercion_error, coerce_empty_to_nil)
55
+ elsif type.is_a?(T::Types::FixedArray)
56
+ _convert_to_a(value, type.types, raise_coercion_error, coerce_empty_to_nil)
53
57
  elsif type.is_a?(T::Types::TypedSet)
54
- Set.new(_convert_to_a(value, type.type, raise_coercion_error))
58
+ Set.new(_convert_to_a(value, type.type, raise_coercion_error, coerce_empty_to_nil))
55
59
  elsif type.is_a?(T::Types::Simple)
56
- _convert(value, type.raw_type, raise_coercion_error)
60
+ _convert(value, type.raw_type, raise_coercion_error, coerce_empty_to_nil)
57
61
  elsif type.is_a?(T::Types::Union)
58
62
  true_idx = T.let(nil, T.nilable(Integer))
59
63
  false_idx = T.let(nil, T.nilable(Integer))
@@ -65,9 +69,7 @@ class TypeCoerce::Converter
65
69
  false_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == FalseClass
66
70
  end
67
71
 
68
- raise ArgumentError.new(
69
- 'the only supported union types are T.nilable and T::Boolean',
70
- ) unless (
72
+ return value unless (
71
73
  (!true_idx.nil? && !false_idx.nil? && !nil_idx.nil?) || # T.nilable(T::Boolean)
72
74
  (type.types.length == 2 && (
73
75
  !nil_idx.nil? || (!true_idx.nil? && !false_idx.nil?) # T.nilable || T::Boolean
@@ -75,12 +77,12 @@ class TypeCoerce::Converter
75
77
  )
76
78
 
77
79
  if !true_idx.nil? && !false_idx.nil?
78
- _convert_simple(value, T::Boolean, raise_coercion_error)
80
+ _convert_simple(value, T::Boolean, raise_coercion_error, coerce_empty_to_nil)
79
81
  else
80
- _convert(value, type.types[nil_idx == 0 ? 1 : 0], raise_coercion_error)
82
+ _convert(value, type.types[nil_idx == 0 ? 1 : 0], raise_coercion_error, coerce_empty_to_nil)
81
83
  end
82
84
  elsif type.is_a?(T::Types::TypedHash)
83
- return {} if _nil_like?(value, type)
85
+ return {} if _nil_like?(value, type, coerce_empty_to_nil)
84
86
 
85
87
  unless value.respond_to?(:map)
86
88
  raise TypeCoerce::ShapeError.new(value, type)
@@ -88,30 +90,34 @@ class TypeCoerce::Converter
88
90
 
89
91
  value.map do |k, v|
90
92
  [
91
- _convert(k, type.keys, raise_coercion_error),
92
- _convert(v, type.values, raise_coercion_error),
93
+ _convert(k, type.keys, raise_coercion_error, coerce_empty_to_nil),
94
+ _convert(v, type.values, raise_coercion_error, coerce_empty_to_nil),
93
95
  ]
94
96
  end.to_h
95
97
  elsif Object.const_defined?('T::Private::Types::TypeAlias') &&
96
98
  type.is_a?(T::Private::Types::TypeAlias)
97
- _convert(value, type.aliased_type, raise_coercion_error)
98
- elsif type.respond_to?(:<) && type < T::Struct
99
- return value if value.is_a?(type)
100
-
101
- args = _build_args(value, type, raise_coercion_error)
102
- type.new(args)
103
- elsif type.respond_to?(:<) && type < T::Enum
104
- return value if value.is_a?(type)
105
-
106
- _convert_enum(value, type, raise_coercion_error)
99
+ _convert(value, type.aliased_type, raise_coercion_error, coerce_empty_to_nil)
100
+ elsif type.is_a?(Class) || type.is_a?(Module)
101
+ return coerce_nil(value, type, coerce_empty_to_nil) if value.is_a?(type)
102
+
103
+ if type < T::Struct
104
+ args = _build_args(value, type, raise_coercion_error, coerce_empty_to_nil)
105
+ type.new(args)
106
+ elsif type < T::Enum
107
+ _convert_enum(value, type, raise_coercion_error, coerce_empty_to_nil)
108
+ else
109
+ _convert_simple(value, type, raise_coercion_error, coerce_empty_to_nil)
110
+ end
107
111
  else
108
- return value if value.is_a?(type)
109
-
110
- _convert_simple(value, type, raise_coercion_error)
112
+ if raise_coercion_error
113
+ raise TypeCoerce::CoercionError.new(value, type)
114
+ else
115
+ value
116
+ end
111
117
  end
112
118
  end
113
119
 
114
- def _convert_enum(value, type, raise_coercion_error)
120
+ def _convert_enum(value, type, raise_coercion_error, coerce_empty_to_nil)
115
121
  if raise_coercion_error
116
122
  type.deserialize(value)
117
123
  else
@@ -121,8 +127,8 @@ class TypeCoerce::Converter
121
127
  raise TypeCoerce::CoercionError.new(value, type)
122
128
  end
123
129
 
124
- def _convert_simple(value, type, raise_coercion_error)
125
- return nil if _nil_like?(value, type)
130
+ def _convert_simple(value, type, raise_coercion_error, coerce_empty_to_nil)
131
+ return nil if _nil_like?(value, type, coerce_empty_to_nil)
126
132
 
127
133
  safe_type_rule = T.let(nil, T.untyped)
128
134
 
@@ -130,6 +136,8 @@ class TypeCoerce::Converter
130
136
  safe_type_rule = SafeType::Boolean.strict
131
137
  elsif value.is_a?(type)
132
138
  return value
139
+ elsif type == BigDecimal
140
+ return BigDecimal(value)
133
141
  elsif PRIMITIVE_TYPES.include?(type)
134
142
  safe_type_rule = SafeType.const_get(type.name).strict
135
143
  else
@@ -149,18 +157,24 @@ class TypeCoerce::Converter
149
157
  end
150
158
  end
151
159
 
152
- def _convert_to_a(ary, type, raise_coercion_error)
153
- return [] if _nil_like?(ary, type)
160
+ def _convert_to_a(ary, type, raise_coercion_error, coerce_empty_to_nil)
161
+ return [] if _nil_like?(ary, type, coerce_empty_to_nil)
154
162
 
155
163
  unless ary.respond_to?(:map)
156
164
  raise TypeCoerce::ShapeError.new(ary, type)
157
165
  end
158
166
 
159
- ary.map { |value| _convert(value, type, raise_coercion_error) }
167
+ ary.map.with_index do |value, i|
168
+ if type.is_a?(Array)
169
+ _convert(value, type[i], raise_coercion_error, coerce_empty_to_nil)
170
+ else
171
+ _convert(value, type, raise_coercion_error, coerce_empty_to_nil)
172
+ end
173
+ end
160
174
  end
161
175
 
162
- def _build_args(args, type, raise_coercion_error)
163
- return {} if _nil_like?(args, Hash)
176
+ def _build_args(args, type, raise_coercion_error, coerce_empty_to_nil)
177
+ return {} if _nil_like?(args, Hash, coerce_empty_to_nil)
164
178
 
165
179
  unless args.respond_to?(:each_pair)
166
180
  raise TypeCoerce::ShapeError.new(args, type)
@@ -172,12 +186,22 @@ class TypeCoerce::Converter
172
186
  [
173
187
  key,
174
188
  (!props.include?(key) || value.nil?) ?
175
- nil : _convert(value, props[key][:type], raise_coercion_error),
189
+ nil : _convert(value, props[key][:type], raise_coercion_error, coerce_empty_to_nil),
176
190
  ]
177
191
  }.to_h.slice(*props.keys)
178
192
  end
179
193
 
180
- def _nil_like?(value, type)
181
- value.nil? || (value == '' && type != String)
194
+ def _nil_like?(value, type, coerce_empty_to_nil)
195
+ return true if value.nil?
196
+ return true if value == '' && coerce_empty_to_nil
197
+ return true if value == '' && type != String
198
+
199
+ false
200
+ end
201
+
202
+ def coerce_nil(value, type, coerce_empty_to_nil)
203
+ return nil if _nil_like?(value, type, coerce_empty_to_nil)
204
+
205
+ value
182
206
  end
183
207
  end
data/spec/coerce_spec.rb CHANGED
@@ -19,6 +19,7 @@ describe TypeCoerce do
19
19
  class Param < T::Struct
20
20
  const :id, Integer
21
21
  const :role, String, default: 'wizard'
22
+ const :price, BigDecimal
22
23
  const :info, ParamInfo
23
24
  const :opt, T.nilable(ParamInfo2)
24
25
  end
@@ -46,6 +47,14 @@ describe TypeCoerce do
46
47
  const :myenum, TestEnum
47
48
  end
48
49
 
50
+ class WithNilableString < T::Struct
51
+ const :myvalue, T.nilable(String)
52
+ end
53
+
54
+ class WithNilableInteger < T::Struct
55
+ const :myvalue, T.nilable(Integer)
56
+ end
57
+
49
58
  class CustomType
50
59
  attr_reader :a
51
60
 
@@ -62,9 +71,26 @@ describe TypeCoerce do
62
71
  # Does not respond to new
63
72
  end
64
73
 
74
+ class WithSupportedUnion < T::Struct
75
+ const :nilable, T.nilable(String)
76
+ const :nilable_boolean, T.nilable(T::Boolean)
77
+ end
78
+
79
+ class WithUnsupportedUnion < T::Struct
80
+ const :union, T.any(String, Integer)
81
+ end
82
+
83
+ class WithFixedArray < T::Struct
84
+ const :arr, [Integer, String, Integer]
85
+ end
86
+
87
+ class CustomString < String
88
+ end
89
+
65
90
  let!(:param) {
66
91
  TypeCoerce[Param].new.from({
67
92
  id: 1,
93
+ price: BigDecimal('98.76'),
68
94
  info: {
69
95
  name: 'mango',
70
96
  lvl: 100,
@@ -81,6 +107,7 @@ describe TypeCoerce do
81
107
  let!(:param2) {
82
108
  TypeCoerce[Param].new.from({
83
109
  id: '2',
110
+ price: '98.76',
84
111
  info: {
85
112
  name: 'honeydew',
86
113
  lvl: '5',
@@ -97,6 +124,7 @@ describe TypeCoerce do
97
124
  it 'reveals the right type' do
98
125
  T.assert_type!(param, Param)
99
126
  T.assert_type!(param.id, Integer)
127
+ T.assert_type!(param.price, BigDecimal)
100
128
  T.assert_type!(param.info, ParamInfo)
101
129
  T.assert_type!(param.info.name,String)
102
130
  T.assert_type!(param.info.lvl, Integer)
@@ -106,6 +134,7 @@ describe TypeCoerce do
106
134
  it 'coerces correctly' do
107
135
  expect(param.id).to eql 1
108
136
  expect(param.role).to eql 'wizard'
137
+ expect(param.price).to eql BigDecimal('98.76')
109
138
  expect(param.info.lvl).to eql 100
110
139
  expect(param.info.name).to eql 'mango'
111
140
  expect(param.info.skill_ids).to eql [123, 456]
@@ -113,6 +142,7 @@ describe TypeCoerce do
113
142
  expect(TypeCoerce[Param].new.from(param)).to eq(param)
114
143
 
115
144
  expect(param2.id).to eql 2
145
+ expect(param2.price).to eql BigDecimal('98.76')
116
146
  expect(param2.info.name).to eql 'honeydew'
117
147
  expect(param2.info.lvl).to eql 5
118
148
  expect(param2.info.skill_ids).to eql []
@@ -138,12 +168,12 @@ describe TypeCoerce do
138
168
  context 'when the given T::Struct is invalid' do
139
169
  class Param2 < T::Struct
140
170
  const :id, Integer
141
- const :info, T.any(Integer, String)
171
+ const :param, Param
142
172
  end
143
173
 
144
174
  it 'raises an error' do
145
175
  expect {
146
- TypeCoerce[Param2].new.from({id: 1, info: 1})
176
+ TypeCoerce[Param2].new.from({id: 1, info: {}})
147
177
  }.to raise_error(ArgumentError)
148
178
  end
149
179
  end
@@ -186,7 +216,34 @@ describe TypeCoerce do
186
216
  end
187
217
  end
188
218
 
189
- context 'when dealing with arries' do
219
+ context 'when given union types' do
220
+ context 'supported union types' do
221
+ it 'coerces correctly' do
222
+ coerced = TypeCoerce[WithSupportedUnion].new.from({
223
+ nilable: 2,
224
+ nilable_boolean: 'true'
225
+ })
226
+ expect(coerced.nilable).to eq('2')
227
+ expect(coerced.nilable_boolean).to eq(true)
228
+ end
229
+ end
230
+
231
+ context 'unsupported union types' do
232
+ it 'keeps the values as-is' do
233
+ coerced = TypeCoerce[WithUnsupportedUnion].new.from({union: 'a'})
234
+ expect(coerced.union).to eq('a')
235
+
236
+ coerced = TypeCoerce[WithUnsupportedUnion].new.from({union: 2})
237
+ expect(coerced.union).to eq(2)
238
+
239
+ expect do
240
+ TypeCoerce[WithUnsupportedUnion].new.from({union: nil})
241
+ end.to raise_error(TypeError)
242
+ end
243
+ end
244
+ end
245
+
246
+ context 'when dealing with arrays' do
190
247
  it 'coreces correctly' do
191
248
  expect(TypeCoerce[T::Array[Integer]].new.from(nil)).to eql []
192
249
  expect(TypeCoerce[T::Array[Integer]].new.from('')).to eql []
@@ -267,18 +324,18 @@ describe TypeCoerce do
267
324
 
268
325
  context 'when dealing with enums' do
269
326
  it 'coerces a serialized enum correctly' do
270
- coerced = TypeCoerce[WithEnum].new.from(myenum: "test")
327
+ coerced = TypeCoerce[WithEnum].new.from({myenum: "test"})
271
328
  expect(coerced.myenum).to eq(TestEnum::Test)
272
329
  end
273
330
 
274
331
  it 'handles a real enum correctly' do
275
- coerced = TypeCoerce[WithEnum].new.from(myenum: TestEnum::Test)
332
+ coerced = TypeCoerce[WithEnum].new.from({myenum: TestEnum::Test})
276
333
  expect(coerced.myenum).to eq(TestEnum::Test)
277
334
  end
278
335
 
279
336
  it 'handles bad enum' do
280
337
  expect {
281
- TypeCoerce[WithEnum].new.from(myenum: "bad_key")
338
+ TypeCoerce[WithEnum].new.from({myenum: "bad_key"})
282
339
  }.to raise_error(TypeCoerce::CoercionError)
283
340
  end
284
341
  end
@@ -289,4 +346,68 @@ describe TypeCoerce do
289
346
  obj = CustomType.new(1)
290
347
  expect(TypeCoerce[T::Hash[String, T.untyped]].new.from({a: obj})).to eq({'a' => obj})
291
348
  end
349
+
350
+ it 'works with T::Types::FixedArray' do
351
+ type = T.type_alias { [Integer, String, Integer] }
352
+ coerced = TypeCoerce[type].new.from(['1', 2, '3'])
353
+ expect(coerced).to eql([1, '2', 3])
354
+
355
+ coerced = TypeCoerce[WithFixedArray].new.from({ arr: ['1', 2, '3'] })
356
+ expect(coerced.arr).to eql([1, '2', 3])
357
+ end
358
+
359
+ context 'when dealing with T.class_of' do
360
+ it 'keeps the value as-is' do
361
+ string_class_type = T.class_of(String)
362
+ expect(TypeCoerce[string_class_type].new.from(String)).to eql(String)
363
+ expect(TypeCoerce[string_class_type].new.from(CustomString)).to eql(CustomString)
364
+ expect do
365
+ TypeCoerce[string_class_type].new.from(Integer)
366
+ end.to raise_error(TypeError)
367
+ expect do
368
+ TypeCoerce[string_class_type].new.from('a')
369
+ end.to raise_error(TypeError)
370
+ end
371
+ end
372
+
373
+ context 'when dealing with unknown types' do
374
+ context 'raise_coercion_error is enabled' do
375
+ it 'raises error' do
376
+ expect do
377
+ TypeCoerce['a'].new.from('a', raise_coercion_error: true)
378
+ end.to raise_error(TypeCoerce::CoercionError)
379
+ end
380
+ end
381
+ context 'raise_coercion_error is disabled' do
382
+ it 'keeps the value as-is (and let Sorbet raise error)' do
383
+ expect do
384
+ TypeCoerce['a'].new.from('a', raise_coercion_error: false)
385
+ end.to raise_error(/must be an T::Types::Base/i)
386
+ end
387
+ end
388
+ end
389
+
390
+ context 'when dealing with coercing empty strings' do
391
+ context 'when flag is set' do
392
+ it 'coerces empty strings to nil from a simple type' do
393
+ expect(TypeCoerce[T.nilable(String)].new.from('', coerce_empty_to_nil: true)).to be_nil
394
+ end
395
+
396
+ it 'coerces empty strings to nil from a struct' do
397
+ coerced = TypeCoerce[WithNilableString].new.from({myvalue: ''}, coerce_empty_to_nil: true)
398
+ expect(coerced.myvalue).to eql(nil)
399
+ end
400
+ end
401
+
402
+ context 'when flag is not set' do
403
+ it 'coerces empty strings to nil from a simple type' do
404
+ expect(TypeCoerce[T.nilable(String)].new.from('', coerce_empty_to_nil: false)).to eql('')
405
+ end
406
+
407
+ it 'coerces empty strings to nil from a struct' do
408
+ coerced = TypeCoerce[WithNilableString].new.from({myvalue: ''}, coerce_empty_to_nil: false)
409
+ expect(coerced.myvalue).to eql('')
410
+ end
411
+ end
412
+ end
292
413
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: false
2
2
  require 'sorbet-coerce'
3
3
 
4
4
  T.assert_type!(TypeCoerce[Integer].new.from('1'), Integer)
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,10 @@
1
1
  # typed: strict
2
- require 'byebug'
3
- require 'simplecov'
2
+ require "byebug"
3
+ require "simplecov"
4
+ require "simplecov-cobertura"
4
5
 
5
6
  SimpleCov.start
6
-
7
- if ENV['CI'] == 'true'
8
- require 'codecov'
9
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
10
- end
7
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
11
8
 
12
9
  RSpec.configure do |config|
13
10
  config.expect_with(:rspec) { |c| c.syntax = :expect }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-coerce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chan Zuckerberg Initiative
@@ -10,20 +10,6 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: sorbet
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 0.4.4704
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: 0.4.4704
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: polyfill
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -73,43 +59,57 @@ dependencies:
73
59
  - !ruby/object:Gem::Version
74
60
  version: 0.4.4704
75
61
  - !ruby/object:Gem::Dependency
76
- name: rspec
62
+ name: sorbet
77
63
  requirement: !ruby/object:Gem::Requirement
78
64
  requirements:
79
65
  - - ">="
80
66
  - !ruby/object:Gem::Version
81
- version: '3.8'
67
+ version: 0.4.4704
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 0.4.4704
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
82
79
  - - "~>"
83
80
  - !ruby/object:Gem::Version
84
81
  version: '3.8'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '3.8'
85
85
  type: :development
86
86
  prerelease: false
87
87
  version_requirements: !ruby/object:Gem::Requirement
88
88
  requirements:
89
- - - ">="
89
+ - - "~>"
90
90
  - !ruby/object:Gem::Version
91
91
  version: '3.8'
92
- - - "~>"
92
+ - - ">="
93
93
  - !ruby/object:Gem::Version
94
94
  version: '3.8'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: byebug
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - ">="
99
+ - - "~>"
100
100
  - !ruby/object:Gem::Version
101
101
  version: 11.0.1
102
- - - "~>"
102
+ - - ">="
103
103
  - !ruby/object:Gem::Version
104
104
  version: 11.0.1
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ">="
109
+ - - "~>"
110
110
  - !ruby/object:Gem::Version
111
111
  version: 11.0.1
112
- - - "~>"
112
+ - - ">="
113
113
  - !ruby/object:Gem::Version
114
114
  version: 11.0.1
115
115
  description:
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
146
  - !ruby/object:Gem::Version
147
147
  version: '0'
148
148
  requirements: []
149
- rubygems_version: 3.0.8
149
+ rubygems_version: 3.1.6
150
150
  signing_key:
151
151
  specification_version: 4
152
152
  summary: A type coercion lib works with Sorbet's static type checker and type definitions;