sinclair 1.11.0 → 1.12.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c6050b1049de69dd4ba37327f3b0d8e92e1a570ec5f6372ff91b1732bbc3be7
4
- data.tar.gz: 68c4c64e8d414bb81d250f180c5f3a6a7f3c180751247a3360b497e53693cf78
3
+ metadata.gz: b14d0d24d28075129d870b9f2b93c306e894407a70878d7950e0c73e7f747dbb
4
+ data.tar.gz: 5a3d836d3b8eb5dc299dd17836e50f387fe3273820e91ef95581aac25348407d
5
5
  SHA512:
6
- metadata.gz: 11a89d1a3b77320298c2027ac33a2a12d7ff57ddda3792753b5e9d0495bb50b3d83904e12ee06b79b84aa615b8796b34c5d087c905aee6a6f77e7d68bed39308
7
- data.tar.gz: '04833c0736f37c690b554c007f60a0226255e3730a30c57b5f3a26cb486571c50b0b9f4970e27f581b6829a264321e8277f8eed22592904b1e6af3616ca62328'
6
+ metadata.gz: c6bbf090685049aaa1936e632ed420060ccead6071bb9864de3b5e26f16ad68431b6d01de24442f4ac4ce87792158a5def414680fe9d6b941d4031b766bd386e
7
+ data.tar.gz: ef28a8f5b9f5b9e9e12cd36c558fe2bb14fededbea91df46cda1b2d8570d0fec22809dc3e36f4af61844da370ea659463df03562232883121d0ebc7f40a63e81
data/README.md CHANGED
@@ -13,13 +13,13 @@ This gem helps the creation of complex gems/concerns
13
13
  that enables creation of methods on the fly through class
14
14
  methods
15
15
 
