sinclair 1.14.2 → 1.16.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 +11 -11
- data/config/yardstick.yml +11 -1
- data/lib/sinclair/caster/class_methods.rb +129 -0
- data/lib/sinclair/caster.rb +381 -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 +22 -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 +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 +13 -32
- data/spec/lib/sinclair/caster/class_methods_spec.rb +208 -0
- data/spec/lib/sinclair/caster_spec.rb +75 -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/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 +17 -2
data/lib/sinclair.rb
CHANGED
@@ -12,13 +12,13 @@ require 'active_support/core_ext'
|
|
12
12
|
# class MyModel
|
13
13
|
# end
|
14
14
|
#
|
15
|
-
# buider = Sinclair.new(MyModel)
|
16
|
-
#
|
17
15
|
# value = 10
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
16
|
+
#
|
17
|
+
# Sinclair.build(MyModel) do
|
18
|
+
# add_method(:default_value) { value }
|
19
|
+
# add_method(:value, '@value || default_value')
|
20
|
+
# add_method(:value=) { |val| @value = val }
|
21
|
+
# end
|
22
22
|
#
|
23
23
|
# instance = MyModel.new
|
24
24
|
# instance.value # returns 10
|
@@ -83,6 +83,7 @@ class Sinclair
|
|
83
83
|
require 'sinclair/options_parser'
|
84
84
|
|
85
85
|
autoload :VERSION, 'sinclair/version'
|
86
|
+
autoload :Caster, 'sinclair/caster'
|
86
87
|
autoload :ClassMethods, 'sinclair/class_methods'
|
87
88
|
autoload :Config, 'sinclair/config'
|
88
89
|
autoload :ConfigBuilder, 'sinclair/config_builder'
|
@@ -104,6 +105,8 @@ class Sinclair
|
|
104
105
|
extend ClassMethods
|
105
106
|
|
106
107
|
# @method self.build(klass, options = {}, &block)
|
108
|
+
# @api public
|
109
|
+
#
|
107
110
|
# Runs build using a block for adding the methods
|
108
111
|
#
|
109
112
|
# The block is executed adding the methods and after the builder
|
@@ -135,7 +138,6 @@ class Sinclair
|
|
135
138
|
# builder = Sinclair.new(Purchase)
|
136
139
|
#
|
137
140
|
# @example Passing building options (Used on subclasses)
|
138
|
-
#
|
139
141
|
# class MyBuilder < Sinclair
|
140
142
|
# def add_methods
|
141
143
|
# if options_object.rescue_error
|
@@ -159,10 +161,9 @@ class Sinclair
|
|
159
161
|
# class MyModel
|
160
162
|
# end
|
161
163
|
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
165
|
-
# builder.build
|
164
|
+
# MyBuilder.build(MyModel, rescue_error: true) do
|
165
|
+
# add_method
|
166
|
+
# end
|
166
167
|
#
|
167
168
|
# instance = MyModel.new
|
168
169
|
#
|
@@ -216,9 +217,9 @@ class Sinclair
|
|
216
217
|
# end
|
217
218
|
# end
|
218
219
|
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
220
|
+
# Sinclair.build(Person) do
|
221
|
+
# add_method(:full_name, '[first_name, last_name].join(" ")')
|
222
|
+
# end
|
222
223
|
#
|
223
224
|
# Person.new('john', 'wick').full_name # returns 'john wick'
|
224
225
|
#
|
@@ -240,9 +241,9 @@ class Sinclair
|
|
240
241
|
# end
|
241
242
|
# end
|
242
243
|
#
|
243
|
-
#
|
244
|
-
#
|
245
|
-
#
|
244
|
+
# Sinclair.build(Person) do
|
245
|
+
# add_method(:bond_name) { "#{last_name}, #{first_name} #{last_name}" }
|
246
|
+
# end
|
246
247
|
#
|
247
248
|
# Person.new('john', 'wick').bond_name # returns 'wick, john wick'
|
248
249
|
#
|
@@ -267,11 +268,11 @@ class Sinclair
|
|
267
268
|
# end
|
268
269
|
# end
|
269
270
|
#
|
270
|
-
#
|
271
|
-
#
|
272
|
-
#
|
271
|
+
# Sinclair.build(Person) do
|
272
|
+
# add_method(:bond_name, type: :block, cached: true) do
|
273
|
+
# "{last_name}, #{first_name} #{last_name}"
|
274
|
+
# end
|
273
275
|
# end
|
274
|
-
# builder.build
|
275
276
|
#
|
276
277
|
# person.Person.new('john', 'wick')
|
277
278
|
#
|
@@ -9,9 +9,9 @@ describe Sinclair do
|
|
9
9
|
klass = Class.new
|
10
10
|
instance = klass.new
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
Sinclair.build(klass) do
|
13
|
+
add_method(:random_number) { Random.rand(10..20) }
|
14
|
+
end
|
15
15
|
|
16
16
|
expect(instance.random_number).to be_between(10, 20)
|
17
17
|
end
|
@@ -34,11 +34,11 @@ describe Sinclair do
|
|
34
34
|
it 'adds the method' do
|
35
35
|
klass = Class.new
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
Sinclair.build(klass) do
|
38
|
+
add_class_method(
|
39
|
+
:function, 'a ** b + c', parameters: [:a], named_parameters: [:b, { c: 15 }]
|
40
|
+
)
|
41
|
+
end
|
42
42
|
|
43
43
|
expect(klass.function(10, b: 2)).to eq(115)
|
44
44
|
end
|
@@ -4,23 +4,17 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe MyBuilder do
|
6
6
|
describe '#yard' do
|
7
|
-
|
8
|
-
described_class.new(klass, rescue_error: true)
|
9
|
-
end
|
7
|
+
let(:klass) { Class.new }
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
describe 'Passing building options (Used on subclasses)' do
|
10
|
+
it 'builds the methods' do
|
11
|
+
MyBuilder.build(klass, rescue_error: true) do
|
12
|
+
add_methods
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
before do
|
16
|
-
builder.add_methods
|
17
|
-
builder.build
|
18
|
-
end
|
15
|
+
instance = klass.new
|
19
16
|
|
20
|
-
|
21
|
-
it 'returns default value' do
|
22
|
-
expect(instance.symbolize).to eq(:default)
|
23
|
-
end
|
17
|
+
expect(instance.symbolize).to eq(:default)
|
24
18
|
end
|
25
19
|
end
|
26
20
|
end
|
@@ -7,9 +7,9 @@ describe 'yard Sinclair#add_method' do
|
|
7
7
|
let(:klass) { Class.new(Person) }
|
8
8
|
|
9
9
|
it 'creates new method' do
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
Sinclair.build(klass) do
|
11
|
+
add_method(:full_name, '[first_name, last_name].join(" ")')
|
12
|
+
end
|
13
13
|
|
14
14
|
expect(klass.new('john', 'wick').full_name).to eq('john wick')
|
15
15
|
end
|
@@ -19,9 +19,9 @@ describe 'yard Sinclair#add_method' do
|
|
19
19
|
let(:klass) { Class.new(Person) }
|
20
20
|
|
21
21
|
it 'creates new method' do
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
Sinclair.build(klass) do
|
23
|
+
add_method(:bond_name) { "#{last_name}, #{first_name} #{last_name}" }
|
24
|
+
end
|
25
25
|
|
26
26
|
expect(klass.new('john', 'wick').bond_name).to eq('wick, john wick')
|
27
27
|
end
|
@@ -31,11 +31,12 @@ describe 'yard Sinclair#add_method' do
|
|
31
31
|
let(:klass) { Class.new(Person) }
|
32
32
|
|
33
33
|
it 'creates new method' do
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
Sinclair.build(klass) do
|
35
|
+
add_method(:bond_name, type: :block, cached: true) do
|
36
|
+
"#{last_name}, #{first_name} #{last_name}"
|
37
|
+
end
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
person = klass.new('john', 'wick')
|
40
41
|
|
41
42
|
expect(person.bond_name).to eq('wick, john wick')
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair::Caster' do
|
6
|
+
describe '.cast' do
|
7
|
+
it 'Casts with a symbol key' do
|
8
|
+
initial = Random.rand(10..20)
|
9
|
+
log = MathCaster.cast(initial, :log)
|
10
|
+
exp = MathCaster.cast(log, :exp)
|
11
|
+
|
12
|
+
expect(exp).to be_between(initial - 0.0001, initial + 0.0001)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'Casts passing parameter' do
|
16
|
+
base = Random.rand(3..6)
|
17
|
+
initial = Random.rand(10..20)
|
18
|
+
log = MathCaster.cast(initial, :log, base: base)
|
19
|
+
exp = MathCaster.cast(log, :exp, base: base)
|
20
|
+
|
21
|
+
expect(exp).to be_between(initial - 0.0001, initial + 0.0001)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'Casts with class key' do
|
25
|
+
hash = { a: 1, b: 2, 'c' => nil }
|
26
|
+
string = 'my string'
|
27
|
+
symbol = :the_symbol
|
28
|
+
number = 10
|
29
|
+
null = nil
|
30
|
+
|
31
|
+
code = <<-RUBY
|
32
|
+
hash_value = #{RubyStringCaster.to_ruby_string(hash)}
|
33
|
+
string_value = #{RubyStringCaster.to_ruby_string(string)}
|
34
|
+
symbol_value = #{RubyStringCaster.to_ruby_string(symbol)}
|
35
|
+
number = #{RubyStringCaster.to_ruby_string(number)}
|
36
|
+
null_value = #{RubyStringCaster.to_ruby_string(null)}
|
37
|
+
RUBY
|
38
|
+
|
39
|
+
expect(code).to eq(<<-RUBY)
|
40
|
+
hash_value = {:a=>1, :b=>2, "c"=>nil}
|
41
|
+
string_value = "my string"
|
42
|
+
symbol_value = :the_symbol
|
43
|
+
number = 10
|
44
|
+
null_value = nil
|
45
|
+
RUBY
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#cast' do
|
50
|
+
it 'Casts from a selected caster' do
|
51
|
+
caster = MathCaster.caster_for(:log)
|
52
|
+
|
53
|
+
expect(caster.cast(100)).to eq(2)
|
54
|
+
expect(caster.cast(8, base: 2)).to eq(3)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair::Caster.cast_with' do
|
6
|
+
let(:my_caster) { Class.new(Sinclair::Caster) }
|
7
|
+
|
8
|
+
it 'Casting from pre registered symbol caster' do
|
9
|
+
my_caster.cast_with(:json, :to_json)
|
10
|
+
|
11
|
+
expect(my_caster.cast({ key: :value }, :json)).to eq('{"key":"value"}')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'Casting from pre registered block caster' do
|
15
|
+
my_caster.cast_with(:complex) do |hash|
|
16
|
+
real = hash[:real]
|
17
|
+
imaginary = hash[:imaginary]
|
18
|
+
|
19
|
+
"#{real.to_f} + #{imaginary.to_f} i"
|
20
|
+
end
|
21
|
+
|
22
|
+
value = { real: 10, imaginary: 5 }
|
23
|
+
|
24
|
+
expect(my_caster.cast(value, :complex)).to eq('10.0 + 5.0 i')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'Casting from pre registered class' do
|
28
|
+
my_caster.cast_with(Numeric, :to_i)
|
29
|
+
|
30
|
+
expect(my_caster.cast('10', Integer)).to eq(10)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'Casting from pre registered block caster from a class' do
|
34
|
+
my_caster.cast_with(HashModel) do |value, klass:|
|
35
|
+
klass.new(value)
|
36
|
+
end
|
37
|
+
|
38
|
+
my_caster.cast_with(String, &:to_json)
|
39
|
+
|
40
|
+
values = [
|
41
|
+
{ klass: String, value: { name: 'john', age: 20, country: 'BR' } },
|
42
|
+
{ klass: HashPerson, value: { name: 'Mary', age: 22, country: 'IT' } }
|
43
|
+
]
|
44
|
+
|
45
|
+
values.map! do |config|
|
46
|
+
value = config[:value]
|
47
|
+
klass = config[:klass]
|
48
|
+
my_caster.cast(value, klass, klass: klass)
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(values[0]).to eq('{"name":"john","age":20,"country":"BR"}')
|
52
|
+
expect(values[1]).to eq(HashPerson.new(name: 'Mary', age: 22))
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair::Caster.cast' do
|
6
|
+
it 'Getting the caster with symbol key' do
|
7
|
+
expect(EnumConverter.to_array({ key: :value })).to eq([%i[key value]])
|
8
|
+
expect(EnumConverter.to_hash([%i[key value]])).to eq({ key: :value })
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'Getting the caster with class key' do
|
12
|
+
expect(StringParser.cast('{"key":"value"}', JSON)).to eq({ 'key' => 'value' })
|
13
|
+
expect(StringParser.cast('10.2', Integer)).to eq(10)
|
14
|
+
expect(StringParser.cast('10.2', Float)).to eq(10.2)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair::Caster::ClassMethods' do
|
6
|
+
let(:my_caster) { Class.new(superclass) }
|
7
|
+
|
8
|
+
let(:superclass) do
|
9
|
+
Class.new(Sinclair::Caster) do
|
10
|
+
cast_with(:string, :to_s)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.master_caster!' do
|
15
|
+
it 'Making a class to be a master caster' do
|
16
|
+
expect(my_caster.cast(10, :string)).to eq('10')
|
17
|
+
|
18
|
+
my_caster.master_caster!
|
19
|
+
|
20
|
+
expect(my_caster.cast(10, :string)).to eq(10)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -5,16 +5,14 @@ require 'spec_helper'
|
|
5
5
|
describe Sinclair::ConfigBuilder do
|
6
6
|
describe 'yard' do
|
7
7
|
describe '#instance_eval' do
|
8
|
-
|
9
|
-
|
10
|
-
end
|
8
|
+
it 'sets variable from config' do
|
9
|
+
config = MyConfig.new
|
11
10
|
|
12
|
-
|
11
|
+
builder = described_class.new(config, :name)
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
.from(nil).to('John')
|
13
|
+
builder.instance_eval { |c| c.name 'John' }
|
14
|
+
|
15
|
+
expect(config.name).to eq('John')
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -5,33 +5,19 @@ require 'spec_helper'
|
|
5
5
|
describe Sinclair::ConfigClass do
|
6
6
|
describe 'yard' do
|
7
7
|
describe '.add_configs' do
|
8
|
-
|
8
|
+
it 'Adding configurations to config class' do
|
9
|
+
config = AppConfig.new
|
9
10
|
|
10
|
-
it 'has a secret configuration method' do
|
11
11
|
expect(config.secret).to be_nil
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'has a app_name configuration method' do
|
15
12
|
expect(config.app_name).to eq('MyApp')
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'when configured' do
|
19
|
-
let(:config_builder) do
|
20
|
-
Sinclair::ConfigBuilder.new(config)
|
21
|
-
end
|
22
13
|
|
23
|
-
|
24
|
-
config_builder.secret '123abc'
|
25
|
-
config_builder.app_name 'MySuperApp'
|
26
|
-
end
|
14
|
+
config_builder = Sinclair::ConfigBuilder.new(config)
|
27
15
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
16
|
+
config_builder.secret '123abc'
|
17
|
+
config_builder.app_name 'MySuperApp'
|
31
18
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
19
|
+
expect(config.secret).to eq('123abc')
|
20
|
+
expect(config.app_name).to eq('MySuperApp')
|
35
21
|
end
|
36
22
|
end
|
37
23
|
end
|
@@ -4,10 +4,8 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Sinclair do
|
6
6
|
describe 'yard' do
|
7
|
-
let(:klass)
|
8
|
-
let(:
|
9
|
-
let(:builder) { described_class.new(klass) }
|
10
|
-
let(:default_value) { 10 }
|
7
|
+
let(:klass) { Class.new(MyModel) }
|
8
|
+
let(:builder) { described_class.new(klass) }
|
11
9
|
|
12
10
|
describe 'Using cache' do
|
13
11
|
subject(:server) { Server.new }
|
@@ -85,38 +83,21 @@ describe Sinclair do
|
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
88
|
-
describe '
|
89
|
-
|
90
|
-
value =
|
91
|
-
builder.add_method(:default_value) { value }
|
92
|
-
builder.add_method(:value, '@value || default_value')
|
93
|
-
builder.add_method(:value=) { |val| @value = val }
|
94
|
-
end
|
95
|
-
|
96
|
-
describe 'after the build' do
|
97
|
-
before { builder.build }
|
86
|
+
describe 'Stand alone usage' do
|
87
|
+
it 'builds the methods' do
|
88
|
+
value = 10
|
98
89
|
|
99
|
-
|
100
|
-
|
90
|
+
Sinclair.build(klass) do
|
91
|
+
add_method(:default_value) { value }
|
92
|
+
add_method(:value, '@value || default_value')
|
93
|
+
add_method(:value=) { |val| @value = val }
|
101
94
|
end
|
102
95
|
|
103
|
-
|
104
|
-
before do
|
105
|
-
instance.value = 20
|
106
|
-
end
|
96
|
+
instance = klass.new
|
107
97
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
context 'when calling the build' do
|
115
|
-
it do
|
116
|
-
expect do
|
117
|
-
builder.build
|
118
|
-
end.to change { instance.respond_to?(:default_value) }.to(true)
|
119
|
-
end
|
98
|
+
expect(instance.value).to eq(10)
|
99
|
+
instance.value = 20
|
100
|
+
expect(instance.value).to eq(20)
|
120
101
|
end
|
121
102
|
end
|
122
103
|
end
|