sinclair 1.4.1 → 1.4.2
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 +5 -3
- data/.rubocop.yml +20 -4
- data/Dockerfile +8 -4
- data/README.md +1 -1
- data/config/yardstick.yml +10 -35
- data/lib/sinclair.rb +87 -18
- data/lib/sinclair/config.rb +3 -0
- data/lib/sinclair/config/methods_builder.rb +15 -1
- data/lib/sinclair/config_builder.rb +1 -0
- data/lib/sinclair/config_class.rb +1 -0
- data/lib/sinclair/config_factory.rb +15 -0
- data/lib/sinclair/configurable.rb +1 -0
- data/lib/sinclair/matchers.rb +20 -6
- data/lib/sinclair/matchers/add_class_method.rb +56 -0
- data/lib/sinclair/matchers/add_class_method_to.rb +98 -0
- data/lib/sinclair/matchers/add_instance_method.rb +85 -0
- data/lib/sinclair/matchers/add_instance_method_to.rb +119 -0
- data/lib/sinclair/matchers/add_method.rb +11 -73
- data/lib/sinclair/matchers/add_method_to.rb +13 -111
- data/lib/sinclair/method_definition.rb +18 -58
- data/lib/sinclair/method_definition/block_definition.rb +37 -6
- data/lib/sinclair/method_definition/class_block_definition.rb +22 -0
- data/lib/sinclair/method_definition/class_method_definition.rb +50 -0
- data/lib/sinclair/method_definition/class_string_definition.rb +24 -0
- data/lib/sinclair/method_definition/instance_block_definition.rb +22 -0
- data/lib/sinclair/method_definition/instance_method_definition.rb +48 -0
- data/lib/sinclair/method_definition/instance_string_definition.rb +24 -0
- data/lib/sinclair/method_definition/string_definition.rb +39 -5
- data/lib/sinclair/method_definitions.rb +28 -0
- data/lib/sinclair/options_parser.rb +5 -0
- data/lib/sinclair/version.rb +1 -1
- data/sinclair.gemspec +16 -10
- data/spec/integration/yard/sinclair/matchers/add_class_method_spec.rb +23 -0
- data/spec/integration/yard/sinclair/matchers/add_class_method_to_spec.rb +19 -0
- data/spec/integration/yard/sinclair/matchers/{add_method_spec.rb → add_instance_method_spec.rb} +3 -3
- data/spec/integration/yard/sinclair/matchers/{add_method_to_spec.rb → add_instance_method_to_spec.rb} +1 -1
- data/spec/integration/yard/sinclair/method_definition/class_block_definition_spec.rb +34 -0
- data/spec/integration/yard/sinclair/method_definition/class_method_definition_spec.rb +28 -0
- data/spec/integration/yard/sinclair/method_definition/class_string_definition_spec.rb +23 -0
- data/spec/integration/yard/sinclair/method_definition/{block_definition_spec.rb → instance_block_definition_spec.rb} +2 -2
- data/spec/integration/yard/sinclair/method_definition/instance_method_definition_spec.rb +35 -0
- data/spec/integration/yard/sinclair/method_definition/{string_definition_spec.rb → instance_string_definition_spec.rb} +1 -1
- data/spec/integration/yard/sinclair_spec.rb +32 -5
- data/spec/lib/sinclair/matchers/add_class_method_spec.rb +36 -0
- data/spec/lib/sinclair/matchers/add_class_method_to_spec.rb +77 -0
- data/spec/lib/sinclair/matchers/{add_method_spec.rb → add_instance_method_spec.rb} +11 -4
- data/spec/lib/sinclair/matchers/{add_method_to_spec.rb → add_instance_method_to_spec.rb} +2 -2
- data/spec/lib/sinclair/matchers_spec.rb +17 -2
- data/spec/lib/sinclair/method_definition/class_block_definition_spec.rb +29 -0
- data/spec/lib/sinclair/method_definition/class_string_definition_spec.rb +27 -0
- data/spec/lib/sinclair/method_definition/{block_definition_spec.rb → instance_block_definition_spec.rb} +2 -2
- data/spec/lib/sinclair/method_definition/{string_definition_spec.rb → instance_string_definition_spec.rb} +2 -2
- data/spec/lib/sinclair/method_definition_spec.rb +52 -6
- data/spec/lib/sinclair_spec.rb +83 -0
- data/spec/support/models/dummy_class_builder.rb +11 -0
- data/spec/support/shared_examples/class_method_definition.rb +96 -0
- data/spec/support/shared_examples/{method_definition.rb → instance_method_definition.rb} +0 -0
- metadata +148 -45
- data/scripts/check_readme.sh +0 -6
- data/scripts/rubycritic.sh +0 -10
- data/spec/integration/sinclair/matchers_spec.rb +0 -99
- data/spec/integration/yard/sinclair/method_definition_spec.rb +0 -56
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class MethodDefinition
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Define a method from block
|
9
|
+
class InstanceBlockDefinition < BlockDefinition
|
10
|
+
private
|
11
|
+
|
12
|
+
# @private
|
13
|
+
#
|
14
|
+
# Method used to define an instance method
|
15
|
+
#
|
16
|
+
# @return [Symbol] Always :define_method
|
17
|
+
def method_definer
|
18
|
+
:define_method
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class MethodDefinition
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Module responsible for building instance method definitions
|
9
|
+
module InstanceMethodDefinition
|
10
|
+
# Returns an instance method definition
|
11
|
+
#
|
12
|
+
# When block is given returns an instance of
|
13
|
+
# {InstanceBlockDefinition}, and when not, returns
|
14
|
+
# {InstanceStringDefinition}
|
15
|
+
#
|
16
|
+
# @param name [String,Symbol] name of the method
|
17
|
+
# @param code [String] code to be evaluated as method
|
18
|
+
# @param block [Proc] block with code to be added as method
|
19
|
+
# @param options [Hash] Options of construction
|
20
|
+
# @option options cached [Boolean] Flag telling to create
|
21
|
+
# a method with cache
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# klass = Class.new
|
25
|
+
#
|
26
|
+
# method_definition = Sinclair::MethodDefinition::InstanceMethodDefinition.from(
|
27
|
+
# :sequence, '@x = @x.to_i ** 2 + 1'
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# method_definition.build(klass)
|
31
|
+
#
|
32
|
+
# instance = klass.new
|
33
|
+
#
|
34
|
+
# instance.sequence # returns 1
|
35
|
+
# instance.sequence # returns 2
|
36
|
+
# instance.sequence # returns 5
|
37
|
+
#
|
38
|
+
# @return MethodDefinition
|
39
|
+
def self.from(name, code = nil, **options, &block)
|
40
|
+
if block
|
41
|
+
InstanceBlockDefinition.new(name, **options, &block)
|
42
|
+
else
|
43
|
+
InstanceStringDefinition.new(name, code, **options)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class MethodDefinition
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Define an instance method from string
|
9
|
+
class InstanceStringDefinition < StringDefinition
|
10
|
+
private
|
11
|
+
|
12
|
+
# @private
|
13
|
+
#
|
14
|
+
# String used when defining method
|
15
|
+
#
|
16
|
+
# Instance definition always returns +name+
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
def method_name
|
20
|
+
name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,7 +2,12 @@
|
|
2
2
|
|
3
3
|
class Sinclair
|
4
4
|
class MethodDefinition
|
5
|
-
#
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# @abstract
|
9
|
+
#
|
10
|
+
# Define an instance method from string
|
6
11
|
class StringDefinition < MethodDefinition
|
7
12
|
# @param name [String,Symbol] name of the method
|
8
13
|
# @param code [String] code to be evaluated as method
|
@@ -22,17 +27,17 @@ class Sinclair
|
|
22
27
|
#
|
23
28
|
# @return [Symbol] name of the created method
|
24
29
|
#
|
25
|
-
# @example
|
30
|
+
# @example Using instance string method with no options
|
26
31
|
# class MyModel
|
27
32
|
# end
|
28
33
|
#
|
29
34
|
# instance = MyModel.new
|
30
35
|
#
|
31
|
-
# method_definition = Sinclair::MethodDefinition.
|
36
|
+
# method_definition = Sinclair::MethodDefinition::InstanceStringDefinition.new(
|
32
37
|
# :sequence, '@x = @x.to_i ** 2 + 1'
|
33
38
|
# )
|
34
39
|
#
|
35
|
-
# method_definition.build(
|
40
|
+
# method_definition.build(MyModel) # adds instance_method :sequence to
|
36
41
|
# # MyModel instances
|
37
42
|
#
|
38
43
|
# instance.instance_variable_get(:@x) # returns nil
|
@@ -43,12 +48,41 @@ class Sinclair
|
|
43
48
|
#
|
44
49
|
# instance.instance_variable_get(:@x) # returns 5
|
45
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)
|
69
|
+
#
|
70
|
+
# MyModel.instance_variable_get(:@sequence) # returns 1
|
71
|
+
# MyModel.instance_variable_get(:@x) # returns 1
|
46
72
|
def build(klass)
|
47
73
|
klass.module_eval(code_definition, __FILE__, __LINE__ + 1)
|
48
74
|
end
|
49
75
|
|
50
76
|
private
|
51
77
|
|
78
|
+
# @method code
|
79
|
+
# @private
|
80
|
+
#
|
81
|
+
# Code to be evaluated as method
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
attr_reader :code
|
85
|
+
|
52
86
|
# @private
|
53
87
|
#
|
54
88
|
# Builds full code of method
|
@@ -58,7 +92,7 @@ class Sinclair
|
|
58
92
|
code_line = cached? ? code_with_cache : code
|
59
93
|
|
60
94
|
<<-CODE
|
61
|
-
def #{
|
95
|
+
def #{method_name}
|
62
96
|
#{code_line}
|
63
97
|
end
|
64
98
|
CODE
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api private
|
5
|
+
# @author darthjee
|
6
|
+
#
|
7
|
+
# Enumerator holding all method definitions
|
8
|
+
class MethodDefinitions < Array
|
9
|
+
# Builds and adds new definition
|
10
|
+
#
|
11
|
+
# @param definition_class [Class] class used to define method definition
|
12
|
+
# @param name [String,Symbol] method name
|
13
|
+
# @param options [Hash] Options of construction
|
14
|
+
# @option options cached [Boolean] Flag telling to create
|
15
|
+
# a method with cache
|
16
|
+
#
|
17
|
+
# @overload add(definition_class, name, code = nil, **options)
|
18
|
+
# @param code [String] code to be evaluated when the method is ran
|
19
|
+
#
|
20
|
+
# @overload add(definition_class, name, **options, &block)
|
21
|
+
# @param block [Proc] block to be ran as method
|
22
|
+
#
|
23
|
+
# @return MethodDefinitions
|
24
|
+
def add(definition_class, name, code = nil, **options, &block)
|
25
|
+
self << definition_class.from(name, code, **options, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/sinclair/version.rb
CHANGED
data/sinclair.gemspec
CHANGED
@@ -21,14 +21,20 @@ Gem::Specification.new do |gem|
|
|
21
21
|
|
22
22
|
gem.add_runtime_dependency 'activesupport', '~> 5.2.0'
|
23
23
|
|
24
|
-
gem.add_development_dependency 'bundler',
|
25
|
-
gem.add_development_dependency 'pry
|
26
|
-
gem.add_development_dependency '
|
27
|
-
gem.add_development_dependency '
|
28
|
-
gem.add_development_dependency '
|
29
|
-
gem.add_development_dependency '
|
30
|
-
gem.add_development_dependency '
|
31
|
-
gem.add_development_dependency '
|
32
|
-
gem.add_development_dependency '
|
33
|
-
gem.add_development_dependency '
|
24
|
+
gem.add_development_dependency 'bundler', '~> 1.16.1'
|
25
|
+
gem.add_development_dependency 'pry', '0.12.2'
|
26
|
+
gem.add_development_dependency 'pry-nav', '0.3.0'
|
27
|
+
gem.add_development_dependency 'rake', '12.3.3'
|
28
|
+
gem.add_development_dependency 'reek', '5.4.0'
|
29
|
+
gem.add_development_dependency 'rspec', '3.8.0'
|
30
|
+
gem.add_development_dependency 'rspec-core', '3.8.0'
|
31
|
+
gem.add_development_dependency 'rspec-expectations', '3.8.3'
|
32
|
+
gem.add_development_dependency 'rspec-mocks', '3.8.0'
|
33
|
+
gem.add_development_dependency 'rspec-support', '3.8.0'
|
34
|
+
gem.add_development_dependency 'rubocop', '0.73.0'
|
35
|
+
gem.add_development_dependency 'rubocop-rspec', '1.33.0'
|
36
|
+
gem.add_development_dependency 'rubycritic', '4.1.0'
|
37
|
+
gem.add_development_dependency 'simplecov', '0.17.0'
|
38
|
+
gem.add_development_dependency 'yard', '0.9.19'
|
39
|
+
gem.add_development_dependency 'yardstick', '0.9.9'
|
34
40
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Sinclair::Matchers::AddClassMethod do
|
6
|
+
describe 'yard' do
|
7
|
+
describe '#to' do
|
8
|
+
context 'when checking against Class' do
|
9
|
+
let(:clazz) { Class.new(MyModel) }
|
10
|
+
|
11
|
+
let(:block) do
|
12
|
+
proc do
|
13
|
+
clazz.define_singleton_method(:new_method) { 2 }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it do
|
18
|
+
expect(&block).to add_class_method(:new_method).to(clazz)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Matchers::AddClassMethodTo do
|
6
|
+
describe 'yard' do
|
7
|
+
let(:klass) { Class.new(MyModel) }
|
8
|
+
|
9
|
+
let(:block) do
|
10
|
+
proc do
|
11
|
+
klass.define_singleton_method(:parent_name) { superclass.name }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it do
|
16
|
+
expect(&block).to add_class_method(:parent_name).to(klass)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/integration/yard/sinclair/matchers/{add_method_spec.rb → add_instance_method_spec.rb}
RENAMED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
RSpec.describe Sinclair::Matchers::
|
5
|
+
RSpec.describe Sinclair::Matchers::AddInstanceMethod do
|
6
6
|
describe 'yard' do
|
7
7
|
describe '#to' do
|
8
8
|
context 'when checking against Class' do
|
9
|
-
let(:clazz) { Class.new }
|
9
|
+
let(:clazz) { Class.new(MyModel) }
|
10
10
|
let(:builder) { Sinclair.new(clazz) }
|
11
11
|
|
12
12
|
before do
|
@@ -19,7 +19,7 @@ RSpec.describe Sinclair::Matchers::AddMethod do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
context 'when checking against instance' do
|
22
|
-
let(:clazz) { Class.new }
|
22
|
+
let(:clazz) { Class.new(MyModel) }
|
23
23
|
let(:builder) { Sinclair.new(clazz) }
|
24
24
|
let(:instance) { clazz.new }
|
25
25
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodDefinition::ClassBlockDefinition do
|
6
|
+
describe 'yard' do
|
7
|
+
describe '#build' do
|
8
|
+
subject(:method_definition) do
|
9
|
+
described_class.new(name) do
|
10
|
+
@x = @x.to_i**2 + 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:klass) { Class.new }
|
15
|
+
let(:name) { :sequence }
|
16
|
+
|
17
|
+
it 'adds a dynamic method' do
|
18
|
+
expect { method_definition.build(klass) }.to add_class_method(name).to(klass)
|
19
|
+
expect { klass.sequence }
|
20
|
+
.to change { klass.instance_variable_get(:@x) }.from(nil).to 1
|
21
|
+
expect(klass.sequence).to eq(2)
|
22
|
+
expect(klass.sequence).to eq(5)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'changes instance variable' do
|
26
|
+
method_definition.build(klass)
|
27
|
+
|
28
|
+
expect { klass.sequence }
|
29
|
+
.to change { klass.instance_variable_get(:@x) }
|
30
|
+
.from(nil).to 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodDefinition::ClassMethodDefinition do
|
6
|
+
describe 'yard' do
|
7
|
+
describe '#build' do
|
8
|
+
describe 'using block with cache option' do
|
9
|
+
subject(:method_definition) do
|
10
|
+
described_class.from(name, cached: true) do
|
11
|
+
@x = @x.to_i**2 + 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:klass) { Class.new }
|
16
|
+
let(:name) { :sequence }
|
17
|
+
|
18
|
+
it 'adds a dynamic method' do
|
19
|
+
expect { method_definition.build(klass) }.to add_class_method(name).to(klass)
|
20
|
+
expect { klass.sequence }
|
21
|
+
.to change { klass.instance_variable_get(:@x) }.from(nil).to 1
|
22
|
+
expect { klass.sequence }.not_to change(klass, :sequence)
|
23
|
+
expect(klass.instance_variable_get(:@sequence)).to eq(1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Sinclair::MethodDefinition::ClassStringDefinition do
|
4
|
+
describe 'yard' do
|
5
|
+
describe '#build' do
|
6
|
+
subject(:method_definition) do
|
7
|
+
described_class.new(name, code, cached: true)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:klass) { Class.new }
|
11
|
+
let(:code) { '@x = @x.to_i ** 2 + 1' }
|
12
|
+
let(:name) { :sequence }
|
13
|
+
|
14
|
+
it 'adds a dynamic method' do
|
15
|
+
expect { method_definition.build(klass) }.to add_class_method(name).to(klass)
|
16
|
+
expect { klass.sequence }
|
17
|
+
.to change { klass.instance_variable_get(:@x) }.from(nil).to(1)
|
18
|
+
expect { klass.sequence }.not_to change(klass, :sequence)
|
19
|
+
expect(klass.instance_variable_get(:@sequence)).to eq(1)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Sinclair::MethodDefinition::
|
3
|
+
describe Sinclair::MethodDefinition::InstanceBlockDefinition do
|
4
4
|
describe 'yard' do
|
5
5
|
describe '#build' do
|
6
6
|
subject(:method_definition) do
|
7
|
-
described_class.
|
7
|
+
described_class.new(name, cached: true) do
|
8
8
|
@x = @x.to_i**2 + 1
|
9
9
|
end
|
10
10
|
end
|