dry-logic 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/README.md +6 -2
  4. data/lib/dry/logic/evaluator.rb +46 -0
  5. data/lib/dry/logic/predicate.rb +3 -3
  6. data/lib/dry/logic/result.rb +26 -126
  7. data/lib/dry/logic/result/each.rb +10 -0
  8. data/lib/dry/logic/result/multi.rb +14 -0
  9. data/lib/dry/logic/result/named.rb +17 -0
  10. data/lib/dry/logic/result/set.rb +10 -0
  11. data/lib/dry/logic/result/value.rb +13 -0
  12. data/lib/dry/logic/rule.rb +14 -36
  13. data/lib/dry/logic/rule/attr.rb +3 -11
  14. data/lib/dry/logic/rule/check.rb +23 -22
  15. data/lib/dry/logic/rule/composite.rb +32 -12
  16. data/lib/dry/logic/rule/each.rb +3 -3
  17. data/lib/dry/logic/rule/key.rb +24 -5
  18. data/lib/dry/logic/rule/negation.rb +15 -0
  19. data/lib/dry/logic/rule/set.rb +9 -8
  20. data/lib/dry/logic/rule/value.rb +15 -3
  21. data/lib/dry/logic/rule_compiler.rb +8 -40
  22. data/lib/dry/logic/version.rb +1 -1
  23. data/spec/shared/predicates.rb +2 -0
  24. data/spec/spec_helper.rb +1 -0
  25. data/spec/unit/rule/attr_spec.rb +5 -5
  26. data/spec/unit/rule/check_spec.rb +26 -39
  27. data/spec/unit/rule/conjunction_spec.rb +4 -4
  28. data/spec/unit/rule/disjunction_spec.rb +3 -3
  29. data/spec/unit/rule/each_spec.rb +2 -2
  30. data/spec/unit/rule/exclusive_disjunction_spec.rb +19 -0
  31. data/spec/unit/rule/implication_spec.rb +2 -2
  32. data/spec/unit/rule/key_spec.rb +103 -9
  33. data/spec/unit/rule/set_spec.rb +7 -9
  34. data/spec/unit/rule/value_spec.rb +29 -3
  35. data/spec/unit/rule_compiler_spec.rb +21 -49
  36. metadata +12 -9
  37. data/lib/dry/logic/rule/group.rb +0 -21
  38. data/lib/dry/logic/rule/result.rb +0 -33
  39. data/rakelib/rubocop.rake +0 -18
  40. data/spec/unit/rule/group_spec.rb +0 -12
  41. data/spec/unit/rule/result_spec.rb +0 -102
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
4
+ version: 0.2.0
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-27 00:00:00.000000000 Z
11
+ date: 2016-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-container
@@ -107,23 +107,27 @@ files:
107
107
  - examples/basic.rb
108
108
  - lib/dry-logic.rb
109
109
  - lib/dry/logic.rb
110
+ - lib/dry/logic/evaluator.rb
110
111
  - lib/dry/logic/predicate.rb
111
112
  - lib/dry/logic/predicate_set.rb
112
113
  - lib/dry/logic/predicates.rb
113
114
  - lib/dry/logic/result.rb
115
+ - lib/dry/logic/result/each.rb
116
+ - lib/dry/logic/result/multi.rb
117
+ - lib/dry/logic/result/named.rb
118
+ - lib/dry/logic/result/set.rb
119
+ - lib/dry/logic/result/value.rb
114
120
  - lib/dry/logic/rule.rb
115
121
  - lib/dry/logic/rule/attr.rb
116
122
  - lib/dry/logic/rule/check.rb
117
123
  - lib/dry/logic/rule/composite.rb
118
124
  - lib/dry/logic/rule/each.rb
119
- - lib/dry/logic/rule/group.rb
120
125
  - lib/dry/logic/rule/key.rb
121
- - lib/dry/logic/rule/result.rb
126
+ - lib/dry/logic/rule/negation.rb
122
127
  - lib/dry/logic/rule/set.rb
123
128
  - lib/dry/logic/rule/value.rb
