sinclair 1.14.2 → 1.16.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|