morpher 0.2.6
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.
Potentially problematic release.
This version of morpher might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.circle.yml +6 -0
- data/.gitignore +5 -0
- data/.rspec +4 -0
- data/.rubocop.yml +8 -0
- data/Changelog.md +60 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +56 -0
- data/Rakefile +95 -0
- data/circle.yml +7 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/heckle.yml +3 -0
- data/config/mutant.yml +8 -0
- data/config/reek.yml +109 -0
- data/config/rubocop.yml +138 -0
- data/config/yardstick.yml +2 -0
- data/examples/README.md +13 -0
- data/examples/a.rb +25 -0
- data/examples/b.rb +35 -0
- data/lib/morpher.rb +111 -0
- data/lib/morpher/compiler.rb +17 -0
- data/lib/morpher/compiler/emitter.rb +82 -0
- data/lib/morpher/compiler/error.rb +84 -0
- data/lib/morpher/compiler/evaluator.rb +63 -0
- data/lib/morpher/compiler/evaluator/emitter.rb +224 -0
- data/lib/morpher/compiler/preprocessor.rb +29 -0
- data/lib/morpher/compiler/preprocessor/emitter.rb +54 -0
- data/lib/morpher/compiler/preprocessor/emitter/anima.rb +69 -0
- data/lib/morpher/compiler/preprocessor/emitter/boolean.rb +31 -0
- data/lib/morpher/compiler/preprocessor/emitter/key.rb +87 -0
- data/lib/morpher/compiler/preprocessor/emitter/noop.rb +45 -0
- data/lib/morpher/compiler/preprocessor/emitter/param.rb +50 -0
- data/lib/morpher/evaluation.rb +118 -0
- data/lib/morpher/evaluator.rb +40 -0
- data/lib/morpher/evaluator/binary.rb +46 -0
- data/lib/morpher/evaluator/nary.rb +97 -0
- data/lib/morpher/evaluator/nullary.rb +92 -0
- data/lib/morpher/evaluator/nullary/parameterized.rb +48 -0
- data/lib/morpher/evaluator/predicate.rb +22 -0
- data/lib/morpher/evaluator/predicate/boolean.rb +76 -0
- data/lib/morpher/evaluator/predicate/contradiction.rb +36 -0
- data/lib/morpher/evaluator/predicate/eql.rb +50 -0
- data/lib/morpher/evaluator/predicate/negation.rb +52 -0
- data/lib/morpher/evaluator/predicate/primitive.rb +49 -0
- data/lib/morpher/evaluator/predicate/tautology.rb +36 -0
- data/lib/morpher/evaluator/transformer.rb +75 -0
- data/lib/morpher/evaluator/transformer/attribute.rb +25 -0
- data/lib/morpher/evaluator/transformer/block.rb +81 -0
- data/lib/morpher/evaluator/transformer/coerce.rb +166 -0
- data/lib/morpher/evaluator/transformer/custom.rb +34 -0
- data/lib/morpher/evaluator/transformer/domain.rb +86 -0
- data/lib/morpher/evaluator/transformer/domain/attribute_accessors.rb +60 -0
- data/lib/morpher/evaluator/transformer/domain/attribute_hash.rb +52 -0
- data/lib/morpher/evaluator/transformer/domain/instance_variables.rb +60 -0
- data/lib/morpher/evaluator/transformer/domain/param.rb +54 -0
- data/lib/morpher/evaluator/transformer/guard.rb +62 -0
- data/lib/morpher/evaluator/transformer/hash_transform.rb +149 -0
- data/lib/morpher/evaluator/transformer/input.rb +37 -0
- data/lib/morpher/evaluator/transformer/key.rb +86 -0
- data/lib/morpher/evaluator/transformer/map.rb +100 -0
- data/lib/morpher/evaluator/transformer/merge.rb +25 -0
- data/lib/morpher/evaluator/transformer/static.rb +27 -0
- data/lib/morpher/evaluator/unary.rb +79 -0
- data/lib/morpher/node_helpers.rb +19 -0
- data/lib/morpher/printer.rb +233 -0
- data/lib/morpher/printer/mixin.rb +58 -0
- data/lib/morpher/registry.rb +51 -0
- data/lib/morpher/type_lookup.rb +51 -0
- data/morpher.gemspec +29 -0
- data/spec/integration_spec.rb +184 -0
- data/spec/rcov.opts +7 -0
- data/spec/shared/evaluator_behavior.rb +155 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/ice_nine_config.rb +8 -0
- data/spec/support/let_mock_helper.rb +8 -0
- data/spec/support/strip_helper.rb +12 -0
- data/spec/unit/morpher/compiler/preprocessor_spec.rb +46 -0
- data/spec/unit/morpher/evaluator/nullary/parameterized_spec.rb +25 -0
- data/spec/unit/morpher/evaluator/predicate/boolean/and_spec.rb +11 -0
- data/spec/unit/morpher/evaluator/predicate/boolean/or_spec.rb +26 -0
- data/spec/unit/morpher/evaluator/predicate/boolean/xor_spec.rb +26 -0
- data/spec/unit/morpher/evaluator/predicate/contrandiction_spec.rb +7 -0
- data/spec/unit/morpher/evaluator/predicate/eql_spec.rb +11 -0
- data/spec/unit/morpher/evaluator/predicate/negation_spec.rb +10 -0
- data/spec/unit/morpher/evaluator/predicate/primitive_spec.rb +17 -0
- data/spec/unit/morpher/evaluator/predicate/tautology_spec.rb +7 -0
- data/spec/unit/morpher/evaluator/transformer/attribute_spec.rb +9 -0
- data/spec/unit/morpher/evaluator/transformer/block_spec.rb +92 -0
- data/spec/unit/morpher/evaluator/transformer/coerce/parse_int_spec.rb +23 -0
- data/spec/unit/morpher/evaluator/transformer/custom_spec.rb +13 -0
- data/spec/unit/morpher/evaluator/transformer/domain/attribute_accessors_spec.rb +48 -0
- data/spec/unit/morpher/evaluator/transformer/domain/attribute_hash_spec.rb +40 -0
- data/spec/unit/morpher/evaluator/transformer/domain/instance_variables_spec.rb +47 -0
- data/spec/unit/morpher/evaluator/transformer/guard_spec.rb +12 -0
- data/spec/unit/morpher/evaluator/transformer/hash_transform_spec.rb +47 -0
- data/spec/unit/morpher/evaluator/transformer/input_spec.rb +11 -0
- data/spec/unit/morpher/evaluator/transformer/map_spec.rb +25 -0
- data/spec/unit/morpher/evaluator/transformer/static_spec.rb +10 -0
- data/spec/unit/morpher/evaluator_spec.rb +15 -0
- data/spec/unit/morpher/printer_spec.rb +21 -0
- data/spec/unit/morpher/registry_spec.rb +11 -0
- data/spec/unit/morpher_spec.rb +53 -0
- metadata +302 -0
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            require 'devtools/spec_helper'
         | 
