sinclair 1.4.2 → 1.5.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/.circleci/config.yml +4 -1
- data/Dockerfile +3 -3
- data/README.md +1 -1
- data/config/check_specs.yml +5 -0
- data/config/yardstick.yml +3 -0
- data/lib/sinclair.rb +26 -9
- data/lib/sinclair/config/methods_builder.rb +3 -1
- data/lib/sinclair/config_factory.rb +4 -2
- data/lib/sinclair/matchers/add_class_method_to.rb +1 -0
- data/lib/sinclair/method_builder.rb +61 -0
- data/lib/sinclair/method_builder/base.rb +67 -0
- data/lib/sinclair/method_builder/block_method_builder.rb +34 -0
- data/lib/sinclair/method_builder/string_method_builder.rb +50 -0
- data/lib/sinclair/method_definition.rb +38 -17
- data/lib/sinclair/method_definition/block_definition.rb +8 -94
- data/lib/sinclair/method_definition/block_helper.rb +46 -0
- data/lib/sinclair/method_definition/string_definition.rb +7 -66
- data/lib/sinclair/method_definitions.rb +16 -4
- data/lib/sinclair/version.rb +1 -1
- data/sinclair.gemspec +1 -1
- data/spec/lib/sinclair/method_builder/block_method_builder_spec.rb +55 -0
- data/spec/lib/sinclair/method_builder/string_method_builder_spec.rb +54 -0
- data/spec/lib/sinclair/method_builder_spec.rb +53 -0
- data/spec/lib/sinclair/method_definition/block_definition_spec.rb +66 -0
- data/spec/lib/sinclair/method_definition/block_helper_spec.rb +111 -0
- data/spec/lib/sinclair/method_definition/string_definition_spec.rb +70 -0
- data/spec/lib/sinclair/method_definition_spec.rb +23 -88
- data/spec/lib/sinclair/method_definitions_spec.rb +45 -0
- data/spec/support/models/random_generator.rb +13 -0
- metadata +18 -20
- data/lib/sinclair/method_definition/class_block_definition.rb +0 -22
- data/lib/sinclair/method_definition/class_method_definition.rb +0 -50
- data/lib/sinclair/method_definition/class_string_definition.rb +0 -24
- data/lib/sinclair/method_definition/instance_block_definition.rb +0 -22
- data/lib/sinclair/method_definition/instance_method_definition.rb +0 -48
- data/lib/sinclair/method_definition/instance_string_definition.rb +0 -24
- data/spec/integration/yard/sinclair/method_definition/class_block_definition_spec.rb +0 -34
- data/spec/integration/yard/sinclair/method_definition/class_method_definition_spec.rb +0 -28
- data/spec/integration/yard/sinclair/method_definition/class_string_definition_spec.rb +0 -23
- data/spec/integration/yard/sinclair/method_definition/instance_block_definition_spec.rb +0 -25
- data/spec/integration/yard/sinclair/method_definition/instance_method_definition_spec.rb +0 -35
- data/spec/integration/yard/sinclair/method_definition/instance_string_definition_spec.rb +0 -32
- data/spec/lib/sinclair/method_definition/class_block_definition_spec.rb +0 -29
- data/spec/lib/sinclair/method_definition/class_string_definition_spec.rb +0 -27
- data/spec/lib/sinclair/method_definition/instance_block_definition_spec.rb +0 -30
- data/spec/lib/sinclair/method_definition/instance_string_definition_spec.rb +0 -28
@@ -17,71 +17,9 @@ class Sinclair
|
|
17
17
|
super(name, **options)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
# @param klass [Class] class which will receive the new method
|
23
|
-
#
|
24
|
-
# @see MethodDefinition#build
|
25
|
-
#
|
26
|
-
# @return [Symbol] name of the created method
|
27
|
-
#
|
28
|
-
# @example Using instance block method with cached options
|
29
|
-
# class MyModel
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# instance = MyModel.new
|
33
|
-
#
|
34
|
-
# method_definition = Sinclair::MethodDefinition::InstanceBlockDefinition.new(
|
35
|
-
# :sequence, cached: true
|
36
|
-
# ) do
|
37
|
-
# @x = @x.to_i ** 2 + 1
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# method_definition.build(MyModel) # adds instance_method :sequence to
|
41
|
-
# # MyModel instances
|
42
|
-
#
|
43
|
-
# instance.instance_variable_get(:@sequence) # returns nil
|
44
|
-
# instance.instance_variable_get(:@x) # returns nil
|
45
|
-
#
|
46
|
-
# instance.sequence # returns 1
|
47
|
-
# instance.sequence # returns 1 (cached value)
|
48
|
-
#
|
49
|
-
# instance.instance_variable_get(:@sequence) # returns 1
|
50
|
-
# instance.instance_variable_get(:@x) # returns 1
|
51
|
-
#
|
52
|
-
# @example Using class block method without options
|
53
|
-
# class MyModel
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# method_definition = Sinclair::MethodDefinition::ClassBlockDefinition.new(:sequence) do
|
57
|
-
# @x = @x.to_i ** 2 + 1
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# method_definition.build(MyModel) # adds instance_method :sequence to
|
61
|
-
# # MyModel instances
|
62
|
-
#
|
63
|
-
# MyModel.instance_variable_get(:@x) # returns nil
|
64
|
-
#
|
65
|
-
# MyModel.sequence # returns 1
|
66
|
-
# MyModel.sequence # returns 2
|
67
|
-
# MyModel.sequence # returns 5
|
68
|
-
#
|
69
|
-
# MyModel.instance_variable_get(:@x) # returns 5
|
70
|
-
def build(klass)
|
71
|
-
klass.send(method_definer, name, method_block)
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
20
|
+
default_value :block?, true
|
21
|
+
default_value :string?, false
|
75
22
|
|
76
|
-
# @method block
|
77
|
-
# @private
|
78
|
-
#
|
79
|
-
# Block with code to be added as method
|
80
|
-
# @return [Proc]
|
81
|
-
attr_reader :block
|
82
|
-
|
83
|
-
# @private
|
84
|
-
#
|
85
23
|
# Returns the block that will be used for method creattion
|
86
24
|
#
|
87
25
|
# @return [Proc]
|
@@ -90,44 +28,20 @@ class Sinclair
|
|
90
28
|
|
91
29
|
case cached
|
92
30
|
when :full
|
93
|
-
full_cached_method_proc(name, block)
|
31
|
+
BlockHelper.full_cached_method_proc(name, &block)
|
94
32
|
else
|
95
|
-
cached_method_proc(name, block)
|
33
|
+
BlockHelper.cached_method_proc(name, &block)
|
96
34
|
end
|
97
35
|
end
|
98
36
|
|
99
|
-
|
100
|
-
#
|
101
|
-
# Returns proc block when {#cached?} as simple
|
102
|
-
#
|
103
|
-
# @return [Proc]
|
104
|
-
def cached_method_proc(method_name, inner_block)
|
105
|
-
proc do
|
106
|
-
instance_variable_get("@#{method_name}") ||
|
107
|
-
instance_variable_set(
|
108
|
-
"@#{method_name}",
|
109
|
-
instance_eval(&inner_block)
|
110
|
-
)
|
111
|
-
end
|
112
|
-
end
|
37
|
+
private
|
113
38
|
|
39
|
+
# @method block
|
114
40
|
# @private
|
115
41
|
#
|
116
|
-
#
|
117
|
-
#
|
42
|
+
# Block with code to be added as method
|
118
43
|
# @return [Proc]
|
119
|
-
|
120
|
-
proc do
|
121
|
-
if instance_variable_defined?("@#{method_name}")
|
122
|
-
instance_variable_get("@#{method_name}")
|
123
|
-
else
|
124
|
-
instance_variable_set(
|
125
|
-
"@#{method_name}",
|
126
|
-
instance_eval(&inner_block)
|
127
|
-
)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
44
|
+
attr_reader :block
|
131
45
|
end
|
132
46
|
end
|
133
47
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class MethodDefinition
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Helper for wrapping block with cacheing
|
9
|
+
module BlockHelper
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# @private
|
13
|
+
#
|
14
|
+
# Returns proc block when {#cached?} as simple
|
15
|
+
#
|
16
|
+
# @return [Proc]
|
17
|
+
def cached_method_proc(method_name, &inner_block)
|
18
|
+
proc do
|
19
|
+
instance_variable_get("@#{method_name}") ||
|
20
|
+
instance_variable_set(
|
21
|
+
"@#{method_name}",
|
22
|
+
instance_eval(&inner_block)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @private
|
28
|
+
#
|
29
|
+
# Returns proc block when {#cached?} as full
|
30
|
+
#
|
31
|
+
# @return [Proc]
|
32
|
+
def full_cached_method_proc(method_name, &inner_block)
|
33
|
+
proc do
|
34
|
+
if instance_variable_defined?("@#{method_name}")
|
35
|
+
instance_variable_get("@#{method_name}")
|
36
|
+
else
|
37
|
+
instance_variable_set(
|
38
|
+
"@#{method_name}",
|
39
|
+
instance_eval(&inner_block)
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -19,58 +19,14 @@ class Sinclair
|
|
19
19
|
super(name, **options)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
#
|
26
|
-
# @see MethodDefinition#build
|
27
|
-
#
|
28
|
-
# @return [Symbol] name of the created method
|
29
|
-
#
|
30
|
-
# @example Using instance string method with no options
|
31
|
-
# class MyModel
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# instance = MyModel.new
|
35
|
-
#
|
36
|
-
# method_definition = Sinclair::MethodDefinition::InstanceStringDefinition.new(
|
37
|
-
# :sequence, '@x = @x.to_i ** 2 + 1'
|
38
|
-
# )
|
39
|
-
#
|
40
|
-
# method_definition.build(MyModel) # adds instance_method :sequence to
|
41
|
-
# # MyModel instances
|
42
|
-
#
|
43
|
-
# instance.instance_variable_get(:@x) # returns nil
|
44
|
-
#
|
45
|
-
# instance.sequence # returns 1
|
46
|
-
# instance.sequence # returns 2
|
47
|
-
# instance.sequence # returns 5
|
48
|
-
#
|
49
|
-
# instance.instance_variable_get(:@x) # returns 5
|
50
|
-
#
|
51
|
-
# @example Using class string method with cache options
|
52
|
-
# class MyModel
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
# method_definition = Sinclair::MethodDefinition::ClassStringDefinition.new(
|
56
|
-
# :sequence,
|
57
|
-
# '@x = @x.to_i ** 2 + 1',
|
58
|
-
# cached: true
|
59
|
-
# )
|
60
|
-
#
|
61
|
-
# method_definition.build(MyModel) # adds instance_method :sequence to
|
62
|
-
# # MyModel instances
|
63
|
-
#
|
64
|
-
# MyModel.instance_variable_get(:@sequence) # returns nil
|
65
|
-
# MyModel.instance_variable_get(:@x) # returns nil
|
66
|
-
#
|
67
|
-
# MyModel.sequence # returns 1
|
68
|
-
# MyModel.sequence # returns 1 (cached value)
|
22
|
+
default_value :block?, false
|
23
|
+
default_value :string?, true
|
24
|
+
|
25
|
+
# codeline to be run inside the code
|
69
26
|
#
|
70
|
-
#
|
71
|
-
|
72
|
-
|
73
|
-
klass.module_eval(code_definition, __FILE__, __LINE__ + 1)
|
27
|
+
# @return [String]
|
28
|
+
def code_line
|
29
|
+
cached? ? code_with_cache : code
|
74
30
|
end
|
75
31
|
|
76
32
|
private
|
@@ -83,21 +39,6 @@ class Sinclair
|
|
83
39
|
# @return [String]
|
84
40
|
attr_reader :code
|
85
41
|
|
86
|
-
# @private
|
87
|
-
#
|
88
|
-
# Builds full code of method
|
89
|
-
#
|
90
|
-
# @return [String]
|
91
|
-
def code_definition
|
92
|
-
code_line = cached? ? code_with_cache : code
|
93
|
-
|
94
|
-
<<-CODE
|
95
|
-
def #{method_name}
|
96
|
-
#{code_line}
|
97
|
-
end
|
98
|
-
CODE
|
99
|
-
end
|
100
|
-
|
101
42
|
# @private
|
102
43
|
#
|
103
44
|
# Returns string code when {#cached?}
|
@@ -5,10 +5,11 @@ class Sinclair
|
|
5
5
|
# @author darthjee
|
6
6
|
#
|
7
7
|
# Enumerator holding all method definitions
|
8
|
-
class MethodDefinitions
|
8
|
+
class MethodDefinitions
|
9
|
+
delegate :each, to: :definitions
|
10
|
+
|
9
11
|
# Builds and adds new definition
|
10
12
|
#
|
11
|
-
# @param definition_class [Class] class used to define method definition
|
12
13
|
# @param name [String,Symbol] method name
|
13
14
|
# @param options [Hash] Options of construction
|
14
15
|
# @option options cached [Boolean] Flag telling to create
|
@@ -21,8 +22,19 @@ class Sinclair
|
|
21
22
|
# @param block [Proc] block to be ran as method
|
22
23
|
#
|
23
24
|
# @return MethodDefinitions
|
24
|
-
def add(
|
25
|
-
|
25
|
+
def add(name, code = nil, **options, &block)
|
26
|
+
definitions << MethodDefinition.from(name, code, **options, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @private
|
32
|
+
#
|
33
|
+
# All definitions
|
34
|
+
#
|
35
|
+
# @return [Array<MethodDefinition>]
|
36
|
+
def definitions
|
37
|
+
@definitions ||= []
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
data/lib/sinclair/version.rb
CHANGED
data/sinclair.gemspec
CHANGED
@@ -35,6 +35,6 @@ Gem::Specification.new do |gem|
|
|
35
35
|
gem.add_development_dependency 'rubocop-rspec', '1.33.0'
|
36
36
|
gem.add_development_dependency 'rubycritic', '4.1.0'
|
37
37
|
gem.add_development_dependency 'simplecov', '0.17.0'
|
38
|
-
gem.add_development_dependency 'yard', '0.9.
|
38
|
+
gem.add_development_dependency 'yard', '0.9.20'
|
39
39
|
gem.add_development_dependency 'yardstick', '0.9.9'
|
40
40
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodBuilder::BlockMethodBuilder do
|
6
|
+
describe '#build' do
|
7
|
+
subject(:builder) do
|
8
|
+
described_class.new(klass, definition, type: type)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:klass) { Class.new }
|
12
|
+
let(:instance) { klass.new }
|
13
|
+
let(:value) { Random.rand }
|
14
|
+
let(:method_name) { :the_method }
|
15
|
+
|
16
|
+
let(:definition) do
|
17
|
+
result = value
|
18
|
+
Sinclair::MethodDefinition.from(method_name) { result }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when type is instance' do
|
22
|
+
let(:type) { Sinclair::MethodBuilder::INSTANCE_METHOD }
|
23
|
+
|
24
|
+
it do
|
25
|
+
expect { builder.build }
|
26
|
+
.to add_method(method_name).to(instance)
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the method is built' do
|
30
|
+
before { builder.build }
|
31
|
+
|
32
|
+
it 'returns the result of the block when called' do
|
33
|
+
expect(instance.the_method).to eq(value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when type is class' do
|
39
|
+
let(:type) { Sinclair::MethodBuilder::CLASS_METHOD }
|
40
|
+
|
41
|
+
it do
|
42
|
+
expect { builder.build }
|
43
|
+
.to add_class_method(method_name).to(klass)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when the method is built' do
|
47
|
+
before { builder.build }
|
48
|
+
|
49
|
+
it 'returns the result of the block when called' do
|
50
|
+
expect(klass.the_method).to eq(value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodBuilder::StringMethodBuilder do
|
6
|
+
describe '#build' do
|
7
|
+
subject(:builder) do
|
8
|
+
described_class.new(klass, definition, type: type)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:klass) { Class.new }
|
12
|
+
let(:instance) { klass.new }
|
13
|
+
let(:value) { Random.rand }
|
14
|
+
let(:method_name) { :the_method }
|
15
|
+
|
16
|
+
let(:definition) do
|
17
|
+
Sinclair::MethodDefinition.from(method_name, value.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when type is instance' do
|
21
|
+
let(:type) { Sinclair::MethodBuilder::INSTANCE_METHOD }
|
22
|
+
|
23
|
+
it do
|
24
|
+
expect { builder.build }
|
25
|
+
.to add_method(method_name).to(instance)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the method is built' do
|
29
|
+
before { builder.build }
|
30
|
+
|
31
|
+
it 'returns the result of the code when called' do
|
32
|
+
expect(instance.the_method).to eq(value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when type is class' do
|
38
|
+
let(:type) { Sinclair::MethodBuilder::CLASS_METHOD }
|
39
|
+
|
40
|
+
it do
|
41
|
+
expect { builder.build }
|
42
|
+
.to add_class_method(method_name).to(klass)
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when the method is built' do
|
46
|
+
before { builder.build }
|
47
|
+
|
48
|
+
it 'returns the result of the code when called' do
|
49
|
+
expect(klass.the_method).to eq(value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodBuilder do
|
6
|
+
subject(:builder) { described_class.new(klass) }
|
7
|
+
|
8
|
+
let(:klass) { Class.new }
|
9
|
+
let(:definitions) { Sinclair::MethodDefinitions.new }
|
10
|
+
let(:value) { Random.rand }
|
11
|
+
let(:method_name) { :the_method }
|
12
|
+
let(:instance) { klass.new }
|
13
|
+
|
14
|
+
before do
|
15
|
+
definitions.add(method_name, value.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#build_methods' do
|
19
|
+
context 'when building an instance method' do
|
20
|
+
let(:type) { described_class::INSTANCE_METHOD }
|
21
|
+
|
22
|
+
it do
|
23
|
+
expect { builder.build_methods(definitions, type) }
|
24
|
+
.to add_method(method_name).to(instance)
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the method is called' do
|
28
|
+
before { builder.build_methods(definitions, type) }
|
29
|
+
|
30
|
+
it do
|
31
|
+
expect(instance.the_method).to eq(value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when building a class method' do
|
37
|
+
let(:type) { described_class::INSTANCE_METHOD }
|
38
|
+
|
39
|
+
it do
|
40
|
+
expect { builder.build_methods(definitions, type) }
|
41
|
+
.to add_method(method_name).to(instance)
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when the method is called' do
|
45
|
+
before { builder.build_methods(definitions, type) }
|
46
|
+
|
47
|
+
it do
|
48
|
+
expect(instance.the_method).to eq(value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|