dry-logic 0.5.0 → 1.5.0
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/CHANGELOG.md +222 -17
 - data/LICENSE +1 -1
 - data/README.md +11 -20
 - data/dry-logic.gemspec +36 -20
 - data/lib/dry/logic/appliable.rb +2 -0
 - data/lib/dry/logic/builder.rb +88 -0
 - data/lib/dry/logic/evaluator.rb +1 -1
 - data/lib/dry/logic/operations/abstract.rb +4 -6
 - data/lib/dry/logic/operations/and.rb +12 -3
 - data/lib/dry/logic/operations/attr.rb +1 -1
 - data/lib/dry/logic/operations/binary.rb +4 -3
 - data/lib/dry/logic/operations/check.rb +3 -5
 - data/lib/dry/logic/operations/each.rb +1 -2
 - data/lib/dry/logic/operations/implication.rb +1 -2
 - data/lib/dry/logic/operations/key.rb +3 -5
 - data/lib/dry/logic/operations/negation.rb +1 -2
 - data/lib/dry/logic/operations/or.rb +1 -2
 - data/lib/dry/logic/operations/set.rb +3 -4
 - data/lib/dry/logic/operations/unary.rb +1 -1
 - data/lib/dry/logic/operations/xor.rb +1 -2
 - data/lib/dry/logic/operators.rb +6 -4
 - data/lib/dry/logic/predicates.rb +110 -28
 - data/lib/dry/logic/result.rb +2 -4
 - data/lib/dry/logic/rule/interface.rb +143 -0
 - data/lib/dry/logic/rule/predicate.rb +23 -17
 - data/lib/dry/logic/rule.rb +31 -31
 - data/lib/dry/logic/rule_compiler.rb +2 -7
 - data/lib/dry/logic/version.rb +3 -1
 - data/lib/dry/logic.rb +21 -5
 - data/lib/dry-logic.rb +3 -1
 - metadata +27 -143
 - data/.codeclimate.yml +0 -23
 - data/.gitignore +0 -7
 - data/.rspec +0 -3
 - data/.rubocop.yml +0 -16
 - data/.rubocop_todo.yml +0 -7
 - data/.travis.yml +0 -30
 - data/CONTRIBUTING.md +0 -29
 - data/Gemfile +0 -17
 - data/Rakefile +0 -12
 - data/bin/console +0 -10
 - data/examples/basic.rb +0 -14
 - data/lib/dry/logic/operations.rb +0 -13
 - data/spec/integration/result_spec.rb +0 -59
 - data/spec/integration/rule_spec.rb +0 -53
 - data/spec/shared/predicates.rb +0 -57
 - data/spec/shared/rule.rb +0 -67
 - data/spec/spec_helper.rb +0 -34
 - data/spec/support/mutant.rb +0 -9
 - data/spec/unit/operations/and_spec.rb +0 -64
 - data/spec/unit/operations/attr_spec.rb +0 -27
 - data/spec/unit/operations/check_spec.rb +0 -49
 - data/spec/unit/operations/each_spec.rb +0 -47
 - data/spec/unit/operations/implication_spec.rb +0 -30
 - data/spec/unit/operations/key_spec.rb +0 -133
 - data/spec/unit/operations/negation_spec.rb +0 -49
 - data/spec/unit/operations/or_spec.rb +0 -73
 - data/spec/unit/operations/set_spec.rb +0 -41
 - data/spec/unit/operations/xor_spec.rb +0 -61
 - data/spec/unit/predicates/array_spec.rb +0 -41
 - data/spec/unit/predicates/attr_spec.rb +0 -29
 - data/spec/unit/predicates/bool_spec.rb +0 -34
 - data/spec/unit/predicates/case_spec.rb +0 -33
 - data/spec/unit/predicates/date_spec.rb +0 -31
 - data/spec/unit/predicates/date_time_spec.rb +0 -31
 - data/spec/unit/predicates/decimal_spec.rb +0 -32
 - data/spec/unit/predicates/empty_spec.rb +0 -38
 - data/spec/unit/predicates/eql_spec.rb +0 -21
 - data/spec/unit/predicates/even_spec.rb +0 -31
 - data/spec/unit/predicates/excluded_from_spec.rb +0 -35
 - data/spec/unit/predicates/excludes_spec.rb +0 -56
 - data/spec/unit/predicates/false_spec.rb +0 -35
 - data/spec/unit/predicates/filled_spec.rb +0 -38
 - data/spec/unit/predicates/float_spec.rb +0 -31
 - data/spec/unit/predicates/format_spec.rb +0 -21
 - data/spec/unit/predicates/gt_spec.rb +0 -40
 - data/spec/unit/predicates/gteq_spec.rb +0 -40
 - data/spec/unit/predicates/included_in_spec.rb +0 -35
 - data/spec/unit/predicates/includes_spec.rb +0 -24
 - data/spec/unit/predicates/int_spec.rb +0 -34
 - data/spec/unit/predicates/key_spec.rb +0 -29
 - data/spec/unit/predicates/lt_spec.rb +0 -40
 - data/spec/unit/predicates/lteq_spec.rb +0 -40
 - data/spec/unit/predicates/max_size_spec.rb +0 -49
 - data/spec/unit/predicates/min_size_spec.rb +0 -49
 - data/spec/unit/predicates/none_spec.rb +0 -28
 - data/spec/unit/predicates/not_eql_spec.rb +0 -21
 - data/spec/unit/predicates/number_spec.rb +0 -37
 - data/spec/unit/predicates/odd_spec.rb +0 -31
 - data/spec/unit/predicates/size_spec.rb +0 -55
 - data/spec/unit/predicates/str_spec.rb +0 -32
 - data/spec/unit/predicates/time_spec.rb +0 -31
 - data/spec/unit/predicates/true_spec.rb +0 -35
 - data/spec/unit/predicates/type_spec.rb +0 -35
 - data/spec/unit/predicates_spec.rb +0 -23
 - data/spec/unit/rule/predicate_spec.rb +0 -53
 - data/spec/unit/rule_compiler_spec.rb +0 -127
 - data/spec/unit/rule_spec.rb +0 -141
 
    
        data/spec/shared/rule.rb
    DELETED
    
    | 
         @@ -1,67 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            shared_examples_for Dry::Logic::Rule do
         
     | 
