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 +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/dry/logic/result.rb +24 -24
- data/lib/dry/logic/rule/check.rb +20 -3
- data/lib/dry/logic/rule/composite.rb +1 -1
- data/lib/dry/logic/rule/result.rb +4 -0
- data/lib/dry/logic/rule_compiler.rb +23 -4
- data/lib/dry/logic/version.rb +1 -1
- data/spec/unit/rule/check_spec.rb +7 -5
- data/spec/unit/rule/result_spec.rb +4 -4
- data/spec/unit/rule_compiler_spec.rb +16 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d49a2ea6e71727f4ae69320aa0619c2ebd96325
|
4
|
+
data.tar.gz: 71414bb0ff667758b7a95fb0379025bd55465b2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/dry/logic/result.rb
CHANGED
@@ -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, [
|
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
|
107
|
+
def then(other)
|
108
108
|
if success?
|
109
109
|
other.(input)
|
110
110
|
else
|
data/lib/dry/logic/rule/check.rb
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
module Dry
|
2
2
|
module Logic
|
3
3
|
class Rule::Check < Rule
|
4
|
-
|
4
|
+
attr_reader :keys
|
5
5
|
|
6
|
-
|
7
|
-
|
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
|
@@ -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
|
-
|
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
|
-
|
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)
|
data/lib/dry/logic/version.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
RSpec.describe Rule::Check do
|
2
|
-
subject(:rule)
|
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
|
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
|
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,
|
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,
|
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,
|
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,
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2016-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-container
|