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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +4 -1
  3. data/Dockerfile +3 -3
  4. data/README.md +1 -1
  5. data/config/check_specs.yml +5 -0
  6. data/config/yardstick.yml +3 -0
  7. data/lib/sinclair.rb +26 -9
  8. data/lib/sinclair/config/methods_builder.rb +3 -1
  9. data/lib/sinclair/config_factory.rb +4 -2
  10. data/lib/sinclair/matchers/add_class_method_to.rb +1 -0
  11. data/lib/sinclair/method_builder.rb +61 -0
  12. data/lib/sinclair/method_builder/base.rb +67 -0
  13. data/lib/sinclair/method_builder/block_method_builder.rb +34 -0
  14. data/lib/sinclair/method_builder/string_method_builder.rb +50 -0
  15. data/lib/sinclair/method_definition.rb +38 -17
  16. data/lib/sinclair/method_definition/block_definition.rb +8 -94
  17. data/lib/sinclair/method_definition/block_helper.rb +46 -0
  18. data/lib/sinclair/method_definition/string_definition.rb +7 -66
  19. data/lib/sinclair/method_definitions.rb +16 -4
  20. data/lib/sinclair/version.rb +1 -1
  21. data/sinclair.gemspec +1 -1
  22. data/spec/lib/sinclair/method_builder/block_method_builder_spec.rb +55 -0
  23. data/spec/lib/sinclair/method_builder/string_method_builder_spec.rb +54 -0
  24. data/spec/lib/sinclair/method_builder_spec.rb +53 -0
  25. data/spec/lib/sinclair/method_definition/block_definition_spec.rb +66 -0
  26. data/spec/lib/sinclair/method_definition/block_helper_spec.rb +111 -0
  27. data/spec/lib/sinclair/method_definition/string_definition_spec.rb +70 -0
  28. data/spec/lib/sinclair/method_definition_spec.rb +23 -88
  29. data/spec/lib/sinclair/method_definitions_spec.rb +45 -0
  30. data/spec/support/models/random_generator.rb +13 -0
  31. metadata +18 -20
  32. data/lib/sinclair/method_definition/class_block_definition.rb +0 -22
  33. data/lib/sinclair/method_definition/class_method_definition.rb +0 -50
  34. data/lib/sinclair/method_definition/class_string_definition.rb +0 -24
  35. data/lib/sinclair/method_definition/instance_block_definition.rb +0 -22
  36. data/lib/sinclair/method_definition/instance_method_definition.rb +0 -48
  37. data/lib/sinclair/method_definition/instance_string_definition.rb +0 -24
  38. data/spec/integration/yard/sinclair/method_definition/class_block_definition_spec.rb +0 -34
  39. data/spec/integration/yard/sinclair/method_definition/class_method_definition_spec.rb +0 -28
  40. data/spec/integration/yard/sinclair/method_definition/class_string_definition_spec.rb +0 -23
  41. data/spec/integration/yard/sinclair/method_definition/instance_block_definition_spec.rb +0 -25
  42. data/spec/integration/yard/sinclair/method_definition/instance_method_definition_spec.rb +0 -35
  43. data/spec/integration/yard/sinclair/method_definition/instance_string_definition_spec.rb +0 -32
  44. data/spec/lib/sinclair/method_definition/class_block_definition_spec.rb +0 -29
  45. data/spec/lib/sinclair/method_definition/class_string_definition_spec.rb +0 -27
  46. data/spec/lib/sinclair/method_definition/instance_block_definition_spec.rb +0 -30
  47. 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
- # Adds the instance method to given klass
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
- # @private
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
- # Returns proc block when {#cached?} as full
117
- #
42
+ # Block with code to be added as method
118
43
  # @return [Proc]
119
- def full_cached_method_proc(method_name, inner_block)
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
- # Adds the method to given klass
23
- #
24
- # @param klass [Class] class which will receive the new method
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
- # MyModel.instance_variable_get(:@sequence) # returns 1
71
- # MyModel.instance_variable_get(:@x) # returns 1
72
- def build(klass)
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 < Array
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(definition_class, name, code = nil, **options, &block)
25
- self << definition_class.from(name, code, **options, &block)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.4.2'
4
+ VERSION = '1.5.0'
5
5
  end
@@ -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.19'
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