| 
       2 
     | 
    
         
            -
              let(:predicate) { double(:predicate, arity: 2, name: predicate_name) }
         
     | 
| 
       3 
     | 
    
         
            -
              let(:rule_type) { described_class }
         
     | 
| 
       4 
     | 
    
         
            -
              let(:predicate_name) { :good? }
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              describe '#arity' do
         
     | 
| 
       7 
     | 
    
         
            -
                it 'returns its predicate arity' do
         
     | 
| 
       8 
     | 
    
         
            -
                  rule = rule_type.new(predicate)
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                  expect(rule.arity).to be(2)
         
     | 
| 
       11 
     | 
    
         
            -
                end
         
     | 
| 
       12 
     | 
    
         
            -
              end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
              describe '#parameters' do
         
     | 
| 
       15 
     | 
    
         
            -
                it 'returns a list of args with their names' do
         
     | 
| 
       16 
     | 
    
         
            -
                  rule = rule_type.new(-> foo, bar { true }, args: [312])
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                  expect(rule.parameters).to eql([[:req, :foo], [:req, :bar]])
         
     | 
| 
       19 
     | 
    
         
            -
                end
         
     | 
| 
       20 
     | 
    
         
            -
              end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       23 
     | 
    
         
            -
                it 'returns success for valid input' do
         
     | 
| 
       24 
     | 
    
         
            -
                  rule = rule_type.new(predicate)
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  expect(predicate).to receive(:[]).with(2).and_return(true)
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                  expect(rule.(2)).to be_success
         
     | 
| 
       29 
     | 
    
         
            -
                end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                it 'returns failure for invalid input' do
         
     | 
| 
       32 
     | 
    
         
            -
                  rule = rule_type.new(predicate)
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  expect(predicate).to receive(:[]).with(2).and_return(false)
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                  expect(rule.(2)).to be_failure
         
     | 
| 
       37 
     | 
    
         
            -
                end
         
     | 
| 
       38 
     | 
    
         
            -
              end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
              describe '#[]' do
         
     | 
| 
       41 
     | 
    
         
            -
                it 'delegates to its predicate' do
         
     | 
| 
       42 
     | 
    
         
            -
                  rule = rule_type.new(predicate)
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  expect(predicate).to receive(:[]).with(2).and_return(true)
         
     | 
| 
       45 
     | 
    
         
            -
                  expect(rule[2]).to be(true)
         
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
       47 
     | 
    
         
            -
              end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
              describe '#curry' do
         
     | 
| 
       50 
     | 
    
         
            -
                it 'returns a curried rule' do
         
     | 
| 
       51 
     | 
    
         
            -
                  rule = rule_type.new(predicate).curry(3)
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  expect(predicate).to receive(:[]).with(3, 2).and_return(true)
         
     | 
| 
       54 
     | 
    
         
            -
                  expect(rule.args).to eql([3])
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                  expect(rule.(2)).to be_success
         
     | 
| 
       57 
     | 
    
         
            -
                end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                it 'raises argument error when arity does not match' do
         
     | 
| 
       60 
     | 
    
         
            -
                  expect(predicate).to receive(:arity).and_return(2)
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                  expect { rule_type.new(predicate).curry(3, 2, 1) }.to raise_error(
         
     | 
| 
       63 
     | 
    
         
            -
                    ArgumentError, 'wrong number of arguments (3 for 2)'
         
     | 
| 
       64 
     | 
    
         
            -
                  )
         
     | 
| 
       65 
     | 
    
         
            -
                end
         
     | 
| 
       66 
     | 
    
         
            -
              end
         
     | 
| 
       67 
     | 
    
         
            -
            end
         
     | 
    
        data/spec/spec_helper.rb
    DELETED
    
    | 
         @@ -1,34 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            if RUBY_ENGINE == 'ruby' && ENV['COVERAGE'] == 'true'
         
     | 
| 
       2 
     | 
    
         
            -
              require 'yaml'
         
     | 
| 
       3 
     | 
    
         
            -
              rubies = YAML.load(File.read(File.join(__dir__, '..', '.travis.yml')))['rvm']
         
     | 
| 
       4 
     | 
    
         
            -
              latest_mri = rubies.select { |v| v =~ /\A\d+\.\d+.\d+\z/ }.max
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              if RUBY_VERSION == latest_mri
         
     | 
| 
       7 
     | 
    
         
            -
                require 'simplecov'
         
     | 
| 
       8 
     | 
    
         
            -
                SimpleCov.start do
         
     | 
| 
       9 
     | 
    
         
            -
                  add_filter '/spec/'
         
     | 
| 
       10 
     | 
    
         
            -
                end
         
     | 
| 
       11 
     | 
    
         
            -
              end
         
     | 
| 
       12 
     | 
    
         
            -
            end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            begin
         
     | 
| 
       15 
     | 
    
         
            -
              require 'byebug'
         
     | 
| 
       16 
     | 
    
         
            -
            rescue LoadError; end
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            require 'dry-logic'
         
     | 
| 
       19 
     | 
    
         
            -
            require 'dry/core/constants'
         
     | 
