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 +4 -4
- data/README.md +42 -12
- data/config/check_specs.yml +2 -2
- data/config/yardstick.yml +2 -0
- data/lib/sinclair/method_builder/base.rb +15 -0
- data/lib/sinclair/method_builder/block_method_builder.rb +1 -12
- data/lib/sinclair/method_builder/call_method_builder.rb +0 -17
- data/lib/sinclair/method_builder/string_method_builder.rb +2 -29
- data/lib/sinclair/method_builder.rb +2 -3
- data/lib/sinclair/method_definition/parameter_builder.rb +89 -0
- data/lib/sinclair/method_definition/parameter_helper.rb +124 -0
- data/lib/sinclair/method_definition/string_definition.rb +24 -2
- data/lib/sinclair/method_definition.rb +3 -2
- data/lib/sinclair/version.rb +1 -1
- data/spec/integration/readme/sinclair/types_of_definition_spec.rb +14 -0
- data/spec/lib/sinclair/method_builder/string_method_builder_spec.rb +24 -1
- data/spec/lib/sinclair/method_definition/parameter_builder_spec.rb +81 -0
- data/spec/lib/sinclair/method_definition/parameter_helper_spec.rb +47 -0
- data/spec/lib/sinclair/method_definition/string_definition_spec.rb +60 -29
- data/spec/lib/sinclair/method_definition_spec.rb +12 -2
- data/spec/support/models/dummy_builder.rb +1 -0
- data/spec/support/models/dummy_class_builder.rb +1 -0
- data/spec/support/shared_examples/sinclair.rb +6 -0
- metadata +6 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b14d0d24d28075129d870b9f2b93c306e894407a70878d7950e0c73e7f747dbb
         | 
| 4 | 
            +
              data.tar.gz: 5a3d836d3b8eb5dc299dd17836e50f387fe3273820e91ef95581aac25348407d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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. | 
| 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. | 
| 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. | 
| 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 | 
            -
             | 
| 294 | 
            -
            instance = klass.new
         | 
| 302 | 
            +
            # Example without parameters
         | 
| 295 303 |  | 
| 296 | 
            -
             | 
| 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 | 
            -
             | 
| 337 | 
            +
            class MyClass
         | 
| 338 | 
            +
            end
         | 
| 309 339 |  | 
| 310 | 
            -
            builder = Sinclair.new( | 
| 340 | 
            +
            builder = Sinclair.new(MyClass)
         | 
| 311 341 | 
             
            builder.add_class_method(:attr_accessor, :number, type: :call)
         | 
| 312 342 | 
             
            builder.build
         | 
| 313 343 |  | 
| 314 | 
            -
             | 
| 315 | 
            -
             | 
| 316 | 
            -
             | 
| 344 | 
            +
            MyClass.number # returns nil
         | 
| 345 | 
            +
            MyClass.number = 10
         | 
| 346 | 
            +
            MyClass.number # returns 10
         | 
| 317 347 | 
             
            ```
         | 
| 318 348 | 
             
            </details>
         | 
| 319 349 |  | 
    
        data/config/check_specs.yml
    CHANGED
    
    | @@ -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 | 
            -
                     | 
| 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 | 
            -
                     | 
| 17 | 
            +
                    evaluating_class.module_eval(code_definition, __FILE__, __LINE__ + 1)
         | 
| 18 18 | 
             
                  end
         | 
| 19 19 |  | 
| 20 | 
            -
                   | 
| 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 : | 
| 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 : | 
| 15 | 
            +
                autoload :ParameterBuilder, 'sinclair/method_definition/parameter_builder'
         | 
| 16 | 
            +
                autoload :ParameterHelper,  'sinclair/method_definition/parameter_helper'
         | 
| 16 17 |  | 
| 17 18 | 
             
                # @method name
         | 
| 18 19 | 
             
                #
         | 
    
        data/lib/sinclair/version.rb
    CHANGED
    
    
| @@ -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,  | 
| 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 '# | 
| 15 | 
            -
                let(:klass) | 
| 16 | 
            -
                let(:instance) | 
| 17 | 
            -
                let(: | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
                   | 
| 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( | 
| 25 | 
            -
                    . | 
| 27 | 
            +
                  expect(definition.code_definition.gsub(/^ */, ''))
         | 
| 28 | 
            +
                    .to eq(expected_code.gsub(/^ */, ''))
         | 
| 26 29 | 
             
                end
         | 
| 27 30 |  | 
| 28 | 
            -
                context 'when  | 
| 29 | 
            -
                  let(:options) { {  | 
| 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. | 
| 33 | 
            -
                      .to eq( | 
| 43 | 
            +
                    expect(definition.code_definition.gsub(/^ */, ''))
         | 
| 44 | 
            +
                      .to eq(expected_code.gsub(/^ */, ''))
         | 
| 34 45 | 
             
                  end
         | 
| 46 | 
            +
                end
         | 
| 35 47 |  | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 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 | 
            -
             | 
| 42 | 
            -
             | 
| 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 | 
            -
             | 
| 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 | 
            -
                     | 
| 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. | 
| 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( | 
| 60 | 
            -
                      .to eq(instance.instance_eval( | 
| 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 | 
            -
                       | 
| 29 | 
            -
             | 
| 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. | 
| 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- | 
| 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
         |