dry-logic 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42c06d53e8a80811c9bb63f5bc9538c87d9de6a6
4
- data.tar.gz: 24d21638462c0dc1ce8cf1c685df35133d8d4c06
3
+ metadata.gz: 5d49a2ea6e71727f4ae69320aa0619c2ebd96325
4
+ data.tar.gz: 71414bb0ff667758b7a95fb0379025bd55465b2e
5
5
  SHA512:
6
- metadata.gz: 6e554a728aa438a6293611ef53f7ac404932114a4ec91acee86295808d0ed39ce92e9e5afa2d1bdd5e1892bdddb949a3b6cb78b8bf61017457738e1ba4374465
7
- data.tar.gz: d7294c09046932acc67f0778dacfa9f3e86d6bb3d37b864fb10e7e52c0630fff9a9e2095f287704c5ca7cdd636c05856b281a453ac09af334941954d2a5f0c43
6
+ metadata.gz: b49f6272d981acc3fe076096ab9beb5c0d8aa57c5956ca88603d6187bd64e0285ec6bda802d4bc9f39b44927b71bc8a095834ea78e91dcee2d2816483bb9c071
7
+ data.tar.gz: a1f2dbdd21ddf76e986036aacc3949433103335f842ae2ee3bcd603716c744b214800ed47129a0a23aa3564b13a65c914edaab8417dfde1b7046dd3c3127cb9f
data/CHANGELOG.md CHANGED
@@ -1,9 +1,23 @@
1
+ # v0.1.2 2016-01-27
2
+
3
+ ### Added
4
+
5
+ * Support for resolving input from `Rule::Result` (solnic)
6
+
7
+ ### Changed
8
+
9
+ * `Check` and `Result` carry original input(s) (solnic)
10
+
11
+ [Compare v0.1.2...v0.1.3](https://github.com/dryrb/dry-logic/compare/v0.1.2...v0.1.3)
12
+
1
13
  # v0.1.2 2016-01-19
2
14
 
3
15
  ### Fixed
4
16
 
5
17
  * `xor` returns wrapped results when used against another result-rule (solnic)
6
18
 
19
+ [Compare v0.1.1...v0.1.2](https://github.com/dryrb/dry-logic/compare/v0.1.1...v0.1.2)
20
+
7
21
  # v0.1.1 2016-01-18
8
22
 
9
23
  ### Added
@@ -23,15 +23,37 @@ module Dry
23
23
 
24
24
  def to_ary
25
25
  indices = value.map { |v| v.failure? ? value.index(v) : nil }.compact
26
- [:input, [rule.name, input, value.values_at(*indices).map(&:to_ary)]]
26
+ [:input, [name, input, value.values_at(*indices).map(&:to_ary)]]
27
27
  end
28
28
  end
29
29
 
30
30
  class Result::Value < Result
31
+ def to_ary
32
+ [:input, [name, input, [rule.to_ary]]]
33
+ end
34
+ alias_method :to_a, :to_ary
35
+ end
36
+
37
+ class Result::LazyValue < Result
31
38
  def to_ary
32
39
  [:input, [rule.name, input, [rule.to_ary]]]
33
40
  end
34
41
  alias_method :to_a, :to_ary
42
+
43
+ def input
44
+ success? ? rule.evaluate_input(@input) : @input
45
+ end
46
+ end
47
+
48
+ class Result::Wrapped < Result::Value
49
+ def to_ary
50
+ [:input, [rule.name, rule.evaluate_input(input), [rule.to_ary]]]
51
+ end
52
+ alias_method :to_a, :to_ary
53
+
54
+ def wrapped?
55
+ true
56
+ end
35
57
  end
36
58
 
37
59
  class Result::Verified < Result
@@ -59,28 +81,6 @@ module Dry
59
81
  end
60
82
  end
61
83
 
62
- class Result::LazyValue < Result
63
- def to_ary
64
- [:input, [rule.name, input, [rule.to_ary]]]
65
- end
66
- alias_method :to_a, :to_ary
67
-
68
- def input
69
- success? ? rule.evaluate_input(@input) : @input
70
- end
71
- end
72
-
73
- class Result::Wrapped < Result
74
- def to_ary
75
- [:input, [name, nil, [rule.to_ary]]]
76
- end
77
- alias_method :to_a, :to_ary
78
-
79
- def wrapped?
80
- true
81
- end
82
- end
83
-
84
84
  def initialize(input, value, rule)
85
85
  @input = input
86
86
  @value = value
@@ -104,7 +104,7 @@ module Dry
104
104
  self.class.new(input, !value, rule)
105
105
  end
106
106
 
107
- def >(other)
107
+ def then(other)
108
108
  if success?
109
109
  other.(input)
110
110
  else
@@ -1,10 +1,27 @@
1
1
  module Dry
2
2
  module Logic
3
3
  class Rule::Check < Rule
4
- alias_method :result, :predicate
4
+ attr_reader :keys
5
5
 
6
- def call(*args)
7
- Logic.Result(nil, result.(*args), self)
6
+ class Unary < Rule::Check
7
+ def evaluate_input(*)
8
+ predicate.input
9
+ end
10
+ end
11
+
12
+ class Binary < Rule::Check
13
+ def evaluate_input(result)
14
+ keys.map { |key| result[key].input }
15
+ end
16
+ end
17
+
18
+ def initialize(name, predicate, keys)
19
+ super(name, predicate)
20
+ @keys = keys
21
+ end
22
+
23
+ def call(result)
24
+ Logic.Result(evaluate_input(result), predicate.(result), self)
8
25
  end
9
26
 
10
27
  def type
@@ -22,7 +22,7 @@ module Dry
22
22
 
23
23
  class Rule::Implication < Rule::Composite
24
24
  def call(*args)
25
- left.(*args) > right
25
+ left.(*args).then(right)
26
26
  end
27
27
 
28
28
  def type
@@ -12,6 +12,10 @@ module Dry
12
12
  end
13
13
  end
14
14
 
15
+ def evaluate_input(result)
16
+ result[name].input
17
+ end
18
+
15
19
  def type
16
20
  :res
17
21
  end
@@ -10,7 +10,7 @@ module Dry
10
10
  end
11
11
 
12
12
  def call(ast)
13
- ast.map { |node| visit(node) }
13
+ ast.to_ary.map { |node| visit(node) }
14
14
  end
15
15
 
16
16
  def visit(node)
@@ -19,8 +19,10 @@ module Dry
19
19
  end
20
20
 
21
21
  def visit_check(node)
22
- name, predicate = node
23
- Rule::Check.new(name, visit(predicate))
22
+ name, predicate, keys = node
23
+ check_keys = keys ? keys : [name]
24
+ klass = check_keys.size == 1 ? Rule::Check::Unary : Rule::Check::Binary
25
+ klass.new(name, visit(predicate), check_keys)
24
26
  end
25
27
 
26
28
  def visit_res(node)
@@ -28,6 +30,18 @@ module Dry
28
30
  Rule::Result.new(name, visit(predicate))
29
31
  end
30
32
 
33
+ def visit_args(nodes)
34
+ nodes.map { |node| visit(node) }
35
+ end
36
+
37
+ def visit_res_arg(name)
38
+ predicates[name].input
39
+ end
40
+
41
+ def visit_arg(value)
42
+ value
43
+ end
44
+
31
45
  def visit_not(node)
32
46
  visit(node).negation
33
47
  end
@@ -59,7 +73,12 @@ module Dry
59
73
 
60
74
  def visit_predicate(node)
61
75
  name, args = node
62
- predicates[name].curry(*args)
76
+
77
+ if args[0] == :args
78
+ predicates[name].curry(*visit(args))
79
+ else
80
+ predicates[name].curry(*args)
81
+ end
63
82
  end
64
83
 
65
84
  def visit_and(node)
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Logic
3
- VERSION = '0.1.2'.freeze
3
+ VERSION = '0.1.3'.freeze
4
4
  end
5
5
  end
@@ -1,5 +1,7 @@
1
1
  RSpec.describe Rule::Check do
2
- subject(:rule) { Rule::Check.new(:name, other.(input).curry(predicate)) }
2
+ subject(:rule) do
3
+ Rule::Check::Unary.new(:name, other.(input).curry(predicate), [:name])
4
+ end
3
5
 
4
6
  include_context 'predicates'
5
7
 
@@ -8,21 +10,21 @@ RSpec.describe Rule::Check do
8
10
  end
9
11
 
10
12
  describe '#call' do
11
- context 'when a given predicate passed' do
13
+ context 'when then given predicate passed' do
12
14
  let(:input) { 'Jane' }
13
15
  let(:predicate) { :filled? }
14
16
 
15
17
  it 'returns a success' do
16
- expect(rule.()).to be_success
18
+ expect(rule.('Jane')).to be_success
17
19
  end
18
20
  end
19
21
 
20
- context 'when a given predicate did not pass' do
22
+ context 'when the given predicate did not pass' do
21
23
  let(:input) { nil }
22
24
  let(:predicate) { :filled? }
23
25
 
24
26
  it 'returns a failure' do
25
- expect(rule.()).to be_failure
27
+ expect(rule.(nil)).to be_failure
26
28
  end
27
29
  end
28
30
  end
@@ -19,7 +19,7 @@ RSpec.describe Dry::Logic::Rule::Result do
19
19
  it 'evaluates successful input for the ast' do
20
20
  expect(rule.(name: is_str.('jane')).to_ary).to eql([
21
21
  :input, [
22
- :name, nil, [[:res, [:name, [:predicate, [:min_size?, [4]]]]]]
22
+ :name, 'jane', [[:res, [:name, [:predicate, [:min_size?, [4]]]]]]
23
23
  ]
24
24
  ])
25
25
  end
@@ -44,7 +44,7 @@ RSpec.describe Dry::Logic::Rule::Result do
44
44
  it 'evaluates input for the ast' do
45
45
  expect(conjunction.(name: is_str.('john')).to_ary).to eql([
46
46
  :input, [
47
- :name, nil, [[:res, [:name, [:predicate, [:eql?, ["jane"]]]]]]
47
+ :name, 'john', [[:res, [:name, [:predicate, [:eql?, ['jane']]]]]]
48
48
  ]
49
49
  ])
50
50
  end
@@ -63,7 +63,7 @@ RSpec.describe Dry::Logic::Rule::Result do
63
63
 
64
64
  expect(result.to_ary).to eql([
65
65
  :input, [
66
- :name, nil, [[:res, [:name, [:predicate, [:min_size?, [4]]]]]]
66
+ :name, 'john', [[:res, [:name, [:predicate, [:min_size?, [4]]]]]]
67
67
  ]
68
68
  ])
69
69
  end
@@ -83,7 +83,7 @@ RSpec.describe Dry::Logic::Rule::Result do
83
83
 
84
84
  expect(result.to_ary).to eql([
85
85
  :input, [
86
- :name, nil, [[:res, [:name, [:predicate, [:eql?, ['jane']]]]]]
86
+ :name, 'john', [[:res, [:name, [:predicate, [:eql?, ['jane']]]]]]
87
87
  ]
88
88
  ])
89
89
  end
@@ -7,7 +7,10 @@ RSpec.describe Dry::Logic::RuleCompiler, '#call' do
7
7
  { key?: predicate,
8
8
  attr?: predicate,
9
9
  filled?: predicate,
10
- email: val_rule.('email').curry(:filled?) }
10
+ gt?: predicate,
11
+ email: val_rule.('email').curry(:filled?),
12
+ left: res_left_rule,
13
+ right: double(input: 312) }
11
14
  }