| 
       20 
     | 
    
         
            -
            require 'pathname'
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            SPEC_ROOT = Pathname(__dir__)
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            Dir[SPEC_ROOT.join('shared/**/*.rb')].each(&method(:require))
         
     | 
| 
       25 
     | 
    
         
            -
            Dir[SPEC_ROOT.join('support/**/*.rb')].each(&method(:require))
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            include Dry::Logic
         
     | 
| 
       28 
     | 
    
         
            -
            include Dry::Core::Constants
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            RSpec.configure do |config|
         
     | 
| 
       31 
     | 
    
         
            -
              config.disable_monkey_patching!
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
              config.warnings = true
         
     | 
| 
       34 
     | 
    
         
            -
            end
         
     | 
    
        data/spec/support/mutant.rb
    DELETED
    
    
| 
         @@ -1,64 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::And do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::And.new(left, right) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:left) { Rule::Predicate.new(int?) }
         
     | 
| 
       7 
     | 
    
         
            -
              let(:right) { Rule::Predicate.new(gt?).curry(18) }
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       10 
     | 
    
         
            -
                it 'calls left and right' do
         
     | 
| 
       11 
     | 
    
         
            -
                  expect(operation.(18)).to be_failure
         
     | 
| 
       12 
     | 
    
         
            -
                end
         
     | 
| 
       13 
     | 
    
         
            -
              end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       16 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       17 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       18 
     | 
    
         
            -
                    [:and, [[:predicate, [:int?, [[:input, Undefined]]]], [:predicate, [:gt?, [[:num, 18], [:input, Undefined]]]]]]
         
     | 
| 
       19 
     | 
    
         
            -
                  )
         
     | 
| 
       20 
     | 
    
         
            -
                end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                it 'returns result ast' do
         
     | 
| 
       23 
     | 
    
         
            -
                  expect(operation.('18').to_ast).to eql(
         
     | 
| 
       24 
     | 
    
         
            -
                    [:and, [[:predicate, [:int?, [[:input, '18']]]], [:hint, [:predicate, [:gt?, [[:num, 18], [:input, '18']]]]]]]
         
     | 
| 
       25 
     | 
    
         
            -
                  )
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                  expect(operation.(18).to_ast).to eql(
         
     | 
| 
       28 
     | 
    
         
            -
                    [:predicate, [:gt?, [[:num, 18], [:input, 18]]]]
         
     | 
| 
       29 
     | 
    
         
            -
                  )
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                it 'returns failure result ast' do
         
     | 
| 
       33 
     | 
    
         
            -
                  expect(operation.with(id: :age).('18').to_ast).to eql(
         
     | 
| 
       34 
     | 
    
         
            -
                    [:failure, [:age, [:and, [[:predicate, [:int?, [[:input, '18']]]], [:hint, [:predicate, [:gt?, [[:num, 18], [:input, '18']]]]]]]]]
         
     | 
| 
       35 
     | 
    
         
            -
                  )
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                  expect(operation.with(id: :age).(18).to_ast).to eql(
         
     | 
| 
       38 
     | 
    
         
            -
                    [:failure, [:age, [:predicate, [:gt?, [[:num, 18], [:input, 18]]]]]]
         
     | 
| 
       39 
     | 
    
         
            -
                  )
         
     | 
| 
       40 
     | 
    
         
            -
                end
         
     | 
| 
       41 
     | 
    
         
            -
              end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
              describe '#and' do
         
     | 
| 
       44 
     | 
    
         
            -
                let(:other) { Rule::Predicate.new(lt?).curry(30) }
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                it 'creates and with the other' do
         
     | 
| 
       47 
     | 
    
         
            -
                  expect(operation.and(other).(31)).to be_failure
         
     | 
| 
       48 
     | 
    
         
            -
                end
         
     | 
| 
       49 
     | 
    
         
            -
              end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
              describe '#or' do
         
     | 
| 
       52 
     | 
    
         
            -
                let(:other) { Rule::Predicate.new(lt?).curry(14) }
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                it 'creates or with the other' do
         
     | 
| 
       55 
     | 
    
         
            -
                  expect(operation.or(other).(13)).to be_success
         
     | 
| 
       56 
     | 
    
         
            -
                end
         
     | 
| 
       57 
     | 
    
         
            -
              end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       60 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       61 
     | 
    
         
            -
                  expect(operation.to_s).to eql('int? AND gt?(18)')
         
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
       63 
     | 
    
         
            -
              end
         
     | 
| 
       64 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,27 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Attr do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Attr.new(Rule::Predicate.new(str?), name: :name) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:model) { Struct.new(:name) }
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       9 
     | 
    
         
            -
                it 'applies predicate to the value' do
         
     | 
| 
       10 
     | 
    
         
            -
                  expect(operation.(model.new('Jane'))).to be_success
         
     | 
| 
       11 
     | 
    
         
            -
                  expect(operation.(model.new(nil))).to be_failure
         
     | 
| 
       12 
     | 
    
         
            -
                end
         
     | 
| 
       13 
     | 
    
         
            -
              end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
              describe '#and' do
         
     | 
| 
       16 
     | 
    
         
            -
                let(:other) { Operations::Attr.new(Rule::Predicate.new(min_size?).curry(3), name: :name) }
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                it 'returns and where value is passed to the right' do
         
     | 
| 
       19 
     | 
    
         
            -
                  present_and_string = operation.and(other)
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                  expect(present_and_string.(model.new('Jane'))).to be_success
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                  expect(present_and_string.(model.new('Ja'))).to be_failure
         
     | 
| 
       24 
     | 
    
         
            -
                  expect(present_and_string.(model.new(1))).to be_failure
         
     | 
| 
       25 
     | 
    
         
            -
                end
         
     | 
| 
       26 
     | 
    
         
            -
              end
         
     | 