| 2 | 
            +
            require 'morpher'
         | 
| 3 | 
            +
            require 'mutant' # for the node helpers
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # Monkeypatch to mutant all specs per mutation.
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # TODO: Use master once it supports configurable implicit coverage.
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            # Morpher predicates are needed to finally make this configurable in mutant.
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            module Mutant
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              module Rspec
         | 
| 14 | 
            +
                class Killer
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # Return all example groups
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  # @return [Enumerable<RSpec::Example>]
         | 
| 19 | 
            +
                  #
         | 
| 20 | 
            +
                  # @api private
         | 
| 21 | 
            +
                  #
         | 
| 22 | 
            +
                  def example_groups
         | 
| 23 | 
            +
                    strategy.example_groups
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                end # Rspec
         | 
| 27 | 
            +
              end # Killer
         | 
| 28 | 
            +
            end # Mutant
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            RSpec.configure do |config|
         | 
| 31 | 
            +
              config.include(StripHelper)
         | 
| 32 | 
            +
              config.include(Morpher::NodeHelpers)
         | 
| 33 | 
            +
              config.expect_with :rspec do |rspec|
         | 
| 34 | 
            +
                rspec.syntax = %i[expect should]
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            describe Morpher::Compiler::Preprocessor do
         | 
| 2 | 
            +
              subject { Morpher::Compiler::Preprocessor::DEFAULT.call(input) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              shared_examples_for 'a preprocessor' do
         | 
| 5 | 
            +
                it { should eql(expected) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                it 'is able to compile output' do
         | 
| 8 | 
            +
                  Morpher.compile(subject)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              context 'with s(:boolean)' do
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                it_should_behave_like 'a preprocessor' do
         | 
| 15 | 
            +
                  let(:input)    { s(:boolean) }
         | 
| 16 | 
            +
                  let(:expected) { s(:xor, s(:primitive, TrueClass), s(:primitive, FalseClass)) }
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              class Example
         | 
| 22 | 
            +
                include Anima.new(:foo, :bar)
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              let(:param) do
         | 
| 26 | 
            +
                Morpher::Evaluator::Transformer::Domain::Param.new(Example, %i[foo bar])
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              context 'with s(:anima_load)' do
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                it_should_behave_like 'a preprocessor' do
         | 
| 32 | 
            +
                  let(:input)    { s(:anima_load, Example) }
         | 
| 33 | 
            +
                  let(:expected) { s(:load_attribute_hash, param) }
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              context 'with s(:anima_dump)' do
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it_should_behave_like 'a preprocessor' do
         | 
| 41 | 
            +
                  let(:input)    { s(:anima_dump, Example) }
         | 
| 42 | 
            +
                  let(:expected) { s(:dump_attribute_hash, param) }
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Nullary::Parameterized do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              describe '.include' do
         | 
| 4 | 
            +
                let(:object) do
         | 
| 5 | 
            +
                  Class.new(Morpher::Evaluator) do
         | 
| 6 | 
            +
                    include Morpher::Evaluator::Nullary::Parameterized
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                    def self.name
         | 
| 9 | 
            +
                      'Foo'
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                let(:instance) do
         | 
| 15 | 
            +
                  object.new('foo')
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                it 'sets up printer' do
         | 
| 19 | 
            +
                  instance.description.should eql(strip(<<-'TEXT'))
         | 
| 20 | 
            +
                    Foo
         | 
| 21 | 
            +
                      param: "foo"
         | 
| 22 | 
            +
                  TEXT
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Predicate::Boolean::And do
         | 
| 2 | 
            +
              let(:object) { described_class.new([body_a, body_b]) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:body_a) { Morpher.compile(s(:primitive, String))                          }
         | 
| 5 | 
            +
              let(:body_b) { Morpher.compile(s(:eql, s(:attribute, :length), s(:static, 1))) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:negative_input) { ''   }
         | 
| 8 | 
            +
              let(:positive_input) { 'a'  }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              include_examples 'predicate evaluator'
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Predicate::Boolean::Or do
         | 
| 2 | 
            +
              let(:object) { described_class.new([body_a, body_b]) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:body_a) { Morpher.compile(s(:primitive, String)) }
         | 
| 5 | 
            +
              let(:body_b) { Morpher.compile(s(:primitive, Symbol)) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:negative_input) { Object.new }
         | 
| 8 | 
            +
              let(:positive_input) { ''         }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              include_examples 'predicate evaluator'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              context '#evalaution' do
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                context 'on positive input' do
         | 
| 15 | 
            +
                  subject { object.evaluation(positive_input) }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  its(:evaluations) { should eql([body_a.evaluation(positive_input)]) }
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                context 'on negative input' do
         | 
| 21 | 
            +
                  subject { object.evaluation(negative_input) }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  its(:evaluations) { should eql(object.body.map { |node| node.evaluation(negative_input) }) }
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Predicate::Boolean::Xor do
         | 
| 2 | 
            +
              let(:object) { described_class.new([body_a, body_b]) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:body_a) { Morpher.compile(s(:primitive, TrueClass)) }
         | 
| 5 | 
            +
              let(:body_b) { Morpher.compile(s(:primitive, FalseClass)) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:negative_input) { nil  }
         | 
| 8 | 
            +
              let(:positive_input) { true }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              include_examples 'predicate evaluator'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              context '#evalaution' do
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                context 'on positive input' do
         | 
| 15 | 
            +
                  subject { object.evaluation(positive_input) }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  its(:evaluations) { should eql([body_a.evaluation(positive_input)]) }
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                context 'on negative input' do
         | 
| 21 | 
            +
                  subject { object.evaluation(negative_input) }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  its(:evaluations) { should eql(object.body.map { |node| node.evaluation(negative_input) }) }
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Predicate::EQL do
         | 
| 2 | 
            +
              let(:object) { described_class.new(left, right) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:left)  { Morpher.compile(s(:static, 1.0)) }
         | 
| 5 | 
            +
              let(:right) { Morpher.compile(s(:input))       }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:positive_input) { 1.0 }
         | 
| 8 | 
            +
              let(:negative_input) { 1   }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              include_examples 'predicate evaluator'
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Predicate::Negation do
         | 
| 2 | 
            +
              let(:object) { described_class.new(operand) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:operand) { Morpher.compile(s(:input)) }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              let(:positive_input) { false }
         | 
| 7 | 
            +
              let(:negative_input) { true  }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              include_examples 'predicate evaluator'
         | 
| 10 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Predicate::Primitive::Exact do
         | 
| 2 | 
            +
              let(:object) { described_class.new(Morpher::Evaluator) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:positive_input) { Morpher::Evaluator.allocate }
         | 
| 5 | 
            +
              let(:negative_input) { Morpher::Evaluator::Predicate.allocate }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              include_examples 'predicate evaluator'
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            describe Morpher::Evaluator::Predicate::Primitive::Permissive do
         | 
| 11 | 
            +
              let(:object) { described_class.new(Morpher::Evaluator) }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              let(:positive_input) { Morpher::Evaluator::Predicate.allocate }
         | 
| 14 | 
            +
              let(:negative_input) { '' }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              include_examples 'predicate evaluator'
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Transformer::Attribute do
         | 
| 2 | 
            +
              let(:object) { described_class.new(:length) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              include_examples 'transforming evaluator on valid input'
         | 
| 5 | 
            +
              include_examples 'intransitive evaluator'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:valid_input)     { 'foo' }
         | 
| 8 | 
            +
              let(:expected_output) { 3     }
         | 
| 9 | 
            +
            end
         | 
| @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Transformer::Block do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              let(:ast) do
         | 
| 4 | 
            +
                s(:block, body_a, body_b)
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:object) do
         | 