12
15
 
13
16
  let(:predicate) { double(:predicate).as_null_object }
@@ -16,8 +19,9 @@ RSpec.describe Dry::Logic::RuleCompiler, '#call' do
16
19
  let(:not_key_rule) { Rule::Key.new(:email, predicate).negation }
17
20
  let(:attr_rule) { Rule::Attr.new(:email, predicate) }
18
21
  let(:val_rule) { Rule::Value.new(:email, predicate) }
19
- let(:check_rule) { Rule::Check.new(:email, predicates[:email]) }
22
+ let(:check_rule) { Rule::Check::Unary.new(:email, predicates[:email], [:email]) }
20
23
  let(:res_rule) { Rule::Result.new(:email, predicates[:email]) }
24
+ let(:res_left_rule) { Rule::Result.new(:left, predicate) }
21
25
  let(:and_rule) { key_rule & val_rule }
22
26
  let(:or_rule) { key_rule | val_rule }
23
27
  let(:xor_rule) { key_rule ^ val_rule }
@@ -48,6 +52,16 @@ RSpec.describe Dry::Logic::RuleCompiler, '#call' do
48
52
  expect(rules).to eql([res_rule])
49
53
  end
50
54
 
55
+ it 'compiles result rules with res args' do
56
+ ast = [[:res, [:left, [:predicate, [:gt?, [:args, [[:res_arg, :right]]]]]]]]
57
+
58
+ expect(predicate).to receive(:curry).with(312)
59
+
60
+ rules = compiler.(ast)
61
+
62
+ expect(rules).to eql([res_left_rule])
63
+ end
64
+
51
65
  it 'compiles attr rules' do
52
66
  ast = [[:attr, [:email, [:predicate, [:attr?, predicate]]]]]
53
67
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-logic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-19 00:00:00.000000000 Z
11
+ date: 2016-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-container