124
129
  - lib/dry/logic/rule_compiler.rb
125
130
  - lib/dry/logic/version.rb
126
- - rakelib/rubocop.rake
127
131
  - spec/shared/predicates.rb
128
132
  - spec/spec_helper.rb
129
133
  - spec/unit/predicate_spec.rb
@@ -158,10 +162,9 @@ files:
158
162
  - spec/unit/rule/conjunction_spec.rb
159
163
  - spec/unit/rule/disjunction_spec.rb
160
164
  - spec/unit/rule/each_spec.rb
161
- - spec/unit/rule/group_spec.rb
165
+ - spec/unit/rule/exclusive_disjunction_spec.rb
162
166
  - spec/unit/rule/implication_spec.rb
163
167
  - spec/unit/rule/key_spec.rb
164
- - spec/unit/rule/result_spec.rb
165
168
  - spec/unit/rule/set_spec.rb
166
169
  - spec/unit/rule/value_spec.rb
167
170
  - spec/unit/rule_compiler_spec.rb
@@ -224,10 +227,10 @@ test_files:
224
227
  - spec/unit/rule/conjunction_spec.rb
225
228
  - spec/unit/rule/disjunction_spec.rb
226
229
  - spec/unit/rule/each_spec.rb
227
- - spec/unit/rule/group_spec.rb
230
+ - spec/unit/rule/exclusive_disjunction_spec.rb
228
231
  - spec/unit/rule/implication_spec.rb
229
232
  - spec/unit/rule/key_spec.rb
230
- - spec/unit/rule/result_spec.rb
231
233
  - spec/unit/rule/set_spec.rb
232
234
  - spec/unit/rule/value_spec.rb
233
235
  - spec/unit/rule_compiler_spec.rb
