sinclair 1.11.0 → 1.12.1

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 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