dry-logic 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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