236
+ has_rdoc:
@@ -1,21 +0,0 @@
1
- module Dry
2
- module Logic
3
- class Rule::Group < Rule
4
- attr_reader :rules
5
-
6
- def initialize(identifier, predicate)
7
- name, rules = identifier.to_a.first
8
- @rules = rules
9
- super(name, predicate)
10
- end
11
-
12
- def call(*input)
13
- Logic.Result(input, predicate.(*input), self)
14
- end
15
-
16
- def type
17
- :group
18
- end
19
- end
20
- end
21
- end
@@ -1,33 +0,0 @@
1
- module Dry
2
- module Logic
3
- class Rule::Result < Rule
4
- def call(input)
5
- result = if name.is_a?(Hash)
6
- parent, _ = name.to_a.flatten
7
- input[parent]
8
- else
9
- input[name]
10
- end
11
-
12
- if result.success?
13
- Result::Wrapped.new(input, predicate.(evaluate_input(input)), self)
14
- else
15
- result
16
- end
17
- end
18
-
19
- def evaluate_input(result)
20
- if name.is_a?(Hash)
21
- parent, child = name.to_a.flatten
22
- result[parent].input[child]
23
- else
24
- result[name].input
25
- end
26
- end
27
-
28
- def type
29
- :res
30
- end
31
- end
32
- end
33
- end
@@ -1,18 +0,0 @@
1
- begin
2
- require 'rubocop/rake_task'
3
-
4
- Rake::Task[:default].enhance [:rubocop]
5
-
6
- RuboCop::RakeTask.new do |task|
7
- task.options << '--display-cop-names'
8
- end
9
-
10
- namespace :rubocop do
11
- desc 'Generate a configuration file acting as a TODO list.'
12
- task :auto_gen_config do
13
- exec 'bundle exec rubocop --auto-gen-config'
14
- end
15
- end
16
-
17
- rescue LoadError
18
- end
@@ -1,12 +0,0 @@
1
- RSpec.describe Rule::Group do
2
- include_context 'predicates'
3
-
4
- subject(:rule) { Rule::Group.new([:pass, :pass_confirm], eql?) }
5
-
6
- describe '#call' do
7
- it 'calls predicate with result values' do
8
- expect(rule.('foo', 'foo')).to be_success
9
- expect(rule.('foo', 'bar')).to be_failure
10
- end
11
- end
12
- end
@@ -1,102 +0,0 @@
1
- require 'dry/logic/rule/result'
2
-
3
- RSpec.describe Dry::Logic::Rule::Result do
4
- subject(:rule) { Dry::Logic::Rule::Result.new(:name, min_size?.curry(4)) }
5
-
6
- include_context 'predicates'
7
-
8
- let(:is_str) { Dry::Logic::Rule::Value.new(:name, str?) }
9
- let(:is_hash) { Dry::Logic::Rule::Value.new(:name, hash?) }
10
- let(:is_jane) { Dry::Logic::Rule::Result.new(:name, eql?.curry('jane')) }
11
- let(:is_john) { Dry::Logic::Rule::Result.new(:name, eql?.curry('john')) }
12
-
13
- describe '#call' do
14
- it 'returns result of a predicate' do
15
- expect(rule.(name: is_str.('jane'))).to be_success
16
- expect(rule.(name: is_str.('jan'))).to be_failure
17
- expect(rule.(name: is_str.(nil))).to be_failure
18
- end
19
-
20
- it 'evaluates successful input for the ast' do
21
- expect(rule.(name: is_str.('jane')).to_ary).to eql([
22
- :input, [
23
- :name, 'jane', [[:res, [:name, [:predicate, [:min_size?, [4]]]]]]
24
- ]
25
- ])
26
- end
27
-
28
- it 'evaluates failed input for the ast' do
29
- expect(rule.(name: is_str.(:john)).to_ary).to eql([
30
- :input, [
31
- :name, :john, [[:val, [:name, [:predicate, [:str?, []]]]]]
32
- ]
33
- ])
34
- end
35
- end
36
-
37
- describe '#call with nested result' do
38
- subject(:rule) do
39
- Dry::Logic::Rule::Result.new({ user: :address }, str?)
40
- end
41
-
42
- it 'evaluates the input' do
43
- expect(rule.(user: is_hash.(address: 'Earth'))).to be_success
44
- end
45
- end
46
-
47
- describe '#and' do
48
- let(:conjunction) { rule.and(is_jane) }
49
-
50
- it 'returns result of a conjunction' do
51
- expect(conjunction.(name: is_str.('jane'))).to be_success
52
- expect(conjunction.(name: is_str.('john'))).to be_failure
53
- end
54
-
55
- it 'evaluates input for the ast' do
56
- expect(conjunction.(name: is_str.('john')).to_ary).to eql([
57
- :input, [
58
- :name, 'john', [[:res, [:name, [:predicate, [:eql?, ['jane']]]]]]
59
- ]
60
- ])
61
- end
62
- end
63
-
64
- describe '#xor' do
65
- let(:xor) { rule.xor(is_john) }
66
-
67
- it 'returns result of an exclusive disjunction' do
68
- expect(xor.(name: is_str.('jane'))).to be_success
69
- expect(xor.(name: is_str.('john'))).to be_failure
70
- end
71
-
72
- it 'evaluates input for the ast' do
73
- result = xor.(name: is_str.('john'))
74
-
75
- expect(result.to_ary).to eql([
76
- :input, [
77
- :name, 'john', [[:res, [:name, [:predicate, [:min_size?, [4]]]]]]
78
- ]
79
- ])
80
- end
81
- end
82
-
83
- describe '#then' do
84
- let(:implication) { rule.then(is_jane) }
85
-
86
- it 'returns result of an exclusive disjunction' do
87
- expect(implication.(name: is_str.('jane'))).to be_success
88
- expect(implication.(name: is_str.(nil))).to be_success
89
- expect(implication.(name: is_str.('john'))).to be_failure
90
- end
91
-
92
- it 'evaluates input for the ast' do
93
- result = implication.(name: is_str.('john'))
94
-
95
- expect(result.to_ary).to eql([
96
- :input, [
97
- :name, 'john', [[:res, [:name, [:predicate, [:eql?, ['jane']]]]]]
98
- ]
99
- ])
100
- end
101
- end
102
- end