dry-logic 0.6.1 → 1.0.6
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 +121 -22
- data/LICENSE +1 -1
- data/README.md +12 -14
- data/dry-logic.gemspec +29 -14
- data/lib/dry-logic.rb +2 -0
- data/lib/dry/logic.rb +2 -0
- data/lib/dry/logic/appliable.rb +2 -0
- data/lib/dry/logic/evaluator.rb +2 -0
- data/lib/dry/logic/operations.rb +2 -0
- data/lib/dry/logic/operations/abstract.rb +5 -3
- data/lib/dry/logic/operations/and.rb +3 -1
- data/lib/dry/logic/operations/attr.rb +2 -0
- data/lib/dry/logic/operations/binary.rb +2 -0
- data/lib/dry/logic/operations/check.rb +3 -1
- data/lib/dry/logic/operations/each.rb +2 -0
- data/lib/dry/logic/operations/implication.rb +2 -0
- data/lib/dry/logic/operations/key.rb +4 -2
- data/lib/dry/logic/operations/negation.rb +2 -0
- data/lib/dry/logic/operations/or.rb +2 -0
- data/lib/dry/logic/operations/set.rb +2 -0
- data/lib/dry/logic/operations/unary.rb +2 -0
- data/lib/dry/logic/operations/xor.rb +2 -0
- data/lib/dry/logic/operators.rb +2 -0
- data/lib/dry/logic/predicates.rb +39 -21
- data/lib/dry/logic/result.rb +2 -0
- data/lib/dry/logic/rule.rb +5 -3
- data/lib/dry/logic/rule/interface.rb +3 -1
- data/lib/dry/logic/rule/predicate.rb +2 -0
- data/lib/dry/logic/rule_compiler.rb +2 -0
- data/lib/dry/logic/version.rb +3 -1
- metadata +11 -128
- data/.codeclimate.yml +0 -15
- data/.gitignore +0 -8
- data/.rspec +0 -3
- data/.travis.yml +0 -31
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -13
- data/Rakefile +0 -12
- data/benchmarks/rule_application.rb +0 -28
- data/benchmarks/setup.rb +0 -11
- data/bin/console +0 -10
- data/examples/basic.rb +0 -14
- 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 -72
- data/spec/spec_helper.rb +0 -34
- data/spec/support/mutant.rb +0 -9
- data/spec/unit/operations/and_spec.rb +0 -68
- 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 -211
@@ -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.build(int?) }
|
7
|
-
let(:gt_18) { Rule::Predicate.build(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.build(array?) }
|
7
|
-
let(:right) { Rule::Predicate.build(empty?) }
|
8
|
-
|
9
|
-
let(:other) do
|
10
|
-
Rule::Predicate.build(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
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#array?' do
|
5
|
-
let(:predicate_name) { :array? }
|
6
|
-
|
7
|
-
context 'when value is an array' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[
|
10
|
-
[ [] ],
|
11
|
-
[ ['other', 'array'] ],
|
12
|
-
[ [123, 'really', :blah] ],
|
13
|
-
[ Array.new ],
|
14
|
-
[ [nil] ],
|
15
|
-
[ [false] ],
|
16
|
-
[ [true] ]
|
17
|
-
]
|
18
|
-
end
|
19
|
-
|
20
|
-
it_behaves_like 'a passing predicate'
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'when value is not an array' do
|
24
|
-
let(:arguments_list) do
|
25
|
-
[
|
26
|
-
[''],
|
27
|
-
[{}],
|
28
|
-
[nil],
|
29
|
-
[:symbol],
|
30
|
-
[String],
|
31
|
-
[1],
|
32
|
-
[1.0],
|
33
|
-
[true],
|
34
|
-
[Hash.new]
|
35
|
-
]
|
36
|
-
end
|
37
|
-
|
38
|
-
it_behaves_like 'a failing predicate'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#attr?' do
|
5
|
-
let(:predicate_name) { :attr? }
|
6
|
-
|
7
|
-
context 'when value responds to the attr name' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[
|
10
|
-
[:name, Struct.new(:name).new('John')],
|
11
|
-
[:age, Struct.new(:age).new(18)]
|
12
|
-
]
|
13
|
-
end
|
14
|
-
|
15
|
-
it_behaves_like 'a passing predicate'
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'with value does not respond to the attr name' do
|
19
|
-
let(:arguments_list) do
|
20
|
-
[
|
21
|
-
[:name, Struct.new(:age).new(18)],
|
22
|
-
[:age, Struct.new(:name).new('Jill')]
|
23
|
-
]
|
24
|
-
end
|
25
|
-
|
26
|
-
it_behaves_like 'a failing predicate'
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#bool?' do
|
5
|
-
let(:predicate_name) { :bool? }
|
6
|
-
|
7
|
-
context 'when value is a date' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[[true], [false]]
|
10
|
-
end
|
11
|
-
|
12
|
-
it_behaves_like 'a passing predicate'
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'when value is not a bool' do
|
16
|
-
let(:arguments_list) do
|
17
|
-
[
|
18
|
-
[''],
|
19
|
-
[[]],
|
20
|
-
[{}],
|
21
|
-
[nil],
|
22
|
-
[:symbol],
|
23
|
-
[String],
|
24
|
-
[1],
|
25
|
-
[0],
|
26
|
-
['true'],
|
27
|
-
['false']
|
28
|
-
]
|
29
|
-
end
|
30
|
-
|
31
|
-
it_behaves_like 'a failing predicate'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#case?' do
|
5
|
-
let(:predicate_name) { :case? }
|
6
|
-
|
7
|
-
context 'when the value matches the pattern' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[
|
10
|
-
[11, 11],
|
11
|
-
[:odd?.to_proc, 11],
|
12
|
-
[/\Af/, 'foo'],
|
13
|
-
[Integer, 11]
|
14
|
-
]
|
15
|
-
end
|
16
|
-
|
17
|
-
it_behaves_like 'a passing predicate'
|
18
|
-
end
|
19
|
-
|
20
|
-
context "when the value doesn't match the pattern" do
|
21
|
-
let(:arguments_list) do
|
22
|
-
[
|
23
|
-
[13, 14],
|
24
|
-
[:odd?.to_proc, 12],
|
25
|
-
[/\Af/, 'bar'],
|
26
|
-
[String, 11]
|
27
|
-
]
|
28
|
-
end
|
29
|
-
|
30
|
-
it_behaves_like 'a failing predicate'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#date?' do
|
5
|
-
let(:predicate_name) { :date? }
|
6
|
-
|
7
|
-
context 'when value is a date' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[[Date.today]]
|
10
|
-
end
|
11
|
-
|
12
|
-
it_behaves_like 'a passing predicate'
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'with value is not an integer' do
|
16
|
-
let(:arguments_list) do
|
17
|
-
[
|
18
|
-
[''],
|
19
|
-
[[]],
|
20
|
-
[{}],
|
21
|
-
[nil],
|
22
|
-
[:symbol],
|
23
|
-
[String],
|
24
|
-
[1]
|
25
|
-
]
|
26
|
-
end
|
27
|
-
|
28
|
-
it_behaves_like 'a failing predicate'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#date_time?' do
|
5
|
-
let(:predicate_name) { :date_time? }
|
6
|
-
|
7
|
-
context 'when value is a date' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[[DateTime.now]]
|
10
|
-
end
|
11
|
-
|
12
|
-
it_behaves_like 'a passing predicate'
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'with value is not an integer' do
|
16
|
-
let(:arguments_list) do
|
17
|
-
[
|
18
|
-
[''],
|
19
|
-
[[]],
|
20
|
-
[{}],
|
21
|
-
[nil],
|
22
|
-
[:symbol],
|
23
|
-
[String],
|
24
|
-
[1]
|
25
|
-
]
|
26
|
-
end
|
27
|
-
|
28
|
-
it_behaves_like 'a failing predicate'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#decimal?' do
|
5
|
-
let(:predicate_name) { :decimal? }
|
6
|
-
|
7
|
-
context 'when value is a date' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[[1.2.to_d]]
|
10
|
-
end
|
11
|
-
|
12
|
-
it_behaves_like 'a passing predicate'
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'with value is not an integer' do
|
16
|
-
let(:arguments_list) do
|
17
|
-
[
|
18
|
-
[''],
|
19
|
-
[[]],
|
20
|
-
[{}],
|
21
|
-
[nil],
|
22
|
-
[:symbol],
|
23
|
-
[String],
|
24
|
-
[1],
|
25
|
-
[1.0]
|
26
|
-
]
|
27
|
-
end
|
28
|
-
|
29
|
-
it_behaves_like 'a failing predicate'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#empty?' do
|
5
|
-
let(:predicate_name) { :empty? }
|
6
|
-
|
7
|
-
context 'when value is empty' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[
|
10
|
-
[''],
|
11
|
-
[[]],
|
12
|
-
[{}],
|
13
|
-
[nil]
|
14
|
-
]
|
15
|
-
end
|
16
|
-
|
17
|
-
it_behaves_like 'a passing predicate'
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'with value is not empty' do
|
21
|
-
let(:arguments_list) do
|
22
|
-
[
|
23
|
-
['Jill'],
|
24
|
-
[[1, 2, 3]],
|
25
|
-
[{ name: 'John' }],
|
26
|
-
[true],
|
27
|
-
[false],
|
28
|
-
['1'],
|
29
|
-
['0'],
|
30
|
-
[:symbol],
|
31
|
-
[String]
|
32
|
-
]
|
33
|
-
end
|
34
|
-
|
35
|
-
it_behaves_like 'a failing predicate'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates, '#eql?' do
|
4
|
-
let(:predicate_name) { :eql? }
|
5
|
-
|
6
|
-
context 'when value is equal to the arg' do
|
7
|
-
let(:arguments_list) do
|
8
|
-
[['Foo', 'Foo']]
|
9
|
-
end
|
10
|
-
|
11
|
-
it_behaves_like 'a passing predicate'
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'with value is not equal to the arg' do
|
15
|
-
let(:arguments_list) do
|
16
|
-
[['Bar', 'Foo']]
|
17
|
-
end
|
18
|
-
|
19
|
-
it_behaves_like 'a failing predicate'
|
20
|
-
end
|
21
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#even?' do
|
5
|
-
let(:predicate_name) { :even? }
|
6
|
-
|
7
|
-
context 'when value is an odd int' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[
|
10
|
-
[13],
|
11
|
-
[1],
|
12
|
-
[1111]
|
13
|
-
]
|
14
|
-
end
|
15
|
-
|
16
|
-
it_behaves_like 'a failing predicate'
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'with value is an even int' do
|
20
|
-
let(:arguments_list) do
|
21
|
-
[
|
22
|
-
[0],
|
23
|
-
[2],
|
24
|
-
[2222]
|
25
|
-
]
|
26
|
-
end
|
27
|
-
|
28
|
-
it_behaves_like 'a passing predicate'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'dry/logic/predicates'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Logic::Predicates do
|
4
|
-
describe '#excluded_from?' do
|
5
|
-
let(:predicate_name) { :excluded_from? }
|
6
|
-
|
7
|
-
context 'when value is not present in list' do
|
8
|
-
let(:arguments_list) do
|
9
|
-
[
|
10
|
-
[['Jill', 'John'], 'Jack'],
|
11
|
-
[1..2, 0],
|
12
|
-
[1..2, 3],
|
13
|
-
[[nil, false], true]
|
14
|
-
]
|
15
|
-
end
|
16
|
-
|
17
|
-
it_behaves_like 'a passing predicate'
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'with value is present in list' do
|
21
|
-
let(:arguments_list) do
|
22
|
-
[
|
23
|
-
[['Jill', 'John'], 'Jill'],
|
24
|
-
[['Jill', 'John'], 'John'],
|
25
|
-
[1..2, 1],
|
26
|
-
[1..2, 2],
|
27
|
-
[[nil, false], nil],
|
28
|
-
[[nil, false], false]
|
29
|
-
]
|
30
|
-
end
|
31
|
-
|
32
|
-
it_behaves_like 'a failing predicate'
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|