| 
       27 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,49 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Check do
         
     | 
| 
       2 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       5 
     | 
    
         
            -
                context 'with 1-level nesting' do
         
     | 
| 
       6 
     | 
    
         
            -
                  subject(:operation) do
         
     | 
| 
       7 
     | 
    
         
            -
                    Operations::Check.new(Rule::Predicate.new(eql?).curry(1), id: :compare, keys: [:num])
         
     | 
| 
       8 
     | 
    
         
            -
                  end
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                  it 'applies predicate to args extracted from the input' do
         
     | 
| 
       11 
     | 
    
         
            -
                    expect(operation.(num: 1)).to be_success
         
     | 
| 
       12 
     | 
    
         
            -
                    expect(operation.(num: 2)).to be_failure
         
     | 
| 
       13 
     | 
    
         
            -
                  end
         
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                context 'with 2-levels nesting' do
         
     | 
| 
       17 
     | 
    
         
            -
                  subject(:operation) do
         
     | 
| 
       18 
     | 
    
         
            -
                    Operations::Check.new(Rule::Predicate.new(eql?), id: :compare, keys: [[:nums, :left], [:nums, :right]])
         
     | 
| 
       19 
     | 
    
         
            -
                  end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                  it 'applies predicate to args extracted from the input' do
         
     | 
| 
       22 
     | 
    
         
            -
                    expect(operation.(nums: { left: 1, right: 1 })).to be_success
         
     | 
| 
       23 
     | 
    
         
            -
                    expect(operation.(nums: { left: 1, right: 2 })).to be_failure
         
     | 
| 
       24 
     | 
    
         
            -
                  end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  it 'curries args properly' do
         
     | 
| 
       27 
     | 
    
         
            -
                    result = operation.(nums: { left: 1, right: 2 })
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                    expect(result.to_ast).to eql(
         
     | 
| 
       30 
     | 
    
         
            -
                      [:failure, [:compare, [:check, [
         
     | 
| 
       31 
     | 
    
         
            -
                        [[:nums, :left], [:nums, :right]], [:predicate, [:eql?, [[:left, 1], [:right, 2]]]]]
         
     | 
| 
       32 
     | 
    
         
            -
                      ]]]
         
     | 
| 
       33 
     | 
    
         
            -
                    )
         
     | 
| 
       34 
     | 
    
         
            -
                  end
         
     | 
| 
       35 
     | 
    
         
            -
                end
         
     | 
| 
       36 
     | 
    
         
            -
              end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       39 
     | 
    
         
            -
                subject(:operation) do
         
     | 
| 
       40 
     | 
    
         
            -
                  Operations::Check.new(Rule::Predicate.new(str?), keys: [:email])
         
     | 
| 
       41 
     | 
    
         
            -
                end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       44 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       45 
     | 
    
         
            -
                    [:check, [[:email], [:predicate, [:str?, [[:input, Undefined]]]]]]
         
     | 
| 
       46 
     | 
    
         
            -
                  )
         
     | 
| 
       47 
     | 
    
         
            -
                end
         
     | 
| 
       48 
     | 
    
         
            -
              end
         
     | 
| 
       49 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,47 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Each do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Each.new(is_string) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:is_string) { Rule::Predicate.new(str?) }
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       9 
     | 
    
         
            -
                it 'applies its rules to all elements in the input' do
         
     | 
| 
       10 
     | 
    
         
            -
                  expect(operation.(['Address'])).to be_success
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  expect(operation.([nil, 'Address'])).to be_failure
         
     | 
| 
       13 
     | 
    
         
            -
                  expect(operation.([:Address, 'Address'])).to be_failure
         
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
              end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       18 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       19 
     | 
    
         
            -
                  expect(operation.to_ast).to eql([:each, [:predicate, [:str?, [[:input, Undefined]]]]])
         
     | 
| 
       20 
     | 
    
         
            -
                end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                it 'returns result ast' do
         
     | 
| 
       23 
     | 
    
         
            -
                  expect(operation.([nil, 12, nil]).to_ast).to eql(
         
     | 
| 
       24 
     | 
    
         
            -
                    [:set, [
         
     | 
| 
       25 
     | 
    
         
            -
                      [:key, [0, [:predicate, [:str?, [[:input, nil]]]]]],
         
     | 
| 
       26 
     | 
    
         
            -
                      [:key, [1, [:predicate, [:str?, [[:input, 12]]]]]],
         
     | 
| 
       27 
     | 
    
         
            -
                      [:key, [2, [:predicate, [:str?, [[:input, nil]]]]]]
         
     | 
| 
       28 
     | 
    
         
            -
                    ]]
         
     | 
| 
       29 
     | 
    
         
            -
                  )
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                it 'returns failure result ast' do
         
     | 
| 
       33 
     | 
    
         
            -
                  expect(operation.with(id: :tags).([nil, 'red', 12]).to_ast).to eql(
         
     | 
| 
       34 
     | 
    
         
            -
                    [:failure, [:tags, [:set, [
         
     | 
| 
       35 
     | 
    
         
            -
                      [:key, [0, [:predicate, [:str?, [[:input, nil]]]]]],
         
     | 
| 
       36 
     | 
    
         
            -
                      [:key, [2, [:predicate, [:str?, [[:input, 12]]]]]]
         
     | 
| 
       37 
     | 
    
         
            -
                    ]]]]
         
     | 
| 
       38 
     | 
    
         
            -
                  )
         
     | 
| 
       39 
     | 
    
         
            -
                end
         
     | 
| 
       40 
     | 
    
         
            -
              end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       43 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       44 
     | 
    
         
            -
                  expect(operation.to_s).to eql('each(str?)')
         
     | 
