sinclair 1.4.2 → 1.5.0

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