| 8 | 
            +
                Morpher.compile(ast)
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              let(:evaluator_a) do
         | 
| 12 | 
            +
                Morpher.compile(body_a)
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              let(:evaluator_b) do
         | 
| 16 | 
            +
                Morpher.compile(body_b)
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              context 'transitive' do
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                let(:body_a) do
         | 
| 22 | 
            +
                  s(:guard, s(:primitive, String))
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                let(:body_b) do
         | 
| 26 | 
            +
                  s(:guard, s(:primitive, String))
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                let(:valid_input)     { 'foo' }
         | 
| 30 | 
            +
                let(:expected_output) { 'foo' }
         | 
| 31 | 
            +
                let(:invalid_input)   { :foo  }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                let(:expected_exception) do
         | 
| 34 | 
            +
                  Morpher::Evaluator::Transformer::TransformError.new(object.body.first, invalid_input)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                include_examples 'transitive evaluator'
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                context 'with invalid input' do
         | 
| 40 | 
            +
                  specify '#evaluation' do
         | 
| 41 | 
            +
                    evaluation = object.evaluation(invalid_input)
         | 
| 42 | 
            +
                    expect(evaluation.evaluations.length).to eql(1)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              context 'intransitive' do
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                let(:valid_input)     { { 'foo' => 'bar' } }
         | 