| 
       45 
     | 
    
         
            -
                end
         
     | 
| 
       46 
     | 
    
         
            -
              end
         
     | 
| 
       47 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,30 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Implication do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Implication.new(left, right) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:left) { Rule::Predicate.new(int?) }
         
     | 
| 
       7 
     | 
    
         
            -
              let(:right) { Rule::Predicate.new(gt?).curry(18) }
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       10 
     | 
    
         
            -
                it 'calls left and right' do
         
     | 
| 
       11 
     | 
    
         
            -
                  expect(operation.('19')).to be_success
         
     | 
| 
       12 
     | 
    
         
            -
                  expect(operation.(19)).to be_success
         
     | 
| 
       13 
     | 
    
         
            -
                  expect(operation.(18)).to be_failure
         
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
              end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       18 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       19 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       20 
     | 
    
         
            -
                    [:implication, [[:predicate, [:int?, [[:input, Undefined]]]], [:predicate, [:gt?, [[:num, 18], [:input, Undefined]]]]]]
         
     | 
| 
       21 
     | 
    
         
            -
                  )
         
     | 
| 
       22 
     | 
    
         
            -
                end
         
     | 
| 
       23 
     | 
    
         
            -
              end
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       26 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       27 
     | 
    
         
            -
                  expect(operation.to_s).to eql('int? THEN gt?(18)')
         
     | 
| 
       28 
     | 
    
         
            -
                end
         
     | 
| 
       29 
     | 
    
         
            -
              end
         
     | 
| 
       30 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,133 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Key do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Key.new(predicate, name: :user) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:predicate) do
         
     | 
| 
       7 
     | 
    
         
            -
                Rule::Predicate.new(key?).curry(:age)
         
     | 
| 
       8 
     | 
    
         
            -
              end
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       11 
     | 
    
         
            -
                context 'with a plain predicate' do
         
     | 
| 
       12 
     | 
    
         
            -
                  it 'returns a success for valid input' do
         
     | 
| 
       13 
     | 
    
         
            -
                    expect(operation.(user: { age: 18 })).to be_success
         
     | 
| 
       14 
     | 
    
         
            -
                  end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                  it 'returns a failure for invalid input' do
         
     | 
| 
       17 
     | 
    
         
            -
                    result = operation.(user: {})
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                    expect(result).to be_failure
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                    expect(result.to_ast).to eql(
         
     | 
| 
       22 
     | 
    
         
            -
                      [:failure, [:user, [:key, [:user,
         
     | 
| 
       23 
     | 
    
         
            -
                        [:predicate, [:key?, [[:name, :age], [:input, {}]]]]
         
     | 
| 
       24 
     | 
    
         
            -
                      ]]]]
         
     | 
| 
       25 
     | 
    
         
            -
                    )
         
     | 
| 
       26 
     | 
    
         
            -
                  end
         
     | 
| 
       27 
     | 
    
         
            -
                end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                context 'with a set rule as predicate' do
         
     | 
| 
       30 
     | 
    
         
            -
                  subject(:operation) do
         
     | 
| 
       31 
     | 
    
         
            -
                    Operations::Key.new(predicate, name: :address)
         
     | 
| 
       32 
     | 
    
         
            -
                  end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  let(:predicate) do
         
     | 
| 
       35 
     | 
    
         
            -
                    Operations::Set.new(Rule::Predicate.new(key?).curry(:city), Rule::Predicate.new(key?).curry(:zipcode))
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                  it 'applies set rule to the value that passes' do
         
     | 
| 
       39 
     | 
    
         
            -
                    result = operation.(address: { city: 'NYC', zipcode: '123' })
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                    expect(result).to be_success
         
     | 
| 
       42 
     | 
    
         
            -
                  end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  it 'applies set rule to the value that fails' do
         
     | 
| 
       45 
     | 
    
         
            -
                    result = operation.(address: { city: 'NYC' })
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                    expect(result).to be_failure
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                    expect(result.to_ast).to eql(
         
     | 
| 
       50 
     | 
    
         
            -
                      [:failure, [:address, [:key, [:address, [:set, [
         
     | 
| 
       51 
     | 
    
         
            -
                        [:predicate, [:key?, [[:name, :zipcode], [:input, { city: 'NYC' }]]]]
         
     | 
| 
       52 
     | 
    
         
            -
                      ]]]]]]
         
     | 
| 
       53 
     | 
    
         
            -
                    )
         
     | 
| 
       54 
     | 
    
         
            -
                  end
         
     | 
| 
       55 
     | 
    
         
            -
                end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                context 'with an each rule as predicate' do
         
     | 
| 
       58 
     | 
    
         
            -
                  subject(:operation) do
         
     | 
| 
       59 
     | 
    
         
            -
                    Operations::Key.new(predicate, name: :nums)
         
     | 
| 
       60 
     | 
    
         
            -
                  end
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                  let(:predicate) do
         
     | 
| 
       63 
     | 
    
         
            -
                    Operations::Each.new(Rule::Predicate.new(str?))
         
     | 
| 
       64 
     | 
    
         
            -
                  end
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                  it 'applies each rule to the value that passses' do
         
     | 
| 
       67 
     | 
    
         
            -
                    result = operation.(nums: %w(1 2 3))
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                    expect(result).to be_success
         
     | 
| 
       70 
     | 
    
         
            -
                  end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                  it 'applies each rule to the value that fails' do
         
     | 
