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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -22
  3. data/LICENSE +1 -1
  4. data/README.md +12 -14
  5. data/dry-logic.gemspec +29 -14
  6. data/lib/dry-logic.rb +2 -0
  7. data/lib/dry/logic.rb +2 -0
  8. data/lib/dry/logic/appliable.rb +2 -0
  9. data/lib/dry/logic/evaluator.rb +2 -0
  10. data/lib/dry/logic/operations.rb +2 -0
  11. data/lib/dry/logic/operations/abstract.rb +5 -3
  12. data/lib/dry/logic/operations/and.rb +3 -1
  13. data/lib/dry/logic/operations/attr.rb +2 -0
  14. data/lib/dry/logic/operations/binary.rb +2 -0
  15. data/lib/dry/logic/operations/check.rb +3 -1
  16. data/lib/dry/logic/operations/each.rb +2 -0
  17. data/lib/dry/logic/operations/implication.rb +2 -0
  18. data/lib/dry/logic/operations/key.rb +4 -2
  19. data/lib/dry/logic/operations/negation.rb +2 -0
  20. data/lib/dry/logic/operations/or.rb +2 -0
  21. data/lib/dry/logic/operations/set.rb +2 -0
  22. data/lib/dry/logic/operations/unary.rb +2 -0
  23. data/lib/dry/logic/operations/xor.rb +2 -0
  24. data/lib/dry/logic/operators.rb +2 -0
  25. data/lib/dry/logic/predicates.rb +39 -21
  26. data/lib/dry/logic/result.rb +2 -0
  27. data/lib/dry/logic/rule.rb +5 -3
  28. data/lib/dry/logic/rule/interface.rb +3 -1
  29. data/lib/dry/logic/rule/predicate.rb +2 -0
  30. data/lib/dry/logic/rule_compiler.rb +2 -0
  31. data/lib/dry/logic/version.rb +3 -1
  32. metadata +11 -128
  33. data/.codeclimate.yml +0 -15
  34. data/.gitignore +0 -8
  35. data/.rspec +0 -3
  36. data/.travis.yml +0 -31
  37. data/CONTRIBUTING.md +0 -29
  38. data/Gemfile +0 -13
  39. data/Rakefile +0 -12
  40. data/benchmarks/rule_application.rb +0 -28
  41. data/benchmarks/setup.rb +0 -11
  42. data/bin/console +0 -10
  43. data/examples/basic.rb +0 -14
  44. data/spec/integration/result_spec.rb +0 -59
  45. data/spec/integration/rule_spec.rb +0 -53
  46. data/spec/shared/predicates.rb +0 -57
  47. data/spec/shared/rule.rb +0 -72
  48. data/spec/spec_helper.rb +0 -34
  49. data/spec/support/mutant.rb +0 -9
  50. data/spec/unit/operations/and_spec.rb +0 -68
  51. data/spec/unit/operations/attr_spec.rb +0 -27
  52. data/spec/unit/operations/check_spec.rb +0 -49
  53. data/spec/unit/operations/each_spec.rb +0 -47
  54. data/spec/unit/operations/implication_spec.rb +0 -30
  55. data/spec/unit/operations/key_spec.rb +0 -133
  56. data/spec/unit/operations/negation_spec.rb +0 -49
  57. data/spec/unit/operations/or_spec.rb +0 -73
  58. data/spec/unit/operations/set_spec.rb +0 -41
  59. data/spec/unit/operations/xor_spec.rb +0 -61
  60. data/spec/unit/predicates/array_spec.rb +0 -41
  61. data/spec/unit/predicates/attr_spec.rb +0 -29
  62. data/spec/unit/predicates/bool_spec.rb +0 -34
  63. data/spec/unit/predicates/case_spec.rb +0 -33
  64. data/spec/unit/predicates/date_spec.rb +0 -31
  65. data/spec/unit/predicates/date_time_spec.rb +0 -31
  66. data/spec/unit/predicates/decimal_spec.rb +0 -32
  67. data/spec/unit/predicates/empty_spec.rb +0 -38
  68. data/spec/unit/predicates/eql_spec.rb +0 -21
  69. data/spec/unit/predicates/even_spec.rb +0 -31
  70. data/spec/unit/predicates/excluded_from_spec.rb +0 -35
  71. data/spec/unit/predicates/excludes_spec.rb +0 -56
  72. data/spec/unit/predicates/false_spec.rb +0 -35
  73. data/spec/unit/predicates/filled_spec.rb +0 -38
  74. data/spec/unit/predicates/float_spec.rb +0 -31
  75. data/spec/unit/predicates/format_spec.rb +0 -21
  76. data/spec/unit/predicates/gt_spec.rb +0 -40
  77. data/spec/unit/predicates/gteq_spec.rb +0 -40
  78. data/spec/unit/predicates/included_in_spec.rb +0 -35
  79. data/spec/unit/predicates/includes_spec.rb +0 -24
  80. data/spec/unit/predicates/int_spec.rb +0 -34
  81. data/spec/unit/predicates/key_spec.rb +0 -29
  82. data/spec/unit/predicates/lt_spec.rb +0 -40
  83. data/spec/unit/predicates/lteq_spec.rb +0 -40
  84. data/spec/unit/predicates/max_size_spec.rb +0 -49
  85. data/spec/unit/predicates/min_size_spec.rb +0 -49
  86. data/spec/unit/predicates/none_spec.rb +0 -28
  87. data/spec/unit/predicates/not_eql_spec.rb +0 -21
  88. data/spec/unit/predicates/number_spec.rb +0 -37
  89. data/spec/unit/predicates/odd_spec.rb +0 -31
  90. data/spec/unit/predicates/size_spec.rb +0 -55
  91. data/spec/unit/predicates/str_spec.rb +0 -32
  92. data/spec/unit/predicates/time_spec.rb +0 -31
  93. data/spec/unit/predicates/true_spec.rb +0 -35
  94. data/spec/unit/predicates/type_spec.rb +0 -35
  95. data/spec/unit/predicates_spec.rb +0 -23
  96. data/spec/unit/rule/predicate_spec.rb +0 -53
  97. data/spec/unit/rule_compiler_spec.rb +0 -127
  98. 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