| 50 | 
            +
                let(:invalid_input)   { {}                 }
         | 
| 51 | 
            +
                let(:expected_output) { true               }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                let(:body_a) do
         | 
| 54 | 
            +
                  s(:key_fetch, 'foo')
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                let(:body_b) do
         | 
| 58 | 
            +
                  s(:primitive, String)
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                let(:expected_exception) do
         | 
| 62 | 
            +
                  Morpher::Evaluator::Transformer::TransformError.new(object.body.first, invalid_input)
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                include_examples 'intransitive evaluator'
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                context '#evaluation' do
         | 
| 68 | 
            +
                  subject { object.evaluation(valid_input) }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  let(:evaluations) do
         | 
| 71 | 
            +
                    [
         | 
| 72 | 
            +
                      evaluator_a.evaluation(valid_input),
         | 
| 73 | 
            +
                      evaluator_b.evaluation('bar')
         | 
| 74 | 
            +
                    ]
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  context 'with valid input' do
         | 
| 78 | 
            +
                    it 'returns evaluation' do
         | 
| 79 | 
            +
                      should eql(
         | 
| 80 | 
            +
                        Morpher::Evaluation::Nary.new(
         | 
| 81 | 
            +
                          input:       valid_input,
         | 
| 82 | 
            +
                          evaluator:   object,
         | 
| 83 | 
            +
                          evaluations: evaluations,
         | 
| 84 | 
            +
                          output:      expected_output,
         | 
| 85 | 
            +
                          success:     true
         | 
| 86 | 
            +
                        )
         | 
| 87 | 
            +
                      )
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Transformer::Coerce::ParseInt do
         | 