16
- Current Release: [1.11.0](https://github.com/darthjee/sinclair/tree/1.11.0)
16
+ Current Release: [1.12.1](https://github.com/darthjee/sinclair/tree/1.12.1)
17
17
 
18
- [Next release](https://github.com/darthjee/sinclair/compare/1.11.0...master)
18
+ [Next release](https://github.com/darthjee/sinclair/compare/1.12.1...master)
19
19
 
20
20
  Yard Documentation
21
21
  -------------------
22
- [https://www.rubydoc.info/gems/sinclair/1.11.0](https://www.rubydoc.info/gems/sinclair/1.11.0)
22
+ [https://www.rubydoc.info/gems/sinclair/1.12.1](https://www.rubydoc.info/gems/sinclair/1.12.1)
23
23
 
24
24
  Installation
25
25
  ---------------
@@ -270,10 +270,14 @@ invalid_object.valid? # returns false
270
270
  </details>
271
271
 
272
272
  #### Different ways of adding the methods
273
- There are different ways to add a method
273
+ There are different ways to add a method, each accepting different options
274
+
274
275
  <details>
275
276
  <summary>Define method using block</summary>
276
277
 
278
+ Block methods accepts, as option
279
+ - [cache](#caching-the-result): defining the cashing of results
280
+
277
281
  ```ruby
278
282
  klass = Class.new
279
283
  instance = klass.new
@@ -289,31 +293,57 @@ instance.random_number # returns a number between 10 and 20
289
293
  <details>
290
294
  <summary>Define method using string</summary>
291
295
 
296
+ String methods accepts, as option
297
+ - [cache](#caching-the-result): defining the cashing of results
298
+ - parameters: defining accepted parameters
299
+ - named_parameters: defining accepted named parameters
300
+
292
301
  ```ruby
293
- klass = Class.new
294
- instance = klass.new
302
+ # Example without parameters
295
303
 
296
- builder = Sinclair.new(klass)
304
+ class MyClass
305
+ end
306
+ instance = MyClass.new
307
+
308
+ builder = Sinclair.new(MyClass)
297
309
  builder.add_method(:random_number, "Random.rand(10..20)")
298
310
  builder.build
299
311
 
300
312
  instance.random_number # returns a number between 10 and 20
301
313
  ```
314
+
315
+ ```ruby
316
+ # Example with parameters
317
+
318
+ class MyClass
319
+ end
320
+
321
+ builder = described_class.new(MyClass)
322
+ builder.add_class_method(
323
+ :function, 'a ** b + c', parameters: [:a], named_parameters: [:b, { c: 15 }]
324
+ )
325
+ builder.build
326
+
327
+ MyClass.function(10, b: 2) # returns 115
328
+ ```
302
329
  </details>
303
330
 
304
331
  <details>
305
332
  <summary>Define method using a call to the class</summary>
306
333
 
334
+ Call method definitions right now have no options available
335
+
307
336
  ```ruby
308
- klass = Class.new
337
+ class MyClass
338
+ end
309
339
 
310
- builder = Sinclair.new(klass)
340
+ builder = Sinclair.new(MyClass)
311
341
  builder.add_class_method(:attr_accessor, :number, type: :call)
312
342
  builder.build
313
343
 
314
- klass.number # returns nil
315
- klass.number = 10
316
- klass.number # returns 10
344
+ MyClass.number # returns nil
345
+ MyClass.number = 10
346
+ MyClass.number # returns 10
317
347
  ```
318
348
  </details>
319
349
 
@@ -1,9 +1,9 @@
1
1
  ignore:
2
2
  - lib/sinclair/comparable/class_methods.rb
3
3
  - lib/sinclair/exception.rb
4
- - lib/sinclair/matchers/add_method_to.rb
5
4
  - lib/sinclair/matchers/add_method.rb
5
+ - lib/sinclair/matchers/add_method_to.rb
6
6
  - lib/sinclair/matchers/base.rb
7
- - lib/sinclair/matchers/method_to.rb
8
7
  - lib/sinclair/matchers/change_method_on.rb
8
+ - lib/sinclair/matchers/method_to.rb
9
9
  - lib/sinclair/version.rb
data/config/yardstick.yml CHANGED
@@ -60,6 +60,8 @@ rules:
60
60
  - Sinclair::MethodDefinition#initialize
61
61
  - Sinclair::MethodDefinition::CallDefinition#initialize
62
62
  - Sinclair::MethodDefinition::BlockDefinition#initialize
63
+ - Sinclair::MethodDefinition::ParameterBuilder#initialize
64
+ - Sinclair::MethodDefinition::ParameterHelper#initialize
63
65
  - Sinclair::MethodDefinition::StringDefinition#initialize
64
66
  - Sinclair::Options#initialize
65
67
  - Sinclair::Options::Builder#initialize
@@ -77,6 +77,21 @@ class Sinclair
77
77
  def instance?
78
78
  type == INSTANCE_METHOD
79
79
  end
80
+
81
+ # Returns the klass where the proc block will be evaluated
82
+ #
83
+ # For instance type, the class itself is returned
84
+ #
85
+ # For adding class methods, the superclass is returned
86
+ #
87
+ # @return [Class]
88
+ def evaluating_class
89
+ return klass if instance?
90
+
91
+ class << klass
92
+ return self
93
+ end
94
+ end
80
95
  end
81
96
  end
82
97
  end
@@ -14,21 +14,10 @@ class Sinclair
14
14
  #
15
15
  # @return (see Base#build)
16
16
  def build
17
- klass.send(method_definition, name, method_block)
17
+ evaluating_class.define_method(name, method_block)
18
18
  end
19
19
 
20
- private
21
-
22
20
  delegate :name, :method_block, to: :definition
23
-
24
- # @private
25
- #
26
- # name of the method used to define a new method on class
27
- #
28
- # @return [Symbol]
29
- def method_definition
30
- instance? ? :define_method : :define_singleton_method
31
- end
32
21
  end
33
22
  end
34
23
  end
@@ -19,8 +19,6 @@ class Sinclair
19
19
  evaluating_class.module_eval(&code_block)
20
20
  end
21
21
 
22
- private
23
-
24
22
  delegate :code_block, to: :definition
25
23
  # @method code_block
26
24
  # @api private
@@ -29,21 +27,6 @@ class Sinclair
29
27
  # Code block to be evaluated by the class
30
28
  #
31
29
  # @return [Proc]
32
-
33
- # Returns the klass where the proc block will be evaluated
34
- #
35
- # For instance type, the class itself is returned
36
- #
37
- # For adding class methods, the superclass is returned
38
- #
39
- # @return [Class]
40
- def evaluating_class
41
- return klass if instance?
42
-
43
- class << klass
44
- return self
45
- end
46
- end
47
30
  end
48
31
  end
49
32
  end
@@ -14,37 +14,10 @@ class Sinclair
14
14
  #
15
15
  # @return (see Base#build)
16
16
  def build
17
- klass.module_eval(code_definition, __FILE__, __LINE__ + 1)
17
+ evaluating_class.module_eval(code_definition, __FILE__, __LINE__ + 1)
18
18
  end
19
19
 
20
- private
21
-
22
- # @private
23
- #
24
- # string used for method name definition
25
- #
26
- # the string changes depending if it is
27
- # a class or instance method
28
- #
29
- # @return [String]
30
- def definition_name
31
- instance? ? name : "self.#{name}"
32
- end
33
-
34
- # @private
35
- #
36
- # string with the code to be defined
37
- #
38
- # @return [String]
39
- def code_definition
40
- <<-CODE
41
- def #{definition_name}
42
- #{code_line}
43
- end
44
- CODE
45
- end
46
-
47
- delegate :code_line, :name, to: :definition
20
+ delegate :code_definition, to: :definition
48
21
  end
49
22
  end
50
23
  end
@@ -7,10 +7,9 @@ class Sinclair
7
7
  # Class responsible for building methods
8
8
  class MethodBuilder
9
9
  autoload :Base, 'sinclair/method_builder/base'
10
- autoload :StringMethodBuilder, 'sinclair/method_builder/string_method_builder'
11
10
  autoload :BlockMethodBuilder, 'sinclair/method_builder/block_method_builder'
12
-
13
- autoload :CallMethodBuilder, 'sinclair/method_builder/call_method_builder'
11
+ autoload :CallMethodBuilder, 'sinclair/method_builder/call_method_builder'
12
+ autoload :StringMethodBuilder, 'sinclair/method_builder/string_method_builder'
14
13
 
15
14
  CLASS_METHOD = :class
16
15
  INSTANCE_METHOD = :instance
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class MethodDefinition
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Builder a string of parameters
9
+ #
10
+ # This is used when creating the string for a method defined
11
+ # using a string definition
12
+ #
13
+ # @see StringDefinition
14
+ class ParameterBuilder
15
+ # Builds a string representing method parameters
16
+ #
17
+ # @overload from(parameters, named_parameters)
18
+ # @param parameters [Array<Object>] List of parameters.
19
+ # @param named_parameters [Array<Object>] List of named parameters
20
+ #
21
+ # The list of +parameters+/+named_parameters+ is formed by an
22
+ # array of +Symbol+ representing required parameters
23
+ # and +Hash+ representing parameters with default values
24
+ #
25
+ # @return [String]
26
+ def self.from(*args)
27
+ new(*args).to_s
28
+ end
29
+
30
+ private_class_method :new
31
+
32
+ # @param parameters [Array<Object>] List of parameters.
33
+ # @param named_parameters [Array<Object>] List of named parameters
34
+ def initialize(parameters, named_parameters)
35
+ @parameters = parameters
36
+ @named_parameters = named_parameters
37
+ end
38
+
39
+ # Returns the parameters string
40
+ #
41
+ # @return [String]
42
+ def to_s
43
+ return '' if empty_parameters?
44
+
45
+ "(#{parameters_string})"
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :parameters, :named_parameters
51
+
52
+ # @!method parameters
53
+ # @api private
54
+ # @private
55
+ #
56
+ # List of parameters
57
+ #
58
+ # @return [Array<Object>]
59
+
60
+ # @!method named_parameters
61
+ # @api private
62
+ # @private
63
+ #
64
+ # List of named parameters
65
+ #
66
+ # @return [Array<Object>]
67
+
68
+ # @private
69
+ # Flag if any kind of parameters have not been provided
70
+ #
71
+ # @return [TrueClass,FalseClass]
72
+ def empty_parameters?
73
+ !parameters.present? && !named_parameters.present?
74
+ end
75
+
76
+ # String of parameters witout ()
77
+ #
78
+ # This will join all individual parameters strings by +,+
79
+ #
80
+ # @return [String]
81
+ def parameters_string
82
+ (
83
+ ParameterHelper.parameters_from(parameters) +
84
+ ParameterHelper.parameters_from(named_parameters, named: true)
85
+ ).join(', ')
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class MethodDefinition
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Helper containing helepr methods for remapping parameters
9
+ #
10
+ # @see ParameterBuilder
11
+ class ParameterHelper
12
+ # Returns a list of strings of parameters
13
+ #
14
+ # @overload parameters_from(parameters_list, named: false)
15
+ # @param parameters_list [Array<Object>] list of parameters and defaults
16
+ # @param named [TrueClass,FalseClass] Flag informing if the parameters are
17
+ # named parameters
18
+ #
19
+ # @return [String]
20
+ def self.parameters_from(*args, **opts)
21
+ new(*args, **opts).strings
22
+ end
23
+
24
+ private_class_method :new
25
+
26
+ # @param parameters_list [Array<Object>] list of parameters and defaults
27
+ # @param named [TrueClass,FalseClass] Flag informing if the parameters are
28
+ # named parameters
29
+ def initialize(parameters_list, named: false)
30
+ @parameters_list = parameters_list
31
+ @named = named
32
+ end
33
+
34
+ # All parameters converted into strings
35
+ #
36
+ # The strings are ready to be pushed into a method definition
37
+ # and joined by +,+
38
+ #
39
+ # @return [Array<String>]
40
+ def strings
41
+ return [] unless parameters_list
42
+
43
+ parameters_strings + defaults_strings
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :parameters_list, :named
49
+ alias named? named
50
+
51
+ # @!method parameters_list
52
+ # @api private
53
+ # @private
54
+ #
55
+ # List of parameters and parameters with defaults
56
+ #
57
+ # @return [Array<Object>]
58
+
59
+ # @!method named
60
+ # @api private
61
+ # @private
62
+ #
63
+ # Flag informing if the parameters are named parameters
64
+ #
65
+ # @return [TrueClass,FalseClass]
66
+
67
+ # @!method named?
68
+ # @api private
69
+ # @private
70
+ #
71
+ # Flag informing if the parameters are named parameters
72
+ #
73
+ # @return [TrueClass,FalseClass]
74
+
75
+ # Parameters without defaults
76
+ #
77
+ # These are filtered out from {#parameters_list} where they are not
78
+ # of type +Hash+
79
+ #
80
+ # @return [Array<Symbol>]
81
+ def parameters
82
+ parameters_list.reject do |param|
83
+ param.is_a?(Hash)
84
+ end
85
+ end
86
+
87
+ # Hash representing all parameters with default values
88
+ #
89
+ # These are filtered out from {#parameters_list} where they are
90
+ # of type +Hash+ and merged into a single hash
91
+ #
92
+ # @return [Hash]
93
+ def defaults
94
+ parameters_list.select do |param|
95
+ param.is_a?(Hash)
96
+ end.reduce(&:merge) || {}
97
+ end
98
+
99
+ # Parameters without default converted to final string
100
+ #
101
+ # {#extra} is added so that for normal parameters the parameter is returned
102
+ # and for named parameter +:+ is added
103
+ #
104
+ # @return [Array<String>]
105
+ def parameters_strings
106
+ return parameters.map(&:to_s) unless named?
107
+
108
+ parameters.map do |param|
109
+ "#{param}:"
110
+ end
111
+ end
112
+
113
+ # Strings representing all parameters with default value
114
+ #
115
+ # @return [Array<String>]
116
+ def defaults_strings
117
+ joinner = named? ? ': ' : ' = '
118
+ defaults.map do |key, value|
119
+ "#{key}#{joinner}#{value.to_json}"
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -22,6 +22,30 @@ class Sinclair
22
22
  default_value :block?, false
23
23
  default_value :string?, true
24
24
 
25
+ # string with the code to be defined
26
+ #
27
+ # @return [String]
28
+ def code_definition
29
+ <<-CODE
30
+ def #{name}#{parameters_string}
31
+ #{code_line}
32
+ end
33
+ CODE
34
+ end
35
+
36
+ private
37
+
38
+ # @private
39
+ # String for parameters
40
+ #
41
+ # @return [String]
42
+ def parameters_string
43
+ ParameterBuilder.from(
44
+ options_object.parameters, options_object.named_parameters
45
+ )
46
+ end
47
+
48
+ # @private
25
49
  # codeline to be run inside the code
26
50
  #
27
51
  # @return [String]
@@ -29,8 +53,6 @@ class Sinclair
29
53
  cached? ? code_with_cache : code
30
54
  end
31
55
 
32
- private
33
-
34
56
  # @method code
35
57
  # @private
36
58
  #
@@ -10,9 +10,10 @@ class Sinclair
10
10
 
11
11
  autoload :BlockHelper, 'sinclair/method_definition/block_helper'
12
12
  autoload :BlockDefinition, 'sinclair/method_definition/block_definition'
13
+ autoload :CallDefinition, 'sinclair/method_definition/call_definition'
13
14
  autoload :StringDefinition, 'sinclair/method_definition/string_definition'
14
-
15
- autoload :CallDefinition, 'sinclair/method_definition/call_definition'
15
+ autoload :ParameterBuilder, 'sinclair/method_definition/parameter_builder'
16
+ autoload :ParameterHelper, 'sinclair/method_definition/parameter_helper'
16
17
 
17
18
  # @method name
18
19
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.11.0'
4
+ VERSION = '1.12.1'
5
5
  end
@@ -30,6 +30,20 @@ describe Sinclair do
30
30
  end
31
31
  end
32
32
 
33
+ describe 'Define method using string with parameters' do
34
+ it 'adds the method' do
35
+ klass = Class.new
36
+
37
+ builder = described_class.new(klass)
38
+ builder.add_class_method(
39
+ :function, 'a ** b + c', parameters: [:a], named_parameters: [:b, { c: 15 }]
40
+ )
41
+ builder.build
42
+
43
+ expect(klass.function(10, b: 2)).to eq(115)
44
+ end
45
+ end
46
+
33
47
  describe 'Define method using call to the class' do
34
48
  it 'performs the call to the class' do
35
49
  klass = Class.new
@@ -12,9 +12,11 @@ describe Sinclair::MethodBuilder::StringMethodBuilder do
12
12
  let(:instance) { klass.new }
13
13
  let(:value) { Random.rand }
14
14
  let(:method_name) { :the_method }
15
+ let(:code) { value.to_s }
16
+ let(:options) { {} }
15
17
 
16
18
  let(:definition) do
17
- Sinclair::MethodDefinition.from(method_name, value.to_s)
19
+ Sinclair::MethodDefinition.from(method_name, code, **options)
18
20
  end
19
21
 
20
22
  context 'when type is instance' do
@@ -31,6 +33,27 @@ describe Sinclair::MethodBuilder::StringMethodBuilder do
31
33
  it 'returns the result of the code when called' do
32
34
  expect(instance.the_method).to eq(value)
33
35
  end
36
+
37
+ it 'creates a method with no parameters' do
38
+ expect(instance.method(method_name).parameters)
39
+ .to be_empty
40
+ end
41
+ end
42
+
43
+ context 'when the method is built with parameters' do
44
+ let(:code) { 'a + b' }
45
+ let(:options) { { parameters: %i[a b] } }
46
+
47
+ before { builder.build }
48
+
49
+ it 'returns the result of the code when called' do
50
+ expect(instance.the_method(12, 23)).to eq(35)
51
+ end
52
+
53
+ it 'creates a method with no parameters' do
54
+ expect(instance.method(method_name).parameters)
55
+ .to eq([%i[req a], %i[req b]])
56
+ end
34
57
  end
35
58
  end
36
59
 
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::ParameterBuilder do
6
+ describe '.from' do
7
+ let(:parameters) { nil }
8
+ let(:named_parameters) { nil }
9
+
10
+ context 'when parameters and named_parameters are nil' do
11
+ it do
12
+ expect(described_class.from(parameters, named_parameters))
13
+ .to eq('')
14
+ end
15
+ end
16
+
17
+ context 'when parameters is empty' do
18
+ let(:parameters) { [] }
19
+
20
+ it do
21
+ expect(described_class.from(parameters, named_parameters))
22
+ .to eq('')
23
+ end
24
+ end
25
+
26
+ context 'when named_parameters is empty' do
27
+ let(:named_parameters) { [] }
28
+
29
+ it do
30
+ expect(described_class.from(parameters, named_parameters))
31
+ .to eq('')
32
+ end
33
+ end
34
+
35
+ context 'when parameters has no default values' do
36
+ let(:parameters) { %i[x y] }
37
+
38
+ it do
39
+ expect(described_class.from(parameters, named_parameters))
40
+ .to eq('(x, y)')
41
+ end
42
+ end
43
+
44
+ context 'when named_parameters has no default values' do
45
+ let(:named_parameters) { %i[x y] }
46
+
47
+ it do
48
+ expect(described_class.from(parameters, named_parameters))
49
+ .to eq('(x:, y:)')
50
+ end
51
+ end
52
+
53
+ context 'when parameters has only default values' do
54
+ let(:parameters) { [{ x: 1, y: 3 }] }
55
+
56
+ it do
57
+ expect(described_class.from(parameters, named_parameters))
58
+ .to eq('(x = 1, y = 3)')
59
+ end
60
+ end
61
+
62
+ context 'when named parameters has only default values' do
63
+ let(:named_parameters) { [{ x: 1, y: 3 }] }
64
+
65
+ it do
66
+ expect(described_class.from(parameters, named_parameters))
67
+ .to eq('(x: 1, y: 3)')
68
+ end
69
+ end
70
+
71
+ context 'when all options are present' do
72
+ let(:parameters) { [:x, { y: 2 }] }
73
+ let(:named_parameters) { [:a, { b: 3 }] }
74
+
75
+ it do
76
+ expect(described_class.from(parameters, named_parameters))
77
+ .to eq('(x, y = 2, a:, b: 3)')
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::ParameterHelper do
6
+ describe '.parameters_from' do
7
+ context 'when parameters are not named' do
8
+ context 'when there are no defaults' do
9
+ it 'returns a list of parameters' do
10
+ expect(described_class.parameters_from(%i[a b]))
11
+ .to eq(%w[a b])
12
+ end
13
+ end
14
+
15
+ context 'when there are defaults' do
16
+ let(:parameters) do
17
+ [{ a: 10, b: 'word', c: true, d: false }]
18
+ end
19
+
20
+ it 'returns a list of parameters' do
21
+ expect(described_class.parameters_from(parameters))
22
+ .to eq(['a = 10', 'b = "word"', 'c = true', 'd = false'])
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'when parameters are named' do
28
+ context 'when there are no defaults' do
29
+ it 'returns a list of parameters' do
30
+ expect(described_class.parameters_from(%i[a b], named: true))
31
+ .to eq(%w[a: b:])
32
+ end
33
+ end
34
+
35
+ context 'when there are defaults' do
36
+ let(:parameters) do
37
+ [{ a: 10, b: 'word', c: true, d: false }]
38
+ end
39
+
40
+ it 'returns a list of parameters' do
41
+ expect(described_class.parameters_from(parameters, named: true))
42
+ .to eq(['a: 10', 'b: "word"', 'c: true', 'd: false'])
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -11,59 +11,90 @@ describe Sinclair::MethodDefinition::StringDefinition do
11
11
  let(:code) { 'Random.rand' }
12
12
  let(:options) { {} }
13
13
 
14
- describe '#code_line' do
15
- let(:klass) { Class.new }
16
- let(:instance) { klass.new }
17
- let(:code_line) { definition.code_line }
18
-
19
- it 'returns the code' do
20
- expect(definition.code_line).to eq(code)
14
+ describe '#code_definition' do
15
+ let(:klass) { Class.new }
16
+ let(:instance) { klass.new }
17
+ let(:code_definition) { definition.code_definition }
18
+ let(:expected_code) do
19
+ <<-CODE
20
+ def #{method_name}
21
+ #{code}
22
+ end
23
+ CODE
21
24
  end
22
25
 
23
26
  it 'returns a code with no cache' do
24
- expect(instance.instance_eval(code_line))
25
- .not_to eq(instance.instance_eval(code_line))
27
+ expect(definition.code_definition.gsub(/^ */, ''))
28
+ .to eq(expected_code.gsub(/^ */, ''))
26
29
  end
27
30
 
28
- context 'when cache true is given' do
29
- let(:options) { { cached: true } }
31
+ context 'when parameters are given with defaults' do
32
+ let(:options) { { parameters: [:x, { y: 10 }] } }
33
+ let(:code) { 'x + y' }
34
+ let(:expected_code) do
35
+ <<-CODE
36
+ def #{method_name}(x, y = 10)
37
+ #{code}
38
+ end
39
+ CODE
40
+ end
30
41
 
31
42
  it 'returns the code with simple cache' do
32
- expect(definition.code_line)
33
- .to eq("@#{method_name} ||= #{code}")
43
+ expect(definition.code_definition.gsub(/^ */, ''))
44
+ .to eq(expected_code.gsub(/^ */, ''))
34
45
  end
46
+ end
35
47
 
36
- it 'returns a code with cache' do
37
- expect(instance.instance_eval(code_line))
38
- .to eq(instance.instance_eval(code_line))
48
+ context 'when parameters are given' do
49
+ let(:options) { { parameters: %i[x y] } }
50
+ let(:code) { 'x + y' }
51
+ let(:expected_code) do
52
+ <<-CODE
53
+ def #{method_name}(x, y)
54
+ #{code}
55
+ end
56
+ CODE
57
+ end
58
+
59
+ it 'returns the code with simple cache' do
60
+ expect(definition.code_definition.gsub(/^ */, ''))
61
+ .to eq(expected_code.gsub(/^ */, ''))
39
62
  end
63
+ end
40
64
 
41
- it 'returns a code that does not cache nil' do
42
- instance.instance_variable_set("@#{method_name}", nil)
65
+ context 'when cache true is given' do
66
+ let(:options) { { cached: true } }
67
+ let(:expected_code) do
68
+ <<-CODE
69
+ def #{method_name}
70
+ @#{method_name} ||= #{code}
71
+ end
72
+ CODE
73
+ end
43
74
 
44
- expect(instance.instance_eval(code_line)).not_to be_nil
75
+ it 'returns the code with simple cache' do
76
+ expect(definition.code_definition.gsub(/^ */, ''))
77
+ .to eq(expected_code.gsub(/^ */, ''))
45
78
  end
46
79
  end
47
80
 
48
81
  context 'when cache full is given' do
49
82
  let(:options) { { cached: :full } }
50
83
  let(:expected) do
51
- "defined?(@#{method_name}) ? @#{method_name} : (@#{method_name} = #{code})"
84
+ <<-CODE
85
+ def #{method_name}
86
+ defined?(@#{method_name}) ? @#{method_name} : (@#{method_name} = #{code})
87
+ end
88
+ CODE
52
89
  end
53
90
 
54
91
  it 'returns the code with full cache' do
55
- expect(definition.code_line).to eq(expected)
92
+ expect(definition.code_definition.gsub(/^ */, '')).to eq(expected.gsub(/^ */, ''))
56
93
  end
57
94
 
58
95
  it 'returns a code with cache' do
59
- expect(instance.instance_eval(code_line))
60
- .to eq(instance.instance_eval(code_line))
61
- end
62
-
63
- it 'returns a code that caches nil' do
64
- instance.instance_variable_set("@#{method_name}", nil)
65
-
66
- expect(instance.instance_eval(code_line)).to be_nil
96
+ expect(instance.instance_eval(code_definition))
97
+ .to eq(instance.instance_eval(code_definition))
67
98
  end
68
99
  end
69
100
  end
@@ -25,8 +25,18 @@ describe Sinclair::MethodDefinition do
25
25
  context 'when the builder has been defined' do
26
26
  let(:definition_class) do
27
27
  Class.new(described_class) do
28
- def code_line
29
- '10'
28
+ attr_reader :name
29
+
30
+ def initialize(name)
31
+ @name = name
32
+ end
33
+
34
+ def code_definition
35
+ <<-CODE
36
+ def #{name}
37
+ 10
38
+ end
39
+ CODE
30
40
  end
31
41
  end
32
42
  end
@@ -5,6 +5,7 @@ class Sinclair
5
5
  def init
6
6
  add_method(:blocked) { 1 }
7
7
  add_method(:defined, "@value = value + #{options_object&.increment || 1}")
8
+ add_method(:sum, 'x + y', parameters: %i[x y])
8
9
  add_method(:value, cached: true) { 0 }
9
10
  add_method(:type_block, type: :block) { 3 }
10
11
  add_method(:type_string, '10', type: :string)
@@ -5,6 +5,7 @@ class Sinclair
5
5
  def init
6
6
  add_class_method(:blocked) { 1 }
7
7
  add_class_method(:defined, "@value = value + #{options_object&.increment || 1}")
8
+ add_class_method(:sum, 'x + y', parameters: %i[x y])
8
9
  add_class_method(:value, '@value ||= 0')
9
10
  add_class_method(:type_block, type: :block) { 3 }
10
11
  add_class_method(:type_string, '10', type: :string)
@@ -26,6 +26,12 @@ RSpec.shared_examples 'A sinclair builder' do |type|
26
26
  expect(object.defined).to eq(1)
27
27
  expect(object.defined).to eq(2)
28
28
  end
29
+
30
+ context 'when the method has custom parameters' do
31
+ it 'creates a method using the string definition' do
32
+ expect(object.sum(10, 23)).to eq(33)
33
+ end
34
+ end
29
35
  end
30
36
 
31
37
  context 'when describing a method using a block specific type' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinclair
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarthJee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-10 00:00:00.000000000 Z
11
+ date: 2023-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -308,6 +308,8 @@ files:
308
308
  - lib/sinclair/method_definition/block_definition.rb
309
309
  - lib/sinclair/method_definition/block_helper.rb
310
310
  - lib/sinclair/method_definition/call_definition.rb
311
+ - lib/sinclair/method_definition/parameter_builder.rb
312
+ - lib/sinclair/method_definition/parameter_helper.rb
311
313
  - lib/sinclair/method_definition/string_definition.rb
312
314
  - lib/sinclair/method_definitions.rb
313
315
  - lib/sinclair/options.rb
@@ -377,6 +379,8 @@ files:
377
379
  - spec/lib/sinclair/method_definition/block_definition_spec.rb
378
380
  - spec/lib/sinclair/method_definition/block_helper_spec.rb
379
381
  - spec/lib/sinclair/method_definition/call_definition_spec.rb
382
+ - spec/lib/sinclair/method_definition/parameter_builder_spec.rb
383
+ - spec/lib/sinclair/method_definition/parameter_helper_spec.rb
380
384
  - spec/lib/sinclair/method_definition/string_definition_spec.rb
381
385
  - spec/lib/sinclair/method_definition_spec.rb
382
386
  - spec/lib/sinclair/method_definitions_spec.rb