sinclair 1.14.1 → 1.15.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/README.md +37 -18
- data/config/yardstick.yml +10 -0
- data/lib/sinclair/caster/class_methods.rb +127 -0
- data/lib/sinclair/caster.rb +381 -0
- data/lib/sinclair/class_methods.rb +41 -0
- data/lib/sinclair/config_class.rb +4 -10
- data/lib/sinclair/method_definition/stringifier.rb +9 -7
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +38 -21
- data/spec/integration/readme/sinclair/types_of_definition_spec.rb +8 -8
- data/spec/integration/yard/my_builder_spec.rb +8 -14
- data/spec/integration/yard/sinclair/add_method_spec.rb +11 -10
- data/spec/integration/yard/sinclair/caster/cast_spec.rb +57 -0
- data/spec/integration/yard/sinclair/caster/cast_with_spec.rb +54 -0
- data/spec/integration/yard/sinclair/caster/caster_for_spec.rb +16 -0
- data/spec/integration/yard/sinclair/caster/class_methods_spec.rb +17 -0
- data/spec/integration/yard/sinclair/class_methods/build_spec.rb +23 -0
- data/spec/integration/yard/sinclair/config_builder_spec.rb +6 -8
- data/spec/integration/yard/sinclair/config_class_spec.rb +7 -21
- data/spec/integration/yard/sinclair_spec.rb +14 -33
- data/spec/lib/sinclair/caster/class_methods_spec.rb +186 -0
- data/spec/lib/sinclair/caster_spec.rb +75 -0
- data/spec/lib/sinclair/class_methods_spec.rb +38 -0
- data/spec/support/models/enum_caster.rb +6 -0
- data/spec/support/models/enum_converter.rb +27 -0
- data/spec/support/models/hash_model.rb +11 -0
- data/spec/support/models/hash_person.rb +11 -0
- data/spec/support/models/http_json_model.rb +4 -6
- data/spec/support/models/math_caster.rb +17 -0
- data/spec/support/models/ruby_string_caster.rb +14 -0
- data/spec/support/models/string_parser.rb +9 -0
- metadata +20 -2
@@ -0,0 +1,186 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Caster::ClassMethods do
|
6
|
+
subject(:caster) { Class.new(Sinclair::Caster) }
|
7
|
+
|
8
|
+
describe '.cast_with' do
|
9
|
+
let(:value) { instance_double('value', to_p: final_value) }
|
10
|
+
let(:final_value) { Random.rand(100) }
|
11
|
+
|
12
|
+
context 'when a proc is given' do
|
13
|
+
it do
|
14
|
+
expect { caster.cast_with(:problem, &:to_p) }
|
15
|
+
.not_to raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when casting is called' do
|
19
|
+
before { caster.cast_with(:problem, &:to_p) }
|
20
|
+
|
21
|
+
it 'returns the cast value' do
|
22
|
+
expect(caster.cast(value, :problem)).to eq(final_value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when a proc with two arguments is given' do
|
28
|
+
it do
|
29
|
+
expect { caster.cast_with(:problem) { |v, **_opts| v.to_p } }
|
30
|
+
.not_to raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when casting is called' do
|
34
|
+
before { caster.cast_with(:problem) { |v, sum:| v.to_p + sum } }
|
35
|
+
|
36
|
+
it 'returns the cast value' do
|
37
|
+
expect(caster.cast(value, :problem, sum: 2))
|
38
|
+
.to eq(final_value + 2)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when a symbol is given' do
|
44
|
+
let(:instance) { Sinclair::Caster.new(&:to_p) }
|
45
|
+
|
46
|
+
it do
|
47
|
+
expect { caster.cast_with(:problem, instance) }
|
48
|
+
.not_to raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when casting is called' do
|
52
|
+
before { caster.cast_with(:problem, instance) }
|
53
|
+
|
54
|
+
it 'returns the cast value' do
|
55
|
+
expect(caster.cast(value, :problem)).to eq(final_value)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when a caster is given is given' do
|
61
|
+
it do
|
62
|
+
expect { caster.cast_with(:problem, :to_p) }
|
63
|
+
.not_to raise_error
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when casting is called' do
|
67
|
+
before { caster.cast_with(:problem, :to_p) }
|
68
|
+
|
69
|
+
it 'returns the cast value' do
|
70
|
+
expect(caster.cast(value, :problem)).to eq(final_value)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when key is a class' do
|
76
|
+
it do
|
77
|
+
expect { caster.cast_with(Integer, :to_i) }
|
78
|
+
.not_to raise_error
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when casting is called' do
|
82
|
+
before { caster.cast_with(Integer, :to_i) }
|
83
|
+
|
84
|
+
it 'returns the cast value' do
|
85
|
+
expect(caster.cast('10', Integer)).to eq(10)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when key is a module' do
|
91
|
+
it do
|
92
|
+
expect { caster.cast_with(JSON) { |value| JSON.parse(value) } }
|
93
|
+
.not_to raise_error
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when casting is called' do
|
97
|
+
before { caster.cast_with(JSON) { |value| JSON.parse(value) } }
|
98
|
+
|
99
|
+
it 'returns the cast value' do
|
100
|
+
expect(caster.cast('{"key":"value"}', JSON))
|
101
|
+
.to eq({ 'key' => 'value' })
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when key is a superclass' do
|
107
|
+
it do
|
108
|
+
expect { caster.cast_with(Numeric, :to_i) }
|
109
|
+
.not_to raise_error
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when casting is called with the child class' do
|
113
|
+
before { caster.cast_with(Numeric, :to_i) }
|
114
|
+
|
115
|
+
it 'returns the cast value' do
|
116
|
+
expect(caster.cast('10', Integer)).to eq(10)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '.caster_for' do
|
123
|
+
context 'when the key has been defined with a symbol key' do
|
124
|
+
before { caster.cast_with(:problem, :to_p) }
|
125
|
+
|
126
|
+
it do
|
127
|
+
expect(caster.caster_for(:problem))
|
128
|
+
.to be_a(Sinclair::Caster)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when the key has not been defined' do
|
133
|
+
it do
|
134
|
+
expect(caster.caster_for(:problem))
|
135
|
+
.to be_a(Sinclair::Caster)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '.cast' do
|
141
|
+
let(:value) { values.sample }
|
142
|
+
let(:values) do
|
143
|
+
[Random.rand, 'some string', { key: 10 }, Object.new, Class.new, [2, 3]]
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when klass is nil' do
|
147
|
+
it 'returns the value' do
|
148
|
+
expect(caster.cast(value, nil))
|
149
|
+
.to eq(value)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'when class is :string' do
|
154
|
+
it 'returns the value as string' do
|
155
|
+
expect(caster.cast(value, :string))
|
156
|
+
.to eq(value.to_s)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when class is :integer' do
|
161
|
+
let(:value) { '10.5' }
|
162
|
+
|
163
|
+
it 'returns the value as integer' do
|
164
|
+
expect(caster.cast(value, :integer))
|
165
|
+
.to eq(10)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'when class is :float' do
|
170
|
+
let(:value) { '10.5' }
|
171
|
+
|
172
|
+
it 'returns the value as float' do
|
173
|
+
expect(caster.cast(value, :float))
|
174
|
+
.to eq(10.5)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '.master_caster!' do
|
180
|
+
it 'ignores superclass registered casters' do
|
181
|
+
expect { caster.master_caster! }
|
182
|
+
.to change { caster.cast('10', :integer) }
|
183
|
+
.from(10).to('10')
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Caster do
|
6
|
+
subject(:caster) { caster_class.new(&method_name) }
|
7
|
+
|
8
|
+
let(:caster_class) { Class.new(described_class) }
|
9
|
+
|
10
|
+
describe '.cast' do
|
11
|
+
context 'when no options are given and the block accepts none' do
|
12
|
+
let(:method_name) { :to_s }
|
13
|
+
|
14
|
+
it 'uses the block to transform the value' do
|
15
|
+
expect(caster.cast(10)).to eq('10')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when options are given and the block accepts none' do
|
20
|
+
let(:method_name) { :to_i }
|
21
|
+
|
22
|
+
it 'uses the block to transform the value' do
|
23
|
+
expect(caster.cast('10', extra: true)).to eq(10)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when no options are given and the block accepts options' do
|
28
|
+
subject(:caster) do
|
29
|
+
caster_class.new do |value, sum: 5|
|
30
|
+
(value.to_i + sum).to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'uses the block to transform the value' do
|
35
|
+
expect(caster.cast('10')).to eq('15')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when options are given and the block accepts options' do
|
40
|
+
subject(:caster) do
|
41
|
+
caster_class.new do |value, sum:|
|
42
|
+
(value.to_i + sum).to_s
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'uses the options in the block' do
|
47
|
+
expect(caster.cast('10', sum: 5)).to eq('15')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when no options are given and the block requires options' do
|
52
|
+
subject(:caster) do
|
53
|
+
caster_class.new do |value, sum:|
|
54
|
+
(value.to_i + sum).to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it do
|
59
|
+
expect { caster.cast('10') }.to raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when extra options are given and the block accepts options' do
|
64
|
+
subject(:caster) do
|
65
|
+
caster_class.new do |value, sum:|
|
66
|
+
(value.to_i + sum).to_s
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'ignores extra options' do
|
71
|
+
expect(caster.cast('10', sum: 5, extra: true)).to eq('15')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::ClassMethods do
|
6
|
+
subject(:builder) { builder_class.new(dummy_class, options) }
|
7
|
+
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:instance) { dummy_class.new }
|
10
|
+
let(:dummy_class) { Class.new }
|
11
|
+
let(:builder_class) { Sinclair }
|
12
|
+
|
13
|
+
describe '#build' do
|
14
|
+
let(:block) do
|
15
|
+
method_name = :some_method
|
16
|
+
value = 1
|
17
|
+
|
18
|
+
proc do
|
19
|
+
add_method(method_name) { value }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'executes the block and builds' do
|
24
|
+
expect { builder_class.build(dummy_class, options, &block) }
|
25
|
+
.to add_method(:some_method).to(dummy_class)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the method is built and called' do
|
29
|
+
before do
|
30
|
+
builder_class.build(dummy_class, options, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns the value' do
|
34
|
+
expect(instance.some_method).to eq(1)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
module EnumConverter
|
4
|
+
class << self
|
5
|
+
def to_hash(value)
|
6
|
+
return value if value.is_a?(Hash)
|
7
|
+
|
8
|
+
hash_caster.cast(value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_array(value)
|
12
|
+
return value if value.is_a?(Array)
|
13
|
+
|
14
|
+
array_caster.cast(value)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def hash_caster
|
20
|
+
@hash_caster ||= EnumCaster.caster_for(:hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
def array_caster
|
24
|
+
@array_caster ||= EnumCaster.caster_for(:array)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -5,15 +5,13 @@ class HttpJsonModel
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def parse(attribute, path: [])
|
8
|
-
builder = Sinclair.new(self)
|
9
|
-
|
10
8
|
keys = (path + [attribute]).map(&:to_s)
|
11
9
|
|
12
|
-
|
13
|
-
|
10
|
+
Sinclair.build(self) do
|
11
|
+
add_method(attribute) do
|
12
|
+
keys.inject(hash) { |h, key| h[key] }
|
13
|
+
end
|
14
14
|
end
|
15
|
-
|
16
|
-
builder.build
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MathCaster < Sinclair::Caster
|
4
|
+
cast_with(:float, :to_f)
|
5
|
+
|
6
|
+
cast_with(:log) do |value, base: 10|
|
7
|
+
value = MathCaster.cast(value, :float)
|
8
|
+
|
9
|
+
Math.log(value, base)
|
10
|
+
end
|
11
|
+
|
12
|
+
cast_with(:exp) do |value, base: 10|
|
13
|
+
value = MathCaster.cast(value, :float)
|
14
|
+
|
15
|
+
base**value
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RubyStringCaster < Sinclair::Caster
|
4
|
+
master_caster!
|
5
|
+
|
6
|
+
cast_with(NilClass) { 'nil' }
|
7
|
+
cast_with(Symbol) { |value| ":#{value}" }
|
8
|
+
cast_with(String, :to_json)
|
9
|
+
cast_with(Object, :to_s)
|
10
|
+
|
11
|
+
def self.to_ruby_string(value)
|
12
|
+
cast(value, value.class)
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinclair
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DarthJee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -273,6 +273,9 @@ files:
|
|
273
273
|
- config/yardstick.yml
|
274
274
|
- docker-compose.yml
|
275
275
|
- lib/sinclair.rb
|
276
|
+
- lib/sinclair/caster.rb
|
277
|
+
- lib/sinclair/caster/class_methods.rb
|
278
|
+
- lib/sinclair/class_methods.rb
|
276
279
|
- lib/sinclair/comparable.rb
|
277
280
|
- lib/sinclair/comparable/class_methods.rb
|
278
281
|
- lib/sinclair/config.rb
|
@@ -338,6 +341,11 @@ files:
|
|
338
341
|
- spec/integration/yard/my_builder_spec.rb
|
339
342
|
- spec/integration/yard/sinclair/add_class_method_spec.rb
|
340
343
|
- spec/integration/yard/sinclair/add_method_spec.rb
|
344
|
+
- spec/integration/yard/sinclair/caster/cast_spec.rb
|
345
|
+
- spec/integration/yard/sinclair/caster/cast_with_spec.rb
|
346
|
+
- spec/integration/yard/sinclair/caster/caster_for_spec.rb
|
347
|
+
- spec/integration/yard/sinclair/caster/class_methods_spec.rb
|
348
|
+
- spec/integration/yard/sinclair/class_methods/build_spec.rb
|
341
349
|
- spec/integration/yard/sinclair/comparable_spec.rb
|
342
350
|
- spec/integration/yard/sinclair/config_builder_spec.rb
|
343
351
|
- spec/integration/yard/sinclair/config_class_spec.rb
|
@@ -359,6 +367,9 @@ files:
|
|
359
367
|
- spec/integration/yard/sinclair/options_parser_spec.rb
|
360
368
|
- spec/integration/yard/sinclair/options_spec.rb
|
361
369
|
- spec/integration/yard/sinclair_spec.rb
|
370
|
+
- spec/lib/sinclair/caster/class_methods_spec.rb
|
371
|
+
- spec/lib/sinclair/caster_spec.rb
|
372
|
+
- spec/lib/sinclair/class_methods_spec.rb
|
362
373
|
- spec/lib/sinclair/comparable_spec.rb
|
363
374
|
- spec/lib/sinclair/config/methods_builder_spec.rb
|
364
375
|
- spec/lib/sinclair/config_builder_spec.rb
|
@@ -417,7 +428,11 @@ files:
|
|
417
428
|
- spec/support/models/dummy_config.rb
|
418
429
|
- spec/support/models/dummy_configurable.rb
|
419
430
|
- spec/support/models/dummy_options_parser.rb
|
431
|
+
- spec/support/models/enum_caster.rb
|
432
|
+
- spec/support/models/enum_converter.rb
|
420
433
|
- spec/support/models/env_settings.rb
|
434
|
+
- spec/support/models/hash_model.rb
|
435
|
+
- spec/support/models/hash_person.rb
|
421
436
|
- spec/support/models/host_config.rb
|
422
437
|
- spec/support/models/http_json_model.rb
|
423
438
|
- spec/support/models/http_person.rb
|
@@ -426,6 +441,7 @@ files:
|
|
426
441
|
- spec/support/models/job.rb
|
427
442
|
- spec/support/models/login_config.rb
|
428
443
|
- spec/support/models/login_configurable.rb
|
444
|
+
- spec/support/models/math_caster.rb
|
429
445
|
- spec/support/models/my_app_client.rb
|
430
446
|
- spec/support/models/my_builder.rb
|
431
447
|
- spec/support/models/my_class.rb
|
@@ -438,9 +454,11 @@ files:
|
|
438
454
|
- spec/support/models/person.rb
|
439
455
|
- spec/support/models/purchase.rb
|
440
456
|
- spec/support/models/random_generator.rb
|
457
|
+
- spec/support/models/ruby_string_caster.rb
|
441
458
|
- spec/support/models/server.rb
|
442
459
|
- spec/support/models/server_config.rb
|
443
460
|
- spec/support/models/service_client.rb
|
461
|
+
- spec/support/models/string_parser.rb
|
444
462
|
- spec/support/models/tv.rb
|
445
463
|
- spec/support/models/validator_builder.rb
|
446
464
|
- spec/support/sample_model.rb
|