fix 1.0.0.beta3 → 1.0.0.beta7
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/LICENSE.md +1 -1
- data/README.md +59 -38
- data/lib/fix.rb +12 -15
- data/lib/fix/doc.rb +24 -0
- data/lib/fix/dsl.rb +113 -0
- data/lib/fix/matcher.rb +209 -0
- data/lib/fix/requirement.rb +162 -0
- data/lib/fix/run.rb +55 -0
- data/lib/fix/set.rb +97 -0
- data/lib/kernel.rb +29 -2
- metadata +96 -35
- data/lib/fix/context.rb +0 -147
- data/lib/fix/expectation_result_not_found_error.rb +0 -5
- data/lib/fix/it.rb +0 -31
- data/lib/fix/suspicious_success_error.rb +0 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 81f6a38942f7037e0250876038e1a715b9b905d5fb2186fb1b3dc3884ebee446
         | 
| 4 | 
            +
              data.tar.gz: 76f805fc42a2683236ed85efbc888c25fadfaeb2f975177127101e4eb8ae2618
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c0ae0f82dd15aff8f14252631c2c8cf134bd6ce78ba814267f53e7b88a5d84ff2c7d14bb753152f51cea595f46a0284ae58d370e6e50f74fa6c6ec7bb7dcace1
         | 
| 7 | 
            +
              data.tar.gz: 983e9f29a66982ab2cfef0548b50c064c0b63605acdb0f055da6f35cfd2153f667bf3d58975f6d274b49101d557149336e3a6c465549cfa3658f758903024617
         | 
    
        data/LICENSE.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,31 +1,44 @@ | |
| 1 1 | 
             
            # Fix
         | 