| 
       73 
     | 
    
         
            -
                    failure = operation.(nums: [1, '3', 3])
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                    expect(failure).to be_failure
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                    expect(failure.to_ast).to eql(
         
     | 
| 
       78 
     | 
    
         
            -
                      [:failure, [:nums, [:key, [:nums, [:set, [
         
     | 
| 
       79 
     | 
    
         
            -
                        [:key, [0, [:predicate, [:str?, [[:input, 1]]]]]],
         
     | 
| 
       80 
     | 
    
         
            -
                        [:key, [2, [:predicate, [:str?, [[:input, 3]]]]]]
         
     | 
| 
       81 
     | 
    
         
            -
                      ]]]]]]
         
     | 
| 
       82 
     | 
    
         
            -
                    )
         
     | 
| 
       83 
     | 
    
         
            -
                  end
         
     | 
| 
       84 
     | 
    
         
            -
                end
         
     | 
| 
       85 
     | 
    
         
            -
              end
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       88 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       89 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       90 
     | 
    
         
            -
                    [:key, [:user, [:predicate, [:key?, [[:name, :age], [:input, Undefined]]]]]]
         
     | 
| 
       91 
     | 
    
         
            -
                  )
         
     | 
| 
       92 
     | 
    
         
            -
                end
         
     | 
| 
       93 
     | 
    
         
            -
              end
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
              describe '#ast' do
         
     | 
| 
       96 
     | 
    
         
            -
                it 'returns ast without the input' do
         
     | 
| 
       97 
     | 
    
         
            -
                  expect(operation.ast).to eql(
         
     | 
| 
       98 
     | 
    
         
            -
                    [:key, [:user, [:predicate, [:key?, [[:name, :age], [:input, Undefined]]]]]]
         
     | 
| 
       99 
     | 
    
         
            -
                  )
         
     | 
| 
       100 
     | 
    
         
            -
                end
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
                it 'returns ast with the input' do
         
     | 
| 
       103 
     | 
    
         
            -
                  expect(operation.ast(user: 'jane')).to eql(
         
     | 
| 
       104 
     | 
    
         
            -
                    [:key, [:user, [:predicate, [:key?, [[:name, :age], [:input, 'jane']]]]]]
         
     | 
| 
       105 
     | 
    
         
            -
                  )
         
     | 
| 
       106 
     | 
    
         
            -
                end
         
     | 
| 
       107 
     | 
    
         
            -
              end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
              describe '#and' do
         
     | 
| 
       110 
     | 
    
         
            -
                subject(:operation) do
         
     | 
| 
       111 
     | 
    
         
            -
                  Operations::Key.new(Rule::Predicate.new(str?), name: [:user, :name])
         
     | 
| 
       112 
     | 
    
         
            -
                end
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
                let(:other) do
         
     | 
| 
       115 
     | 
    
         
            -
                  Operations::Key.new(Rule::Predicate.new(filled?), name: [:user, :name])
         
     | 
| 
       116 
     | 
    
         
            -
                end
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
                it 'returns and rule where value is passed to the right' do
         
     | 
| 
       119 
     | 
    
         
            -
                  present_and_string = operation.and(other)
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
                  expect(present_and_string.(user: { name: 'Jane' })).to be_success
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
                  expect(present_and_string.(user: {})).to be_failure
         
     | 
| 
       124 
     | 
    
         
            -
                  expect(present_and_string.(user: { name: 1 })).to be_failure
         
     | 
| 
       125 
     | 
    
         
            -
                end
         
     | 
| 
       126 
     | 
    
         
            -
              end
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       129 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       130 
     | 
    
         
            -
                  expect(operation.to_s).to eql('key[user](key?(:age))')
         
     | 
| 
       131 
     | 
    
         
            -
                end
         
     | 
| 
       132 
     | 
    
         
            -
              end
         
     | 
| 
       133 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,49 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Negation do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Negation.new(is_int) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:is_int) { Rule::Predicate.new(int?) }
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       9 
     | 
    
         
            -
                it 'negates its rule' do
         
     | 
| 
       10 
     | 
    
         
            -
                  expect(operation.('19')).to be_success
         
     | 
| 
       11 
     | 
    
         
            -
                  expect(operation.(17)).to be_failure
         
     | 
| 
       12 
     | 
    
         
            -
                end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                context 'double negation' do
         
     | 
| 
       15 
     | 
    
         
            -
                  subject(:double_negation) { Operations::Negation.new(operation) }
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                  it 'works as rule' do
         
     | 
| 
       18 
     | 
    
         
            -
                    expect(double_negation.('19')).to be_failure
         
     | 
| 
       19 
     | 
    
         
            -
                    expect(double_negation.(17)).to be_success
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
       21 
     | 
    
         
            -
                end
         
     | 
| 
       22 
     | 
    
         
            -
              end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       25 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       26 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       27 
     | 
    
         
            -
                    [:not, [:predicate, [:int?, [[:input, Undefined]]]]]
         
     | 
| 
       28 
     | 
    
         
            -
                  )
         
     | 
| 
       29 
     | 
    
         
            -
                end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                it 'returns result ast' do
         
     | 
| 
       32 
     | 
    
         
            -
                  expect(operation.(17).to_ast).to eql(
         
     | 
| 
       33 
     | 
    
         
            -
                    [:not, [:predicate, [:int?, [[:input, 17]]]]]
         
     | 
| 
       34 
     | 
    
         
            -
                  )
         
     | 
| 
       35 
     | 
    
         
            -
                end
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                it 'returns result ast with an :id' do
         
     | 
| 
       38 
     | 
    
         
            -
                  expect(operation.with(id: :age).(17).to_ast).to eql(
         
     | 
| 
       39 
     | 
    
         
            -
                    [:failure, [:age, [:not, [:predicate, [:int?, [[:input, 17]]]]]]]
         
     | 
| 
       40 
     | 
    
         
            -
                  )
         
     | 
| 
       41 
     | 
    
         
            -
                end
         
     | 
| 
       42 
     | 
    
         
            -
              end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       45 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       46 
     | 
    
         
            -
                  expect(operation.to_s).to eql('not(int?)')
         
     | 