| 2 | 
            +
              let(:object) { described_class.new(base) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              context 'base 16' do
         | 
| 5 | 
            +
                let(:base) { 16 }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                include_examples 'transitive evaluator'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                let(:valid_input)     { 'ff'   }
         | 
| 10 | 
            +
                let(:invalid_input)   { '0xfg' }
         | 
| 11 | 
            +
                let(:expected_output) { 255    }
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              context 'base 10' do
         | 
| 15 | 
            +
                let(:base) { 10 }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                include_examples 'transitive evaluator'
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                let(:valid_input)     { '100'   }
         | 
| 20 | 
            +
                let(:invalid_input)   { '100.0' }
         | 
| 21 | 
            +
                let(:expected_output) { 100     }
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Transformer::Custom do
         | 
| 2 | 
            +
              let(:object) { described_class.new(param) }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              let(:param)  { [a, b] }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              let(:a) { ->(_input) { :a } }
         | 
| 7 | 
            +
              let(:b) { ->(_input) { :b } }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              let(:valid_input)     { double('Input') }
         | 
| 10 | 
            +
              let(:expected_output) { :a              }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              include_examples 'transforming evaluator on valid input'
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            describe Morpher::Evaluator::Transformer::Domain::AttributeAccessors do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              let(:model) do
         | 
| 4 | 
            +
                Class.new do
         | 
| 5 | 
            +
                  include Equalizer.new(:foo, :bar)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  attr_accessor :foo, :bar
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              let(:param) do
         | 
| 12 | 
            +
                described_class::Param.new(model, %i[foo bar])
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              describe Morpher::Evaluator::Transformer::Domain::AttributeAccessors::Dump do
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                let(:object) { described_class::Dump.new(param) }
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                let(:expected_output) { { foo: :foo, bar: :bar } }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                let(:valid_input) do
         | 
| 22 | 
            +
                  object = model.allocate
         | 
| 23 | 
            +
                  object.foo = :foo
         | 
| 24 | 
            +
                  object.bar = :bar
         | 
| 25 | 
            +
                  object
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                include_examples 'transforming evaluator on valid input'
         | 
| 29 | 
            +
                include_examples 'transitive evaluator'
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              describe Morpher::Evaluator::Transformer::Domain::AttributeAccessors::Load do
         | 
| 34 | 
            +
                let(:object) { described_class::Load.new(param) }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                let(:valid_input)     { { foo: :foo, bar: :bar } }
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                let(:expected_output) do
         | 
| 39 | 
            +
                  object = model.allocate
         | 
| 40 | 
            +
                  object.foo = :foo
         | 
| 41 | 
            +
                  object.bar = :bar
         | 
| 42 | 
            +
                  object
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                include_examples 'transforming evaluator on valid input'
         | 
| 46 | 
            +
                include_examples 'transitive evaluator'
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         |