| 2 2 |  | 
| 3 | 
            -
            [](https://fixrb.dev/)
         | 
| 4 | 
            +
            [](https://github.com/fixrb/fix/releases)
         | 
| 5 | 
            +
            [](https://rubydoc.info/github/fixrb/fix/main)
         | 
| 6 | 
            +
            [](https://github.com/fixrb/fix/actions?query=workflow%3Aci+branch%3Amain)
         | 
| 7 | 
            +
            [](https://github.com/fixrb/fix/actions?query=workflow%3Arubocop+branch%3Amain)
         | 
| 8 | 
            +
            [](https://github.com/fixrb/fix/raw/main/LICENSE.md)
         | 
| 9 9 |  | 
| 10 | 
            -
             | 
| 10 | 
            +
            ⚠️ This project is still in the experimental phase. May be used at your own risk.
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ## Project goals
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            * Extract specs from the tests.
         | 
| 17 | 
            +
            * Look like English documents.
         | 
| 18 | 
            +
            * Be minimalist and easy to hack.
         | 
| 19 | 
            +
            * Run tests quickly.
         | 
| 11 20 |  | 
| 12 21 | 
             
            ## Installation
         | 
| 13 22 |  | 
| 14 23 | 
             
            Add this line to your application's Gemfile:
         | 
| 15 24 |  | 
| 16 25 | 
             
            ```ruby
         | 
| 17 | 
            -
            gem  | 
| 26 | 
            +
            gem "fix", ">= 1.0.0.beta7"
         | 
| 18 27 | 
             
            ```
         | 
| 19 28 |  | 
| 20 29 | 
             
            And then execute:
         | 
| 21 30 |  | 
| 22 | 
            -
             | 
| 31 | 
            +
            ```sh
         | 
| 32 | 
            +
            bundle
         | 
| 33 | 
            +
            ```
         | 
| 23 34 |  | 
| 24 35 | 
             
            Or install it yourself as:
         | 
| 25 36 |  | 
| 26 | 
            -
             | 
| 37 | 
            +
            ```sh
         | 
| 38 | 
            +
            gem install fix --pre
         | 
| 39 | 
            +
            ```
         | 
| 27 40 |  | 
| 28 | 
            -
            ##  | 
| 41 | 
            +
            ## Example
         | 
| 29 42 |  | 
| 30 43 | 
             
            Given this app:
         | 
| 31 44 |  | 
| @@ -33,59 +46,74 @@ Given this app: | |
| 33 46 | 
             
            # examples/duck/app.rb
         | 
| 34 47 | 
             
            class Duck
         | 
| 35 48 | 
             
              def walks
         | 
| 36 | 
            -
                 | 
| 49 | 
            +
                "Klop klop!"
         | 
| 37 50 | 
             
              end
         | 
| 38 51 |  | 
| 39 52 | 
             
              def swims
         | 
| 40 | 
            -
                 | 
| 53 | 
            +
                "Swoosh..."
         | 
| 41 54 | 
             
              end
         | 
| 42 55 |  | 
| 43 56 | 
             
              def quacks
         | 
| 44 | 
            -
                puts  | 
| 57 | 
            +
                puts "Quaaaaaack!"
         | 
| 45 58 | 
             
              end
         | 
| 46 59 | 
             
            end
         | 
| 47 60 | 
             
            ```
         | 
| 48 61 |  | 
| 49 | 
            -
             | 
| 62 | 
            +
            And this fixed behavior:
         | 
| 50 63 |  | 
| 51 64 | 
             
            ```ruby
         | 
| 52 65 | 
             
            # examples/duck/fix.rb
         | 
| 53 | 
            -
            require_relative 'app'
         | 
| 54 | 
            -
            require_relative '../../lib/fix'
         | 
| 55 66 |  | 
| 56 | 
            -
             | 
| 67 | 
            +
            relative "fix"
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            Fix :Duck do
         | 
| 70 | 
            +
              it SHOULD be_an_instance_of :Duck
         | 
| 57 71 |  | 
| 58 | 
            -
            Fix(@bird) do
         | 
| 59 72 | 
             
              on :swims do
         | 
| 60 | 
            -
                it  | 
| 73 | 
            +
                it MUST be_an_instance_of :String
         | 
| 74 | 
            +
                it MUST eql "Swoosh..."
         | 
| 61 75 | 
             
              end
         | 
| 62 76 |  | 
| 63 77 | 
             
              on :speaks do
         | 
| 64 | 
            -
                it  | 
| 78 | 
            +
                it MUST raise_exception NoMethodError
         | 
| 65 79 | 
             
              end
         | 
| 66 80 |  | 
| 67 81 | 
             
              on :sings do
         | 
| 68 | 
            -
                it  | 
| 82 | 
            +
                it MAY eql "♪... ♫..."
         | 
| 69 83 | 
             
              end
         | 
| 70 84 | 
             
            end
         | 
| 71 85 | 
             
            ```
         | 
| 72 86 |  | 
| 73 | 
            -
             | 
| 87 | 
            +
            When I run this test:
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            ```ruby
         | 
| 90 | 
            +
            # examples/duck/test.rb
         | 
| 91 | 
            +
             | 
| 92 | 
            +
            require_relative "app"
         | 
| 93 | 
            +
            require_relative "fix"
         | 
| 94 | 
            +
             | 
| 95 | 
            +
            Fix[:Duck].test { Duck.new }
         | 
| 96 | 
            +
            ```
         | 
| 74 97 |  | 
| 75 98 | 
             
            ```sh
         | 
| 76 | 
            -
            ruby examples/duck/ | 
| 99 | 
            +
            ruby examples/duck/test.rb
         | 
| 77 100 | 
             
            ```
         | 
| 78 101 |  | 
| 102 | 
            +
            I should see this output:
         | 
| 103 | 
            +
             | 
| 79 104 | 
             
            ```txt
         | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 105 | 
            +
            Success: expected #<Duck:0x00007fc55b3c6388> to be an instance of Duck.
         | 
| 106 | 
            +
            Success: expected to eql "Swoosh...".
         | 
| 107 | 
            +
            Success: undefined method `speaks' for #<Duck:0x00007fc55b3c46f0>.
         | 
| 108 | 
            +
            NoMethodError: undefined method `sings' for #<Duck:0x00007fc558aab6d8>.
         | 
| 83 109 | 
             
            ```
         | 
| 84 110 |  | 
| 85 111 | 
             
            ## Contact
         | 
| 86 112 |  | 
| 87 | 
            -
            * Home page: https://fixrb.dev/
         | 
| 88 | 
            -
            * Source code: https://github.com/fixrb/fix
         | 
| 113 | 
            +
            * Home page: [https://fixrb.dev/](https://fixrb.dev/)
         | 
| 114 | 
            +
            * Source code: [https://github.com/fixrb/fix](https://github.com/fixrb/fix)
         | 
| 115 | 
            +
            * API Doc: [https://rubydoc.info/gems/fix](https://rubydoc.info/gems/fix)
         | 
| 116 | 
            +
            * Twitter: [https://twitter.com/fix\_rb](https://twitter.com/fix\_rb)
         | 
| 89 117 |  | 
| 90 118 | 
             
            ## Versioning
         | 
| 91 119 |  | 
| @@ -93,20 +121,13 @@ __Fix__ follows [Semantic Versioning 2.0](https://semver.org/). | |
| 93 121 |  | 
| 94 122 | 
             
            ## License
         | 
| 95 123 |  | 
| 96 | 
            -
            The gem is available as open source under the terms of the [MIT License](https:// | 
| 124 | 
            +
            The [gem](https://rubygems.org/gems/fix) is available as open source under the terms of the [MIT License](https://github.com/fixrb/fix/raw/main/LICENSE.md).
         | 
| 97 125 |  | 
| 98 126 | 
             
            ***
         | 
| 99 127 |  | 
| 100 128 | 
             
            <p>
         | 
| 101 129 | 
             
              This project is sponsored by:<br />
         | 
| 102 130 | 
             
              <a href="https://sashite.com/"><img
         | 
| 103 | 
            -
                src="https://github.com/fixrb/fix/raw/ | 
| 131 | 
            +
                src="https://github.com/fixrb/fix/raw/main/img/sashite.png"
         | 
| 104 132 | 
             
                alt="Sashite" /></a>
         | 
| 105 133 | 
             
            </p>
         | 
| 106 | 
            -
             | 
| 107 | 
            -
            [travis]: https://travis-ci.org/fixrb/fix
         | 
| 108 | 
            -
            [codeclimate]: https://codeclimate.com/github/fixrb/fix
         | 
| 109 | 
            -
            [gem]: https://rubygems.org/gems/fix
         | 
| 110 | 
            -
            [inchpages]: https://inch-ci.org/github/fixrb/fix
         | 
| 111 | 
            -
            [rubydoc]: https://rubydoc.info/gems/fix/frames
         | 
| 112 | 
            -
            [gitter]: https://gitter.im/fixrb/fix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
         | 
    
        data/lib/fix.rb
    CHANGED
    
    | @@ -1,25 +1,22 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require_relative File.join("fix", "set")
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require_relative "kernel"
         | 
| 6 | 
            +
             | 
| 3 7 | 
             
            # Namespace for the Fix framework.
         | 
| 4 8 | 
             
            #
         | 
| 9 | 
            +
            # @api public
         | 
| 5 10 | 
             
            module Fix
         | 
| 6 | 
            -
              #  | 
| 11 | 
            +
              # Test a built specification.
         | 
| 7 12 | 
             
              #
         | 
| 8 | 
            -
              # @example  | 
| 9 | 
            -
              #    | 
| 10 | 
            -
              #     it { MUST equal 42 }
         | 
| 11 | 
            -
              #   end
         | 
| 13 | 
            +
              # @example Run _Answer_ specification against `42`.
         | 
| 14 | 
            +
              #   Fix[:Answer].test(42)
         | 
| 12 15 | 
             
              #
         | 
| 13 | 
            -
              # @param  | 
| 14 | 
            -
              # @param options      [Hash]        Some options.
         | 
| 15 | 
            -
              # @param specs        [Proc]        The set of specs.
         | 
| 16 | 
            +
              # @param name [String, Symbol] The name of the specification document.
         | 
| 16 17 | 
             
              #
         | 
| 17 | 
            -
              # @ | 
| 18 | 
            -
              def self. | 
| 19 | 
            -
                 | 
| 20 | 
            -
                c.instance_eval(&block)
         | 
| 18 | 
            +
              # @return [::Fix::Test] The specification document.
         | 
| 19 | 
            +
              def self.[](name)
         | 
| 20 | 
            +
                ::Fix::Set.load(name)
         | 
| 21 21 | 
             
              end
         | 
| 22 22 | 
             
            end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
            require_relative 'kernel'
         | 
| 25 | 
            -
            require_relative File.join('fix', 'context')
         | 
    
        data/lib/fix/doc.rb
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Fix
         | 
| 4 | 
            +
              # Module for storing spec documents.
         | 
| 5 | 
            +
              #
         | 
| 6 | 
            +
              # @api private
         | 
| 7 | 
            +
              module Doc
         | 
| 8 | 
            +
                # @param name [String, Symbol] The name of the specification document.
         | 
| 9 | 
            +
                def self.fetch(name)
         | 
| 10 | 
            +
                  const_get("#{name}::CONTEXTS")
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # @param contexts [Array<::Fix::Dsl>] The list of contexts document.
         | 
| 14 | 
            +
                def self.specs(*contexts)
         | 
| 15 | 
            +
                  contexts.flat_map do |context|
         | 
| 16 | 
            +
                    env = context.new
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    env.public_methods(false).map do |public_method|
         | 
| 19 | 
            +
                      [env] + env.public_send(public_method)
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
    
        data/lib/fix/dsl.rb
    ADDED
    
    | @@ -0,0 +1,113 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "defi"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require_relative "matcher"
         | 
| 6 | 
            +
            require_relative "requirement"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            module Fix
         | 
| 9 | 
            +
              # Abstract class for handling the domain-specific language.
         | 
| 10 | 
            +
              #
         | 
| 11 | 
            +
              # @api private
         | 
| 12 | 
            +
              class Dsl
         | 
| 13 | 
            +
                extend Matcher
         | 
| 14 | 
            +
                extend Requirement
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                # Sets a user-defined property.
         | 
| 17 | 
            +
                #
         | 
| 18 | 
            +
                # @example
         | 
| 19 | 
            +
                #   require "fix"
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                #   Fix do
         | 
| 22 | 
            +
                #     let(:name) { "Bob" }
         | 
| 23 | 
            +
                #   end
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                # @param name   [String, Symbol] The name of the property.
         | 
| 26 | 
            +
                # @param block  [Proc] The content of the method to define.
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                # @return [Symbol] A private method that define the block content.
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
                # @api public
         | 
| 31 | 
            +
                def self.let(name, &block)
         | 
| 32 | 
            +
                  private define_method(name, &block)
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # Defines an example group with user-defined properties that describes a
         | 
| 36 | 
            +
                # unit to be tested.
         | 
| 37 | 
            +
                #
         | 
| 38 | 
            +
                # @example
         | 
| 39 | 
            +
                #   require "fix"
         | 
| 40 | 
            +
                #
         | 
| 41 | 
            +
                #   Fix do
         | 
| 42 | 
            +
                #     with :password, "secret" do
         | 
| 43 | 
            +
                #       it MUST be true
         | 
| 44 | 
            +
                #     end
         | 
| 45 | 
            +
                #   end
         | 
| 46 | 
            +
                #
         | 
| 47 | 
            +
                # @param kwargs [Hash] The list of propreties.
         | 
| 48 | 
            +
                # @param block [Proc] The block to define the specs.
         | 
| 49 | 
            +
                #
         | 
| 50 | 
            +
                # @api public
         | 
| 51 | 
            +
                def self.with(**kwargs, &block)
         | 
| 52 | 
            +
                  klass = ::Class.new(self)
         | 
| 53 | 
            +
                  klass.const_get(:CONTEXTS) << klass
         | 
| 54 | 
            +
                  kwargs.each { |name, value| klass.let(name) { value } }
         | 
| 55 | 
            +
                  klass.instance_eval(&block)
         | 
| 56 | 
            +
                  klass
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                # Defines an example group that describes a unit to be tested.
         | 
| 60 | 
            +
                #
         | 
| 61 | 
            +
                # @example
         | 
| 62 | 
            +
                #   require "fix"
         | 
| 63 | 
            +
                #
         | 
| 64 | 
            +
                #   Fix do
         | 
| 65 | 
            +
                #     on :+, 2 do
         | 
| 66 | 
            +
                #       it MUST be 42
         | 
| 67 | 
            +
                #     end
         | 
| 68 | 
            +
                #   end
         | 
| 69 | 
            +
                #
         | 
| 70 | 
            +
                # @param method_name [String, Symbol] The method to send to the subject.
         | 
| 71 | 
            +
                # @param block [Proc] The block to define the specs.
         | 
| 72 | 
            +
                #
         | 
| 73 | 
            +
                # @api public
         | 
| 74 | 
            +
                def self.on(method_name, *args, **kwargs, &block)
         | 
| 75 | 
            +
                  klass = ::Class.new(self)
         | 
| 76 | 
            +
                  klass.const_get(:CONTEXTS) << klass
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  const_set("Child#{block.object_id}", klass)
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  klass.define_singleton_method(:challenges) do
         | 
| 81 | 
            +
                    challenge = ::Defi.send(method_name, *args, **kwargs)
         | 
| 82 | 
            +
                    super() + [challenge]
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  klass.instance_eval(&block)
         | 
| 86 | 
            +
                  klass
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                # Defines a concrete spec definition.
         | 
| 90 | 
            +
                #
         | 
| 91 | 
            +
                # @example
         | 
| 92 | 
            +
                #   require "fix"
         | 
| 93 | 
            +
                #
         | 
| 94 | 
            +
                #   Fix { it MUST be 42 }
         | 
| 95 | 
            +
                #
         | 
| 96 | 
            +
                # @api public
         | 
| 97 | 
            +
                def self.it(requirement)
         | 
| 98 | 
            +
                  location = caller_locations(1, 1).fetch(0)
         | 
| 99 | 
            +
                  location = [location.path, location.lineno].join(":")
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  define_method("test_#{requirement.object_id}") do
         | 
| 102 | 
            +
                    [location, requirement, self.class.challenges]
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                # The list of challenges to be addressed to the object to be tested.
         | 
| 107 | 
            +
                #
         | 
| 108 | 
            +
                # @return [Array<Defi::Challenge>] A list of challenges.
         | 
| 109 | 
            +
                def self.challenges
         | 
| 110 | 
            +
                  []
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
            end
         | 
    
        data/lib/fix/matcher.rb
    ADDED
    
    | @@ -0,0 +1,209 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "matchi"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Fix
         | 
| 6 | 
            +
              # Collection of expectation matchers.
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # @api private
         | 
| 9 | 
            +
              module Matcher
         | 
| 10 | 
            +
                # Equivalence matcher
         | 
| 11 | 
            +
                #
         | 
| 12 | 
            +
                # @example
         | 
| 13 | 
            +
                #   matcher = eq("foo")
         | 
| 14 | 
            +
                #   matcher.matches? { "foo" } # => true
         | 
| 15 | 
            +
                #   matcher.matches? { "bar" } # => false
         | 
| 16 | 
            +
                #
         | 
| 17 | 
            +
                # @param expected [#eql?] An expected equivalent object.
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # @return [#matches?] An equivalence matcher.
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # @api public
         | 
| 22 | 
            +
                def eq(expected)
         | 
| 23 | 
            +
                  ::Matchi::Eq.new(expected)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                alias eql eq
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # Identity matcher
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
                # @example
         | 
| 31 | 
            +
                #   object = "foo"
         | 
| 32 | 
            +
                #   matcher = be(object)
         | 
| 33 | 
            +
                #   matcher.matches? { object } # => true
         | 
| 34 | 
            +
                #   matcher.matches? { "foo" } # => false
         | 
| 35 | 
            +
                #
         | 
| 36 | 
            +
                # @param expected [#equal?] The expected identical object.
         | 
| 37 | 
            +
                #
         | 
| 38 | 
            +
                # @return [#matches?] An identity matcher.
         | 
| 39 | 
            +
                #
         | 
| 40 | 
            +
                # @api public
         | 
| 41 | 
            +
                def be(expected)
         | 
| 42 | 
            +
                  ::Matchi::Be.new(expected)
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                alias equal be
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # Comparisons matcher
         | 
| 48 | 
            +
                #
         | 
| 49 | 
            +
                # @example
         | 
| 50 | 
            +
                #   matcher = be_within(1).of(41)
         | 
| 51 | 
            +
                #   matcher.matches? { 42 } # => true
         | 
| 52 | 
            +
                #   matcher.matches? { 43 } # => false
         | 
| 53 | 
            +
                #
         | 
| 54 | 
            +
                # @param delta [Numeric] A numeric value.
         | 
| 55 | 
            +
                #
         | 
| 56 | 
            +
                # @return [#matches?] A comparison matcher.
         | 
| 57 | 
            +
                #
         | 
| 58 | 
            +
                # @api public
         | 
| 59 | 
            +
                def be_within(delta)
         | 
| 60 | 
            +
                  ::Matchi::BeWithin.new(delta)
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                # Regular expressions matcher
         | 
| 64 | 
            +
                #
         | 
| 65 | 
            +
                # @example
         | 
| 66 | 
            +
                #   matcher = match(/^foo$/)
         | 
| 67 | 
            +
                #   matcher.matches? { "foo" } # => true
         | 
| 68 | 
            +
                #   matcher.matches? { "bar" } # => false
         | 
| 69 | 
            +
                #
         | 
| 70 | 
            +
                # @param expected [#match] A regular expression.
         | 
| 71 | 
            +
                #
         | 
| 72 | 
            +
                # @return [#matches?] A regular expression matcher.
         | 
| 73 | 
            +
                #
         | 
| 74 | 
            +
                # @api public
         | 
| 75 | 
            +
                def match(expected)
         | 
| 76 | 
            +
                  ::Matchi::Match.new(expected)
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                # Expecting errors matcher
         | 
| 80 | 
            +
                #
         | 
| 81 | 
            +
                # @example
         | 
| 82 | 
            +
                #   matcher = raise_exception(NameError)
         | 
| 83 | 
            +
                #   matcher.matches? { Boom } # => true
         | 
| 84 | 
            +
                #   matcher.matches? { true } # => false
         | 
| 85 | 
            +
                #
         | 
| 86 | 
            +
                # @param expected [Exception, #to_s] The expected exception name.
         | 
| 87 | 
            +
                #
         | 
| 88 | 
            +
                # @return [#matches?] An error matcher.
         | 
| 89 | 
            +
                #
         | 
| 90 | 
            +
                # @api public
         | 
| 91 | 
            +
                def raise_exception(expected)
         | 
| 92 | 
            +
                  ::Matchi::RaiseException.new(expected)
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                # True matcher
         | 
| 96 | 
            +
                #
         | 
| 97 | 
            +
                # @example
         | 
| 98 | 
            +
                #   matcher = be_true
         | 
| 99 | 
            +
                #   matcher.matches? { true } # => true
         | 
| 100 | 
            +
                #   matcher.matches? { false } # => false
         | 
| 101 | 
            +
                #   matcher.matches? { nil } # => false
         | 
| 102 | 
            +
                #   matcher.matches? { 4 } # => false
         | 
| 103 | 
            +
                #
         | 
| 104 | 
            +
                # @return [#matches?] A `true` matcher.
         | 
| 105 | 
            +
                #
         | 
| 106 | 
            +
                # @api public
         | 
| 107 | 
            +
                def be_true
         | 
| 108 | 
            +
                  be(true)
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                # False matcher
         | 
| 112 | 
            +
                #
         | 
| 113 | 
            +
                # @example
         | 
| 114 | 
            +
                #   matcher = be_false
         | 
| 115 | 
            +
                #   matcher.matches? { false } # => true
         | 
| 116 | 
            +
                #   matcher.matches? { true } # => false
         | 
| 117 | 
            +
                #   matcher.matches? { nil } # => false
         | 
| 118 | 
            +
                #   matcher.matches? { 4 } # => false
         | 
| 119 | 
            +
                #
         | 
| 120 | 
            +
                # @return [#matches?] A `false` matcher.
         | 
| 121 | 
            +
                #
         | 
| 122 | 
            +
                # @api public
         | 
| 123 | 
            +
                def be_false
         | 
| 124 | 
            +
                  be(false)
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                # Nil matcher
         | 
| 128 | 
            +
                #
         | 
| 129 | 
            +
                # @example
         | 
| 130 | 
            +
                #   matcher = be_nil
         | 
| 131 | 
            +
                #   matcher.matches? { nil } # => true
         | 
| 132 | 
            +
                #   matcher.matches? { false } # => false
         | 
| 133 | 
            +
                #   matcher.matches? { true } # => false
         | 
| 134 | 
            +
                #   matcher.matches? { 4 } # => false
         | 
| 135 | 
            +
                #
         | 
| 136 | 
            +
                # @return [#matches?] A `nil` matcher.
         | 
| 137 | 
            +
                #
         | 
| 138 | 
            +
                # @api public
         | 
| 139 | 
            +
                def be_nil
         | 
| 140 | 
            +
                  be(nil)
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                # Type/class matcher
         | 
| 144 | 
            +
                #
         | 
| 145 | 
            +
                # @example
         | 
| 146 | 
            +
                #   matcher = be_an_instance_of(String)
         | 
| 147 | 
            +
                #   matcher.matches? { "foo" } # => true
         | 
| 148 | 
            +
                #   matcher.matches? { 4 } # => false
         | 
| 149 | 
            +
                #
         | 
| 150 | 
            +
                # @param expected [Class, #to_s] The expected class name.
         | 
| 151 | 
            +
                #
         | 
| 152 | 
            +
                # @return [#matches?] A type/class matcher.
         | 
| 153 | 
            +
                #
         | 
| 154 | 
            +
                # @api public
         | 
| 155 | 
            +
                def be_an_instance_of(expected)
         | 
| 156 | 
            +
                  ::Matchi::BeAnInstanceOf.new(expected)
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                # Change matcher
         | 
| 160 | 
            +
                #
         | 
| 161 | 
            +
                # @example
         | 
| 162 | 
            +
                #   object = []
         | 
| 163 | 
            +
                #   matcher = change(object, :length).by(1)
         | 
| 164 | 
            +
                #   matcher.matches? { object << 1 } # => true
         | 
| 165 | 
            +
                #
         | 
| 166 | 
            +
                #   object = []
         | 
| 167 | 
            +
                #   matcher = change(object, :length).by_at_least(1)
         | 
| 168 | 
            +
                #   matcher.matches? { object << 1 } # => true
         | 
| 169 | 
            +
                #
         | 
| 170 | 
            +
                #   object = []
         | 
| 171 | 
            +
                #   matcher = change(object, :length).by_at_most(1)
         | 
| 172 | 
            +
                #   matcher.matches? { object << 1 } # => true
         | 
| 173 | 
            +
                #
         | 
| 174 | 
            +
                #   object = "foo"
         | 
| 175 | 
            +
                #   matcher = change(object, :to_s).from("foo").to("FOO")
         | 
| 176 | 
            +
                #   matcher.matches? { object.upcase! } # => true
         | 
| 177 | 
            +
                #
         | 
| 178 | 
            +
                #   object = "foo"
         | 
| 179 | 
            +
                #   matcher = change(object, :to_s).to("FOO")
         | 
| 180 | 
            +
                #   matcher.matches? { object.upcase! } # => true
         | 
| 181 | 
            +
                #
         | 
| 182 | 
            +
                # @param object [#object_id]  An object.
         | 
| 183 | 
            +
                # @param method [Symbol]      The name of a method.
         | 
| 184 | 
            +
                # @param args   [Array]       A list of arguments.
         | 
| 185 | 
            +
                # @param kwargs [Hash]        A list of keyword arguments.
         | 
| 186 | 
            +
                #
         | 
| 187 | 
            +
                # @return [#matches?] A change matcher.
         | 
| 188 | 
            +
                #
         | 
| 189 | 
            +
                # @api public
         | 
| 190 | 
            +
                def change(object, method, *args, **kwargs, &block)
         | 
| 191 | 
            +
                  ::Matchi::Change.new(object, method, *args, **kwargs, &block)
         | 
| 192 | 
            +
                end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                # Satisfy matcher
         | 
| 195 | 
            +
                #
         | 
| 196 | 
            +
                # @example
         | 
| 197 | 
            +
                #   matcher = satisfy { |value| value == 42 }
         | 
| 198 | 
            +
                #   matcher.matches? { 42 } # => true
         | 
| 199 | 
            +
                #
         | 
| 200 | 
            +
                # @param expected [Proc] A block of code.
         | 
| 201 | 
            +
                #
         | 
| 202 | 
            +
                # @return [#matches?] A satisfy matcher.
         | 
| 203 | 
            +
                #
         | 
| 204 | 
            +
                # @api public
         | 
| 205 | 
            +
                def satisfy(&expected)
         | 
| 206 | 
            +
                  ::Matchi::Satisfy.new(&expected)
         | 
| 207 | 
            +
                end
         | 
| 208 | 
            +
              end
         | 
| 209 | 
            +
            end
         | 
| @@ -0,0 +1,162 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "spectus/requirement/optional"
         | 
| 4 | 
            +
            require "spectus/requirement/recommended"
         | 
| 5 | 
            +
            require "spectus/requirement/required"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Fix
         | 
| 8 | 
            +
              # Collection of expectation matchers.
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              # @api private
         | 
| 11 | 
            +
              module Requirement
         | 
| 12 | 
            +
                # rubocop:disable Naming/MethodName
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # This method mean that the definition is an absolute requirement of the
         | 
| 15 | 
            +
                # specification.
         | 
| 16 | 
            +
                #
         | 
| 17 | 
            +
                # @param matcher [#matches?] The matcher.
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # @return [Requirement::Required] An absolute requirement level instance.
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # @api public
         | 
| 22 | 
            +
                def MUST(matcher)
         | 
| 23 | 
            +
                  ::Spectus::Requirement::Required.new(
         | 
| 24 | 
            +
                    isolate: false,
         | 
| 25 | 
            +
                    negate:  false,
         | 
| 26 | 
            +
                    matcher: matcher
         | 
| 27 | 
            +
                  )
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                # @see MUST
         | 
| 31 | 
            +
                #
         | 
| 32 | 
            +
                # @api public
         | 
| 33 | 
            +
                def MUST!(matcher)
         | 
| 34 | 
            +
                  ::Spectus::Requirement::Required.new(
         | 
| 35 | 
            +
                    isolate: true,
         | 
| 36 | 
            +
                    negate:  false,
         | 
| 37 | 
            +
                    matcher: matcher
         | 
| 38 | 
            +
                  )
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                # This method mean that the definition is an absolute prohibition of the specification.
         | 
| 42 | 
            +
                #
         | 
| 43 | 
            +
                # @param matcher [#matches?] The matcher.
         | 
| 44 | 
            +
                #
         | 
| 45 | 
            +
                # @return [Requirement::Required] An absolute prohibition level instance.
         | 
| 46 | 
            +
                #
         | 
| 47 | 
            +
                # @api public
         | 
| 48 | 
            +
                def MUST_NOT(matcher)
         | 
| 49 | 
            +
                  ::Spectus::Requirement::Required.new(
         | 
| 50 | 
            +
                    isolate: false,
         | 
| 51 | 
            +
                    negate:  true,
         | 
| 52 | 
            +
                    matcher: matcher
         | 
| 53 | 
            +
                  )
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                # @see MUST_NOT
         | 
| 57 | 
            +
                #
         | 
| 58 | 
            +
                # @api public
         | 
| 59 | 
            +
                def MUST_NOT!(matcher)
         | 
| 60 | 
            +
                  ::Spectus::Requirement::Required.new(
         | 
| 61 | 
            +
                    isolate: true,
         | 
| 62 | 
            +
                    negate:  true,
         | 
| 63 | 
            +
                    matcher: matcher
         | 
| 64 | 
            +
                  )
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                # This method mean that there may exist valid reasons in particular
         | 
| 68 | 
            +
                # circumstances to ignore a particular item, but the full implications must be
         | 
| 69 | 
            +
                # understood and carefully weighed before choosing a different course.
         | 
| 70 | 
            +
                #
         | 
| 71 | 
            +
                # @param matcher [#matches?] The matcher.
         | 
| 72 | 
            +
                #
         | 
| 73 | 
            +
                # @return [Requirement::Recommended] A recommended requirement level instance.
         | 
| 74 | 
            +
                #
         | 
| 75 | 
            +
                # @api public
         | 
| 76 | 
            +
                def SHOULD(matcher)
         | 
| 77 | 
            +
                  ::Spectus::Requirement::Recommended.new(
         | 
| 78 | 
            +
                    isolate: false,
         | 
| 79 | 
            +
                    negate:  false,
         | 
| 80 | 
            +
                    matcher: matcher
         | 
| 81 | 
            +
                  )
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                # @see SHOULD
         | 
| 85 | 
            +
                #
         | 
| 86 | 
            +
                # @api public
         | 
| 87 | 
            +
                def SHOULD!(matcher)
         | 
| 88 | 
            +
                  ::Spectus::Requirement::Recommended.new(
         | 
| 89 | 
            +
                    isolate: true,
         | 
| 90 | 
            +
                    negate:  false,
         | 
| 91 | 
            +
                    matcher: matcher
         | 
| 92 | 
            +
                  )
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                # This method mean that there may exist valid reasons in particular
         | 
| 96 | 
            +
                # circumstances when the particular behavior is acceptable or even useful, but
         | 
| 97 | 
            +
                # the full implications should be understood and the case carefully weighed
         | 
| 98 | 
            +
                # before implementing any behavior described with this label.
         | 
| 99 | 
            +
                #
         | 
| 100 | 
            +
                # @param matcher [#matches?] The matcher.
         | 
| 101 | 
            +
                #
         | 
| 102 | 
            +
                # @return [Requirement::Recommended] A not recommended requirement level
         | 
| 103 | 
            +
                #   instance.
         | 
| 104 | 
            +
                #
         | 
| 105 | 
            +
                # @api public
         | 
| 106 | 
            +
                def SHOULD_NOT(matcher)
         | 
| 107 | 
            +
                  ::Spectus::Requirement::Recommended.new(
         | 
| 108 | 
            +
                    isolate: false,
         | 
| 109 | 
            +
                    negate:  true,
         | 
| 110 | 
            +
                    matcher: matcher
         | 
| 111 | 
            +
                  )
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                # @see SHOULD_NOT
         | 
| 115 | 
            +
                #
         | 
| 116 | 
            +
                # @api public
         | 
| 117 | 
            +
                def SHOULD_NOT!(matcher)
         | 
| 118 | 
            +
                  ::Spectus::Requirement::Recommended.new(
         | 
| 119 | 
            +
                    isolate: true,
         | 
| 120 | 
            +
                    negate:  true,
         | 
| 121 | 
            +
                    matcher: matcher
         | 
| 122 | 
            +
                  )
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                # This method mean that an item is truly optional.
         | 
| 126 | 
            +
                # One vendor may choose to include the item because a particular marketplace
         | 
| 127 | 
            +
                # requires it or because the vendor feels that it enhances the product while
         | 
| 128 | 
            +
                # another vendor may omit the same item. An implementation which does not
         | 
| 129 | 
            +
                # include a particular option must be prepared to interoperate with another
         | 
| 130 | 
            +
                # implementation which does include the option, though perhaps with reduced
         | 
| 131 | 
            +
                # functionality. In the same vein an implementation which does include a
         | 
| 132 | 
            +
                # particular option must be prepared to interoperate with another
         | 
| 133 | 
            +
                # implementation which does not include the option (except, of course, for the
         | 
| 134 | 
            +
                # feature the option provides).
         | 
| 135 | 
            +
                #
         | 
| 136 | 
            +
                # @param matcher [#matches?] The matcher.
         | 
| 137 | 
            +
                #
         | 
| 138 | 
            +
                # @return [Requirement::Optional] An optional requirement level instance.
         | 
| 139 | 
            +
                #
         | 
| 140 | 
            +
                # @api public
         | 
| 141 | 
            +
                def MAY(matcher)
         | 
| 142 | 
            +
                  ::Spectus::Requirement::Optional.new(
         | 
| 143 | 
            +
                    isolate: false,
         | 
| 144 | 
            +
                    negate:  false,
         | 
| 145 | 
            +
                    matcher: matcher
         | 
| 146 | 
            +
                  )
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                # @see MAY
         | 
| 150 | 
            +
                #
         | 
| 151 | 
            +
                # @api public
         | 
| 152 | 
            +
                def MAY!(matcher)
         | 
| 153 | 
            +
                  ::Spectus::Requirement::Optional.new(
         | 
| 154 | 
            +
                    isolate: true,
         | 
| 155 | 
            +
                    negate:  false,
         | 
| 156 | 
            +
                    matcher: matcher
         | 
| 157 | 
            +
                  )
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                # rubocop:enable Naming/MethodName
         | 
| 161 | 
            +
              end
         | 
| 162 | 
            +
            end
         | 
    
        data/lib/fix/run.rb
    ADDED
    
    | @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "expresenter/fail"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Fix
         | 
| 6 | 
            +
              # Run class.
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # @api private
         | 
| 9 | 
            +
              class Run
         | 
| 10 | 
            +
                # @return [::Fix::Dsl] A context instance.
         | 
| 11 | 
            +
                attr_reader :environment
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # @return [::Spectus::Requirement::Base] An expectation.
         | 
| 14 | 
            +
                attr_reader :requirement
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                # @return [Array<::Defi::Challenge>] A list of challenges.
         | 
| 17 | 
            +
                attr_reader :challenges
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # @param environment  [::Fix::Dsl]                    A context instance.
         | 
| 20 | 
            +
                # @param requirement  [::Spectus::Requirement::Base]  An expectation.
         | 
| 21 | 
            +
                # @param challenges   [Array<::Defi::Challenge>]      A list of challenges.
         | 
| 22 | 
            +
                def initialize(environment, requirement, *challenges)
         | 
| 23 | 
            +
                  @environment = environment
         | 
| 24 | 
            +
                  @requirement = requirement
         | 
| 25 | 
            +
                  @challenges  = challenges
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # Verify if the object checks the condition.
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
                # @param subject [Proc] The block of code to be tested.
         | 
| 31 | 
            +
                #
         | 
| 32 | 
            +
                # @raise [::Expresenter::Fail] A failed spec exception.
         | 
| 33 | 
            +
                # @return [::Expresenter::Pass] A passed spec instance.
         | 
| 34 | 
            +
                #
         | 
| 35 | 
            +
                # @see https://github.com/fixrb/expresenter
         | 
| 36 | 
            +
                def against(&subject)
         | 
| 37 | 
            +
                  requirement.call { actual_value(&subject) }
         | 
| 38 | 
            +
                rescue ::Expresenter::Fail => e
         | 
| 39 | 
            +
                  e
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                private
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                # The test's actual value.
         | 
| 45 | 
            +
                #
         | 
| 46 | 
            +
                # @param subject [Proc] The block of code to be tested.
         | 
| 47 | 
            +
                #
         | 
| 48 | 
            +
                # @return [#object_id] The actual value to be tested.
         | 
| 49 | 
            +
                def actual_value(&subject)
         | 
| 50 | 
            +
                  challenges.inject(environment.instance_eval(&subject)) do |obj, challenge|
         | 
| 51 | 
            +
                    challenge.to(obj).call
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
    
        data/lib/fix/set.rb
    ADDED
    
    | @@ -0,0 +1,97 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "doc"
         | 
| 4 | 
            +
            require_relative "run"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Fix
         | 
| 7 | 
            +
              # Collection of specifications.
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              # @api private
         | 
| 10 | 
            +
              class Set
         | 
| 11 | 
            +
                # The type of result.
         | 
| 12 | 
            +
                #
         | 
| 13 | 
            +
                # Passed expectations can be classified as:
         | 
| 14 | 
            +
                #
         | 
| 15 | 
            +
                #  * `success`
         | 
| 16 | 
            +
                #  * `warning`
         | 
| 17 | 
            +
                #  * `info`
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # Failed expectations can be classified as:
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                #  * `failure`
         | 
| 22 | 
            +
                #  * `error`
         | 
| 23 | 
            +
                LOG_LEVELS = %w[
         | 
| 24 | 
            +
                  none
         | 
| 25 | 
            +
                  error
         | 
| 26 | 
            +
                  failure
         | 
| 27 | 
            +
                  warning
         | 
| 28 | 
            +
                  info
         | 
| 29 | 
            +
                  success
         | 
| 30 | 
            +
                ].freeze
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                # @return [Array] A list of specifications.
         | 
| 33 | 
            +
                attr_reader :specs
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # @param name [String, Symbol] The name of the specification document.
         | 
| 36 | 
            +
                #
         | 
| 37 | 
            +
                # @api public
         | 
| 38 | 
            +
                def self.load(name)
         | 
| 39 | 
            +
                  new(*Doc.fetch(name))
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                # @param contexts [Array<::Fix::Dsl>] The list of contexts document.
         | 
| 43 | 
            +
                def initialize(*contexts)
         | 
| 44 | 
            +
                  @specs  = Doc.specs(*contexts)
         | 
| 45 | 
            +
                  @passed = true
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                # @param subject [Proc] The block of code to be tested.
         | 
| 49 | 
            +
                #
         | 
| 50 | 
            +
                # @raise [::SystemExit] The result of the test.
         | 
| 51 | 
            +
                #
         | 
| 52 | 
            +
                # @api public
         | 
| 53 | 
            +
                def test(log_level: 5, &subject)
         | 
| 54 | 
            +
                  randomize!
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  specs.each do |environment, location, requirement, challenges|
         | 
| 57 | 
            +
                    runner = Run.new(environment, requirement, *challenges)
         | 
| 58 | 
            +
                    result = runner.against(&subject)
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    failed! if result.failed?
         | 
| 61 | 
            +
                    report!(location, result, log_level: log_level)
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  exit!
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                private
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def randomize!
         | 
| 70 | 
            +
                  specs.shuffle!
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                # @raise [::SystemExit] The result of the test.
         | 
| 74 | 
            +
                def exit!
         | 
| 75 | 
            +
                  ::Kernel.exit(passed?)
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def failed!
         | 
| 79 | 
            +
                  @passed = false
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                # @return [Boolean] The test set passed or failed.
         | 
| 83 | 
            +
                def passed?
         | 
| 84 | 
            +
                  @passed
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def report!(path, result, log_level:)
         | 
| 88 | 
            +
                  return unless report?(result, log_level: log_level)
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  puts "#{path} #{result.colored_string}"
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                def report?(result, log_level:)
         | 
| 94 | 
            +
                  LOG_LEVELS[1..log_level].any? { |name| result.public_send("#{name}?") }
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
            end
         | 
    
        data/lib/kernel.rb
    CHANGED
    
    | @@ -1,9 +1,36 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require_relative File.join("fix", "doc")
         | 
| 4 | 
            +
            require_relative File.join("fix", "dsl")
         | 
| 5 | 
            +
            require_relative File.join("fix", "set")
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            # The Kernel module.
         | 
| 3 8 | 
             
            module Kernel
         | 
| 4 9 | 
             
              # rubocop:disable Naming/MethodName
         | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 10 | 
            +
             | 
| 11 | 
            +
              # Specifications are built with this method.
         | 
| 12 | 
            +
              #
         | 
| 13 | 
            +
              # @example Require an answer equal to 42.
         | 
| 14 | 
            +
              #   # The spec
         | 
| 15 | 
            +
              #   Fix :Answer do
         | 
| 16 | 
            +
              #     it MUST equal 42
         | 
| 17 | 
            +
              #   end
         | 
| 18 | 
            +
              #
         | 
| 19 | 
            +
              #   # A test
         | 
| 20 | 
            +
              #   Fix[:Answer].test { 42 }
         | 
| 21 | 
            +
              #
         | 
| 22 | 
            +
              # @param name   [String, Symbol]  The name of the specification document.
         | 
| 23 | 
            +
              # @param block  [Proc]            The specifications.
         | 
| 24 | 
            +
              #
         | 
| 25 | 
            +
              # @return [#test] The collection of specifications.
         | 
| 26 | 
            +
              #
         | 
| 27 | 
            +
              # @api public
         | 
| 28 | 
            +
              def Fix(name = nil, &block)
         | 
| 29 | 
            +
                klass = ::Class.new(::Fix::Dsl)
         | 
| 30 | 
            +
                klass.const_set(:CONTEXTS, [klass])
         | 
| 31 | 
            +
                klass.instance_eval(&block)
         | 
| 32 | 
            +
                ::Fix::Doc.const_set(name, klass) unless name.nil?
         | 
| 33 | 
            +
                ::Fix::Set.new(*klass.const_get(:CONTEXTS))
         | 
| 7 34 | 
             
              end
         | 
| 8 35 | 
             
              # rubocop:enable Naming/MethodName
         | 
| 9 36 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: fix
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0.0. | 
| 4 | 
            +
              version: 1.0.0.beta7
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Cyril Kato
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-07-27 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: defi
         | 
| @@ -16,70 +16,84 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - "~>"
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: 2.0. | 
| 19 | 
            +
                    version: 2.0.5
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - "~>"
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: 2.0. | 
| 26 | 
            +
                    version: 2.0.5
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: matchi
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: 3.2.0
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: 3.2.0
         | 
| 27 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 42 | 
             
              name: spectus
         | 
| 29 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 44 | 
             
                requirements:
         | 
| 31 45 | 
             
                - - "~>"
         | 
| 32 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version:  | 
| 47 | 
            +
                    version: 4.0.2
         | 
| 34 48 | 
             
              type: :runtime
         | 
| 35 49 | 
             
              prerelease: false
         | 
| 36 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 51 | 
             
                requirements:
         | 
| 38 52 | 
             
                - - "~>"
         | 
| 39 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version:  | 
| 54 | 
            +
                    version: 4.0.2
         | 
| 41 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 56 | 
             
              name: bundler
         | 
| 43 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 58 | 
             
                requirements:
         | 
| 45 | 
            -
                - - " | 
| 59 | 
            +
                - - ">="
         | 
| 46 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            -
                    version: ' | 
| 61 | 
            +
                    version: '0'
         | 
| 48 62 | 
             
              type: :development
         | 
| 49 63 | 
             
              prerelease: false
         | 
| 50 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 65 | 
             
                requirements:
         | 
| 52 | 
            -
                - - " | 
| 66 | 
            +
                - - ">="
         | 
| 53 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            -
                    version: ' | 
| 68 | 
            +
                    version: '0'
         | 
| 55 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 70 | 
             
              name: rake
         | 
| 57 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 72 | 
             
                requirements:
         | 
| 59 | 
            -
                - - " | 
| 73 | 
            +
                - - ">="
         | 
| 60 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: ' | 
| 75 | 
            +
                    version: '0'
         | 
| 62 76 | 
             
              type: :development
         | 
| 63 77 | 
             
              prerelease: false
         | 
| 64 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 79 | 
             
                requirements:
         | 
| 66 | 
            -
                - - " | 
| 80 | 
            +
                - - ">="
         | 
| 67 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: ' | 
| 82 | 
            +
                    version: '0'
         | 
| 69 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            -
              name: rubocop
         | 
| 84 | 
            +
              name: rubocop-md
         | 
| 71 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 86 | 
             
                requirements:
         | 
| 73 | 
            -
                - - " | 
| 87 | 
            +
                - - ">="
         | 
| 74 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version: '0 | 
| 89 | 
            +
                    version: '0'
         | 
| 76 90 | 
             
              type: :development
         | 
| 77 91 | 
             
              prerelease: false
         | 
| 78 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 93 | 
             
                requirements:
         | 
| 80 | 
            -
                - - " | 
| 94 | 
            +
                - - ">="
         | 
| 81 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            -
                    version: '0 | 
| 96 | 
            +
                    version: '0'
         | 
| 83 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 98 | 
             
              name: rubocop-performance
         | 
| 85 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -94,35 +108,77 @@ dependencies: | |
| 94 108 | 
             
                - - ">="
         | 
| 95 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 110 | 
             
                    version: '0'
         | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: rubocop-rake
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '0'
         | 
| 118 | 
            +
              type: :development
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - ">="
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: '0'
         | 
| 125 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 126 | 
            +
              name: rubocop-rspec
         | 
| 127 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 | 
            +
                requirements:
         | 
| 129 | 
            +
                - - ">="
         | 
| 130 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            +
                    version: '0'
         | 
| 132 | 
            +
              type: :development
         | 
| 133 | 
            +
              prerelease: false
         | 
| 134 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 | 
            +
                requirements:
         | 
| 136 | 
            +
                - - ">="
         | 
| 137 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            +
                    version: '0'
         | 
| 139 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 140 | 
            +
              name: rubocop-thread_safety
         | 
| 141 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 142 | 
            +
                requirements:
         | 
| 143 | 
            +
                - - ">="
         | 
| 144 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 145 | 
            +
                    version: '0'
         | 
| 146 | 
            +
              type: :development
         | 
| 147 | 
            +
              prerelease: false
         | 
| 148 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 149 | 
            +
                requirements:
         | 
| 150 | 
            +
                - - ">="
         | 
| 151 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 152 | 
            +
                    version: '0'
         | 
| 97 153 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 154 | 
             
              name: simplecov
         | 
| 99 155 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 156 | 
             
                requirements:
         | 
| 101 | 
            -
                - - " | 
| 157 | 
            +
                - - ">="
         | 
| 102 158 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            -
                    version: '0 | 
| 159 | 
            +
                    version: '0'
         | 
| 104 160 | 
             
              type: :development
         | 
| 105 161 | 
             
              prerelease: false
         | 
| 106 162 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 163 | 
             
                requirements:
         | 
| 108 | 
            -
                - - " | 
| 164 | 
            +
                - - ">="
         | 
| 109 165 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            -
                    version: '0 | 
| 166 | 
            +
                    version: '0'
         | 
| 111 167 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 168 | 
             
              name: yard
         | 
| 113 169 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 170 | 
             
                requirements:
         | 
| 115 | 
            -
                - - " | 
| 171 | 
            +
                - - ">="
         | 
| 116 172 | 
             
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            -
                    version: '0 | 
| 173 | 
            +
                    version: '0'
         | 
| 118 174 | 
             
              type: :development
         | 
| 119 175 | 
             
              prerelease: false
         | 
| 120 176 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 177 | 
             
                requirements:
         | 
| 122 | 
            -
                - - " | 
| 178 | 
            +
                - - ">="
         | 
| 123 179 | 
             
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            -
                    version: '0 | 
| 125 | 
            -
            description: Specing framework | 
| 180 | 
            +
                    version: '0'
         | 
| 181 | 
            +
            description: Specing framework.
         | 
| 126 182 | 
             
            email: contact@cyril.email
         | 
| 127 183 | 
             
            executables: []
         | 
| 128 184 | 
             
            extensions: []
         | 
| @@ -131,16 +187,21 @@ files: | |
| 131 187 | 
             
            - LICENSE.md
         | 
| 132 188 | 
             
            - README.md
         | 
| 133 189 | 
             
            - lib/fix.rb
         | 
| 134 | 
            -
            - lib/fix/ | 
| 135 | 
            -
            - lib/fix/ | 
| 136 | 
            -
            - lib/fix/ | 
| 137 | 
            -
            - lib/fix/ | 
| 190 | 
            +
            - lib/fix/doc.rb
         | 
| 191 | 
            +
            - lib/fix/dsl.rb
         | 
| 192 | 
            +
            - lib/fix/matcher.rb
         | 
| 193 | 
            +
            - lib/fix/requirement.rb
         | 
| 194 | 
            +
            - lib/fix/run.rb
         | 
| 195 | 
            +
            - lib/fix/set.rb
         | 
| 138 196 | 
             
            - lib/kernel.rb
         | 
| 139 197 | 
             
            homepage: https://fixrb.dev/
         | 
| 140 198 | 
             
            licenses:
         | 
| 141 199 | 
             
            - MIT
         | 
| 142 200 | 
             
            metadata:
         | 
| 201 | 
            +
              bug_tracker_uri: https://github.com/fixrb/fix/issues
         | 
| 202 | 
            +
              documentation_uri: https://rubydoc.info/gems/fix
         | 
| 143 203 | 
             
              source_code_uri: https://github.com/fixrb/fix
         | 
| 204 | 
            +
              wiki_uri: https://github.com/fixrb/fix/wiki
         | 
| 144 205 | 
             
            post_install_message: 
         | 
| 145 206 | 
             
            rdoc_options: []
         | 
| 146 207 | 
             
            require_paths:
         | 
| @@ -149,15 +210,15 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 149 210 | 
             
              requirements:
         | 
| 150 211 | 
             
              - - ">="
         | 
| 151 212 | 
             
                - !ruby/object:Gem::Version
         | 
| 152 | 
            -
                  version: 2. | 
| 213 | 
            +
                  version: 2.7.0
         | 
| 153 214 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 154 215 | 
             
              requirements:
         | 
| 155 216 | 
             
              - - ">"
         | 
| 156 217 | 
             
                - !ruby/object:Gem::Version
         | 
| 157 218 | 
             
                  version: 1.3.1
         | 
| 158 219 | 
             
            requirements: []
         | 
| 159 | 
            -
            rubygems_version: 3.1. | 
| 220 | 
            +
            rubygems_version: 3.1.6
         | 
| 160 221 | 
             
            signing_key: 
         | 
| 161 222 | 
             
            specification_version: 4
         | 
| 162 | 
            -
            summary: Specing framework | 
| 223 | 
            +
            summary: Specing framework.
         | 
| 163 224 | 
             
            test_files: []
         | 
    
        data/lib/fix/context.rb
    DELETED
    
    | @@ -1,147 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'aw'
         | 
| 4 | 
            -
            require 'defi'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            module Fix
         | 
| 7 | 
            -
              # Wraps the target of challenge.
         | 
| 8 | 
            -
              class Context
         | 
| 9 | 
            -
                RESERVED_KEYWORDS = %i[
         | 
| 10 | 
            -
                  alias
         | 
| 11 | 
            -
                  and
         | 
| 12 | 
            -
                  begin
         | 
| 13 | 
            -
                  break
         | 
| 14 | 
            -
                  case
         | 
| 15 | 
            -
                  catch
         | 
| 16 | 
            -
                  class
         | 
| 17 | 
            -
                  def
         | 
| 18 | 
            -
                  defined?
         | 
| 19 | 
            -
                  do
         | 
| 20 | 
            -
                  else
         | 
| 21 | 
            -
                  elsif
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
                  ensure
         | 
| 24 | 
            -
                  fail
         | 
| 25 | 
            -
                  false
         | 
| 26 | 
            -
                  for
         | 
| 27 | 
            -
                  if
         | 
| 28 | 
            -
                  in
         | 
| 29 | 
            -
                  module
         | 
| 30 | 
            -
                  next
         | 
| 31 | 
            -
                  nil
         | 
| 32 | 
            -
                  not
         | 
| 33 | 
            -
                  or
         | 
| 34 | 
            -
                  raise
         | 
| 35 | 
            -
                  redo
         | 
| 36 | 
            -
                  rescue
         | 
| 37 | 
            -
                  retry
         | 
| 38 | 
            -
                  return
         | 
| 39 | 
            -
                  self
         | 
| 40 | 
            -
                  super
         | 
| 41 | 
            -
                  then
         | 
| 42 | 
            -
                  throw
         | 
| 43 | 
            -
                  true
         | 
| 44 | 
            -
                  undef
         | 
| 45 | 
            -
                  unless
         | 
| 46 | 
            -
                  until
         | 
| 47 | 
            -
                  when
         | 
| 48 | 
            -
                  while
         | 
| 49 | 
            -
                  yield
         | 
| 50 | 
            -
                ].freeze
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                attr_reader :callable
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                def initialize(subject, challenge, before_hooks_counter = 0, *hooks, **lets)
         | 
| 55 | 
            -
                  @subject      = subject
         | 
| 56 | 
            -
                  @callable     = challenge.to(subject)
         | 
| 57 | 
            -
                  @before_hooks = hooks[0, before_hooks_counter]
         | 
| 58 | 
            -
                  @after_hooks  = hooks[before_hooks_counter..-1]
         | 
| 59 | 
            -
                  @lets         = lets
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                def before(&block)
         | 
| 63 | 
            -
                  @before_hooks << block
         | 
| 64 | 
            -
                end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                def after(&block)
         | 
| 67 | 
            -
                  @after_hooks << block
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                def let(name, &block)
         | 
| 71 | 
            -
                  raise ::TypeError, "expected a Symbol, got #{name.class}" unless name.is_a?(::Symbol)
         | 
| 72 | 
            -
                  raise ::NameError, "wrong method name `#{name}'" unless name.match(/\A[a-z][a-z0-9_]+[?!]?\z/)
         | 
| 73 | 
            -
                  raise ::NameError, "reserved keyword name `#{name}'" if RESERVED_KEYWORDS.include?(name)
         | 
| 74 | 
            -
                  raise ::NameError, "reserved method name `#{name}'" if respond_to?(name, true) && !@lets.key?(name)
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                  @lets.update(name => block.call)
         | 
| 77 | 
            -
                rescue ::SystemExit => e
         | 
| 78 | 
            -
                  raise SuspiciousSuccessError, "attempt `#{name}' to bypass the tests" if e.success?
         | 
| 79 | 
            -
                  raise e
         | 
| 80 | 
            -
                end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                def let!(name, &block)
         | 
| 83 | 
            -
                  raise ::TypeError, "expected a Symbol, got #{name.class}" unless name.is_a?(::Symbol)
         | 
| 84 | 
            -
                  raise ::NameError, "wrong method name `#{name}'" unless name.match(/\A[a-z][a-z0-9_]+[?!]?\z/)
         | 
| 85 | 
            -
                  raise ::NameError, "reserved keyword name `#{name}'" if RESERVED_KEYWORDS.include?(name)
         | 
| 86 | 
            -
                  raise ::NameError, "reserved method name `#{name}'" if respond_to?(name, true) && !@lets.key?(name)
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  @lets.update(name => ::Aw.fork! { block.call })
         | 
| 89 | 
            -
                rescue ::SystemExit => e
         | 
| 90 | 
            -
                  raise SuspiciousSuccessError, "attempt `#{name}' to bypass the tests" if e.success?
         | 
| 91 | 
            -
                  raise e
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                # Verify the expectation.
         | 
| 95 | 
            -
                #
         | 
| 96 | 
            -
                # @param block [Proc] A spec to compare against the computed actual value.
         | 
| 97 | 
            -
                #
         | 
| 98 | 
            -
                # @return [::Spectus::Result::Pass, ::Spectus::Result::Fail] Pass or fail.
         | 
| 99 | 
            -
                def it(_message = nil, &block)
         | 
| 100 | 
            -
                  print "#{block.source_location.join(':')}: "
         | 
| 101 | 
            -
                  i = It.new(callable, **@lets)
         | 
| 102 | 
            -
                  @before_hooks.each { |hook| i.instance_eval(&hook) }
         | 
| 103 | 
            -
                  result = i.instance_eval(&block)
         | 
| 104 | 
            -
                  puts result.colored_string
         | 
| 105 | 
            -
                rescue ::Spectus::Result::Fail => result
         | 
| 106 | 
            -
                  abort result.colored_string
         | 
| 107 | 
            -
                ensure
         | 
| 108 | 
            -
                  @after_hooks.each { |hook| i.instance_eval(&hook) }
         | 
| 109 | 
            -
                  raise ExpectationResultNotFoundError, result.class.inspect unless result.is_a?(::Spectus::Result::Common)
         | 
| 110 | 
            -
                end
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                def on(name, *args, **options, &block)
         | 
| 113 | 
            -
                  if callable.raised?
         | 
| 114 | 
            -
                    actual    = callable
         | 
| 115 | 
            -
                    challenge = ::Defi.send(:call)
         | 
| 116 | 
            -
                  else
         | 
| 117 | 
            -
                    actual    = callable.object
         | 
| 118 | 
            -
                    challenge = ::Defi.send(name, *args, **options)
         | 
| 119 | 
            -
                  end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                  o = Context.new(actual, challenge, @before_hooks.length, *@before_hooks + @after_hooks, **@lets)
         | 
| 122 | 
            -
                  o.instance_eval(&block)
         | 
| 123 | 
            -
                end
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                def with(_message = nil, **new_lets, &block)
         | 
| 126 | 
            -
                  actual    = callable.object
         | 
| 127 | 
            -
                  challenge = ::Defi.send(:itself)
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                  c = Context.new(actual, challenge, @before_hooks.length, *@before_hooks + @after_hooks, **@lets.merge(new_lets))
         | 
| 130 | 
            -
                  c.instance_eval(&block)
         | 
| 131 | 
            -
                end
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                private
         | 
| 134 | 
            -
             | 
| 135 | 
            -
                def method_missing(name, *args, &block)
         | 
| 136 | 
            -
                  @lets.fetch(name) { super }
         | 
| 137 | 
            -
                end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                def respond_to_missing?(name, include_private = false)
         | 
| 140 | 
            -
                  @lets.key?(name) || super
         | 
| 141 | 
            -
                end
         | 
| 142 | 
            -
              end
         | 
| 143 | 
            -
            end
         | 
| 144 | 
            -
             | 
| 145 | 
            -
            require_relative 'it'
         | 
| 146 | 
            -
            require_relative 'expectation_result_not_found_error'
         | 
| 147 | 
            -
            require_relative 'suspicious_success_error'
         | 
    
        data/lib/fix/it.rb
    DELETED
    
    | @@ -1,31 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'spectus/expectation_target'
         | 
| 4 | 
            -
            require 'matchi/helper'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            module Fix
         | 
| 7 | 
            -
              # Wraps the target of an expectation.
         | 
| 8 | 
            -
              class It < ::Spectus::ExpectationTarget
         | 
| 9 | 
            -
                include ::Matchi::Helper
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                # Create a new expection target
         | 
| 12 | 
            -
                #
         | 
| 13 | 
            -
                # @param callable [#call] The object to test.
         | 
| 14 | 
            -
                def initialize(callable, **lets)
         | 
| 15 | 
            -
                  raise unless callable.respond_to?(:call)
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  @callable = callable
         | 
| 18 | 
            -
                  @lets     = lets
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                private
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                def method_missing(name, *args, &block)
         | 
| 24 | 
            -
                  @lets.fetch(name) { super }
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                def respond_to_missing?(name, include_private = false)
         | 
| 28 | 
            -
                  @lets.key?(name) || super
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
            end
         |