| 
       47 
     | 
    
         
            -
                end
         
     | 
| 
       48 
     | 
    
         
            -
              end
         
     | 
| 
       49 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,73 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Or do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Or.new(left, right) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:left) { Rule::Predicate.new(nil?) }
         
     | 
| 
       7 
     | 
    
         
            -
              let(:right) { Rule::Predicate.new(gt?).curry(18) }
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              let(:other) do
         
     | 
| 
       10 
     | 
    
         
            -
                Rule::Predicate.new(int?) & Rule::Predicate.new(lt?).curry(14)
         
     | 
| 
       11 
     | 
    
         
            -
              end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       14 
     | 
    
         
            -
                it 'calls left and right' do
         
     | 
| 
       15 
     | 
    
         
            -
                  expect(operation.(nil)).to be_success
         
     | 
| 
       16 
     | 
    
         
            -
                  expect(operation.(19)).to be_success
         
     | 
| 
       17 
     | 
    
         
            -
                  expect(operation.(18)).to be_failure
         
     | 
| 
       18 
     | 
    
         
            -
                end
         
     | 
| 
       19 
     | 
    
         
            -
              end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       22 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       23 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       24 
     | 
    
         
            -
                    [:or, [
         
     | 
| 
       25 
     | 
    
         
            -
                      [:predicate, [:nil?, [[:input, Undefined]]]],
         
     | 
| 
       26 
     | 
    
         
            -
                      [:predicate, [:gt?, [[:num, 18], [:input, Undefined]]]]]
         
     | 
| 
       27 
     | 
    
         
            -
                    ]
         
     | 
| 
       28 
     | 
    
         
            -
                  )
         
     | 
| 
       29 
     | 
    
         
            -
                end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                it 'returns result ast' do
         
     | 
| 
       32 
     | 
    
         
            -
                  expect(operation.(17).to_ast).to eql(
         
     | 
| 
       33 
     | 
    
         
            -
                    [:or, [
         
     | 
| 
       34 
     | 
    
         
            -
                      [:predicate, [:nil?, [[:input, 17]]]],
         
     | 
| 
       35 
     | 
    
         
            -
                      [:predicate, [:gt?, [[:num, 18], [:input, 17]]]]]
         
     | 
| 
       36 
     | 
    
         
            -
                    ]
         
     | 
| 
       37 
     | 
    
         
            -
                  )
         
     | 
| 
       38 
     | 
    
         
            -
                end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                it 'returns failure result ast' do
         
     | 
| 
       41 
     | 
    
         
            -
                  expect(operation.with(id: :age).(17).to_ast).to eql(
         
     | 
| 
       42 
     | 
    
         
            -
                    [:failure, [:age, [:or, [
         
     | 
| 
       43 
     | 
    
         
            -
                      [:predicate, [:nil?, [[:input, 17]]]],
         
     | 
| 
       44 
     | 
    
         
            -
                      [:predicate, [:gt?, [[:num, 18], [:input, 17]]]]]
         
     | 
| 
       45 
     | 
    
         
            -
                    ]]]
         
     | 
| 
       46 
     | 
    
         
            -
                  )
         
     | 
| 
       47 
     | 
    
         
            -
                end
         
     | 
| 
       48 
     | 
    
         
            -
              end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
              describe '#and' do
         
     | 
| 
       51 
     | 
    
         
            -
                it 'creates and with the other' do
         
     | 
| 
       52 
     | 
    
         
            -
                  expect(operation.and(other).(nil)).to be_failure
         
     | 
| 
       53 
     | 
    
         
            -
                  expect(operation.and(other).(19)).to be_failure
         
     | 
| 
       54 
     | 
    
         
            -
                  expect(operation.and(other).(13)).to be_failure
         
     | 
| 
       55 
     | 
    
         
            -
                  expect(operation.and(other).(14)).to be_failure
         
     | 
| 
       56 
     | 
    
         
            -
                end
         
     | 
| 
       57 
     | 
    
         
            -
              end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
              describe '#or' do
         
     | 
| 
       60 
     | 
    
         
            -
                it 'creates or with the other' do
         
     | 
| 
       61 
     | 
    
         
            -
                  expect(operation.or(other).(nil)).to be_success
         
     | 
| 
       62 
     | 
    
         
            -
                  expect(operation.or(other).(19)).to be_success
         
     | 
| 
       63 
     | 
    
         
            -
                  expect(operation.or(other).(13)).to be_success
         
     | 
| 
       64 
     | 
    
         
            -
                  expect(operation.or(other).(14)).to be_failure
         
     | 
| 
       65 
     | 
    
         
            -
                end
         
     | 
| 
       66 
     | 
    
         
            -
              end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       69 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       70 
     | 
    
         
            -
                  expect(operation.to_s).to eql('nil? OR gt?(18)')
         
     | 
| 
       71 
     | 
    
         
            -
                end
         
     | 
| 
       72 
     | 
    
         
            -
              end
         
     | 
| 
       73 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,41 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Set do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Set.new(is_int, gt_18) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:is_int) { Rule::Predicate.new(int?) }
         
     | 
| 
       7 
     | 
    
         
            -
              let(:gt_18) { Rule::Predicate.new(gt?, args: [18]) }
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       10 
     | 
    
         
            -
                it 'applies all its rules to the input' do
         
     | 
| 
       11 
     | 
    
         
            -
                  expect(operation.(19)).to be_success
         
     | 
| 
       12 
     | 
    
         
            -
                  expect(operation.(17)).to be_failure
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
       14 
     | 
    
         
            -
              end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       17 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       18 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       19 
     | 
    
         
            -
                    [:set, [[:predicate, [:int?, [[:input, Undefined]]]], [:predicate, [:gt?, [[:num, 18], [:input, Undefined]]]]]]
         
     | 
| 
       20 
     | 
    
         
            -
                  )
         
     | 
| 
       21 
     | 
    
         
            -
                end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                it 'returns result ast' do
         
     | 
| 
       24 
     | 
    
         
            -
                  expect(operation.(17).to_ast).to eql(
         
     | 
| 
       25 
     | 
    
         
            -
                    [:set, [[:predicate, [:gt?, [[:num, 18], [:input, 17]]]]]]
         
     | 
| 
       26 
     | 
    
         
            -
                  )
         
     | 
| 
       27 
     | 
    
         
            -
                end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                it 'returns result ast with an :id' do
         
     | 
| 
       30 
     | 
    
         
            -
                  expect(operation.with(id: :age).(17).to_ast).to eql(
         
     | 
| 
       31 
     | 
    
         
            -
                    [:failure, [:age, [:set, [[:predicate, [:gt?, [[:num, 18], [:input, 17]]]]]]]]
         
     | 
| 
       32 
     | 
    
         
            -
                  )
         
     | 
| 
       33 
     | 
    
         
            -
                end
         
     | 
| 
       34 
     | 
    
         
            -
              end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       37 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       38 
     | 
    
         
            -
                  expect(operation.to_s).to eql('set(int?, gt?(18))')
         
     | 
| 
       39 
     | 
    
         
            -
                end
         
     | 
| 
       40 
     | 
    
         
            -
              end
         
     | 
| 
       41 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,61 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            RSpec.describe Operations::Xor do
         
     | 
| 
       2 
     | 
    
         
            -
              subject(:operation) { Operations::Xor.new(left, right) }
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              include_context 'predicates'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              let(:left) { Rule::Predicate.new(array?) }
         
     | 
| 
       7 
     | 
    
         
            -
              let(:right) { Rule::Predicate.new(empty?) }
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              let(:other) do
         
     | 
| 
       10 
     | 
    
         
            -
                Rule::Predicate.new(str?)
         
     | 
| 
       11 
     | 
    
         
            -
              end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
              describe '#call' do
         
     | 
| 
       14 
     | 
    
         
            -
                it 'calls left and right' do
         
     | 
| 
       15 
     | 
    
         
            -
                  expect(operation.(nil)).to be_success
         
     | 
| 
       16 
     | 
    
         
            -
                  expect(operation.('')).to be_success
         
     | 
| 
       17 
     | 
    
         
            -
                  expect(operation.([])).to be_failure
         
     | 
| 
       18 
     | 
    
         
            -
                end
         
     | 
| 
       19 
     | 
    
         
            -
              end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
              describe '#to_ast' do
         
     | 
| 
       22 
     | 
    
         
            -
                it 'returns ast' do
         
     | 
| 
       23 
     | 
    
         
            -
                  expect(operation.to_ast).to eql(
         
     | 
| 
       24 
     | 
    
         
            -
                    [:xor, [[:predicate, [:array?, [[:input, Undefined]]]], [:predicate, [:empty?, [[:input, Undefined]]]]]]
         
     | 
| 
       25 
     | 
    
         
            -
                  )
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                it 'returns result ast' do
         
     | 
| 
       29 
     | 
    
         
            -
                  expect(operation.([]).to_ast).to eql(
         
     | 
| 
       30 
     | 
    
         
            -
                    [:xor, [[:predicate, [:array?, [[:input, []]]]], [:predicate, [:empty?, [[:input, []]]]]]]
         
     | 
| 
       31 
     | 
    
         
            -
                  )
         
     | 
| 
       32 
     | 
    
         
            -
                end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                it 'returns failure result ast' do
         
     | 
| 
       35 
     | 
    
         
            -
                  expect(operation.with(id: :name).([]).to_ast).to eql(
         
     | 
| 
       36 
     | 
    
         
            -
                    [:failure, [:name, [:xor, [[:predicate, [:array?, [[:input, []]]]], [:predicate, [:empty?, [[:input, []]]]]]]]]
         
     | 
| 
       37 
     | 
    
         
            -
                  )
         
     | 
| 
       38 
     | 
    
         
            -
                end
         
     | 
| 
       39 
     | 
    
         
            -
              end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
              describe '#and' do
         
     | 
| 
       42 
     | 
    
         
            -
                it 'creates conjunction with the other' do
         
     | 
| 
       43 
     | 
    
         
            -
                  expect(operation.and(other).(nil)).to be_failure
         
     | 
| 
       44 
     | 
    
         
            -
                  expect(operation.and(other).(19)).to be_failure
         
     | 
| 
       45 
     | 
    
         
            -
                  expect(operation.and(other).('')).to be_success
         
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
       47 
     | 
    
         
            -
              end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
              describe '#or' do
         
     | 
| 
       50 
     | 
    
         
            -
                it 'creates disjunction with the other' do
         
     | 
| 
       51 
     | 
    
         
            -
                  expect(operation.or(other).([])).to be_failure
         
     | 
| 
       52 
     | 
    
         
            -
                  expect(operation.or(other).('')).to be_success
         
     | 
| 
       53 
     | 
    
         
            -
                end
         
     | 
| 
       54 
     | 
    
         
            -
              end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
              describe '#to_s' do
         
     | 
| 
       57 
     | 
    
         
            -
                it 'returns string representation' do
         
     | 
| 
       58 
     | 
    
         
            -
                  expect(operation.to_s).to eql('array? XOR empty?')
         
     | 
| 
       59 
     | 
    
         
            -
                end
         
     | 
| 
       60 
     | 
    
         
            -
              end
         
     | 
| 
       61 
     | 
    
         
            -
            end
         
     |