predicate 1.0.0
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 +7 -0
- data/Gemfile +2 -0
- data/LICENSE.md +22 -0
- data/Rakefile +11 -0
- data/lib/predicate/factory.rb +107 -0
- data/lib/predicate/grammar.rb +33 -0
- data/lib/predicate/grammar.sexp.yml +58 -0
- data/lib/predicate/nodes/and.rb +23 -0
- data/lib/predicate/nodes/contradiction.rb +34 -0
- data/lib/predicate/nodes/dyadic_comp.rb +26 -0
- data/lib/predicate/nodes/eq.rb +15 -0
- data/lib/predicate/nodes/expr.rb +68 -0
- data/lib/predicate/nodes/gt.rb +10 -0
- data/lib/predicate/nodes/gte.rb +10 -0
- data/lib/predicate/nodes/identifier.rb +18 -0
- data/lib/predicate/nodes/in.rb +26 -0
- data/lib/predicate/nodes/literal.rb +18 -0
- data/lib/predicate/nodes/lt.rb +10 -0
- data/lib/predicate/nodes/lte.rb +10 -0
- data/lib/predicate/nodes/nadic_bool.rb +16 -0
- data/lib/predicate/nodes/native.rb +30 -0
- data/lib/predicate/nodes/neq.rb +10 -0
- data/lib/predicate/nodes/not.rb +22 -0
- data/lib/predicate/nodes/or.rb +10 -0
- data/lib/predicate/nodes/qualified_identifier.rb +22 -0
- data/lib/predicate/nodes/tautology.rb +30 -0
- data/lib/predicate/processors/qualifier.rb +23 -0
- data/lib/predicate/processors/renamer.rb +25 -0
- data/lib/predicate/processors/to_ruby_code.rb +71 -0
- data/lib/predicate/processors.rb +3 -0
- data/lib/predicate/version.rb +8 -0
- data/lib/predicate.rb +113 -0
- data/spec/expr/test_to_proc.rb +16 -0
- data/spec/expr/test_to_ruby_code.rb +152 -0
- data/spec/factory/shared/a_comparison_factory_method.rb +35 -0
- data/spec/factory/shared/a_predicate_ast_node.rb +20 -0
- data/spec/factory/test_and.rb +13 -0
- data/spec/factory/test_between.rb +12 -0
- data/spec/factory/test_comp.rb +35 -0
- data/spec/factory/test_contradiction.rb +11 -0
- data/spec/factory/test_eq.rb +9 -0
- data/spec/factory/test_factor_predicate.rb +50 -0
- data/spec/factory/test_gt.rb +9 -0
- data/spec/factory/test_gte.rb +9 -0
- data/spec/factory/test_identifier.rb +13 -0
- data/spec/factory/test_in.rb +12 -0
- data/spec/factory/test_literal.rb +13 -0
- data/spec/factory/test_lt.rb +9 -0
- data/spec/factory/test_lte.rb +9 -0
- data/spec/factory/test_native.rb +19 -0
- data/spec/factory/test_neq.rb +9 -0
- data/spec/factory/test_not.rb +13 -0
- data/spec/factory/test_or.rb +13 -0
- data/spec/factory/test_qualified_identifier.rb +15 -0
- data/spec/factory/test_tautology.rb +12 -0
- data/spec/grammar/test_match.rb +93 -0
- data/spec/grammar/test_sexpr.rb +103 -0
- data/spec/nodes/and/test_and_split.rb +66 -0
- data/spec/nodes/dyadic_comp/test_and_split.rb +45 -0
- data/spec/nodes/identifier/test_and_split.rb +23 -0
- data/spec/nodes/identifier/test_free_variables.rb +12 -0
- data/spec/nodes/identifier/test_name.rb +12 -0
- data/spec/nodes/nadic_bool/test_free_variables.rb +14 -0
- data/spec/nodes/qualified_identifier/test_and_split.rb +23 -0
- data/spec/nodes/qualified_identifier/test_free_variables.rb +12 -0
- data/spec/nodes/qualified_identifier/test_name.rb +12 -0
- data/spec/nodes/qualified_identifier/test_qualifier.rb +12 -0
- data/spec/predicate/test_and_split.rb +57 -0
- data/spec/predicate/test_bool_and.rb +34 -0
- data/spec/predicate/test_bool_not.rb +68 -0
- data/spec/predicate/test_bool_or.rb +34 -0
- data/spec/predicate/test_coerce.rb +75 -0
- data/spec/predicate/test_constant_variables.rb +52 -0
- data/spec/predicate/test_contradiction.rb +24 -0
- data/spec/predicate/test_evaluate.rb +66 -0
- data/spec/predicate/test_factory_methods.rb +77 -0
- data/spec/predicate/test_free_variables.rb +14 -0
- data/spec/predicate/test_hash_and_equal.rb +26 -0
- data/spec/predicate/test_qualify.rb +34 -0
- data/spec/predicate/test_rename.rb +76 -0
- data/spec/predicate/test_tautology.rb +24 -0
- data/spec/predicate/test_to_proc.rb +14 -0
- data/spec/predicate/test_to_ruby_code.rb +20 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/test_predicate.rb +127 -0
- data/tasks/test.rake +11 -0
- metadata +186 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'shared/a_predicate_ast_node'
|
2
|
+
class Predicate
|
3
|
+
describe Factory, 'native' do
|
4
|
+
include Factory
|
5
|
+
|
6
|
+
subject{ native(proc) }
|
7
|
+
|
8
|
+
context 'with a proc' do
|
9
|
+
let(:proc){ ->{} }
|
10
|
+
|
11
|
+
it_should_behave_like "a predicate AST node"
|
12
|
+
|
13
|
+
it{ should be_a(Native) }
|
14
|
+
|
15
|
+
it{ should eql([:native, proc]) }
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'shared/a_predicate_ast_node'
|
2
|
+
class Predicate
|
3
|
+
describe Factory, 'not' do
|
4
|
+
include Factory
|
5
|
+
|
6
|
+
subject{ self.not(true) }
|
7
|
+
|
8
|
+
it_should_behave_like "a predicate AST node"
|
9
|
+
it{ should be_a(Not) }
|
10
|
+
it{ should eql([:not, tautology]) }
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'shared/a_predicate_ast_node'
|
2
|
+
class Predicate
|
3
|
+
describe Factory, 'or' do
|
4
|
+
include Factory
|
5
|
+
|
6
|
+
subject{ self.or(true, true) }
|
7
|
+
|
8
|
+
it_should_behave_like "a predicate AST node"
|
9
|
+
it{ should be_a(Or) }
|
10
|
+
it{ should eql([:or, tautology, tautology]) }
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'shared/a_predicate_ast_node'
|
2
|
+
class Predicate
|
3
|
+
describe Factory, 'qualified_identifier' do
|
4
|
+
include Factory
|
5
|
+
|
6
|
+
subject{ qualified_identifier(:t, :name) }
|
7
|
+
|
8
|
+
it_should_behave_like "a predicate AST node"
|
9
|
+
|
10
|
+
it{ should be_a(QualifiedIdentifier) }
|
11
|
+
|
12
|
+
it{ should eql([:qualified_identifier, :t, :name]) }
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe Grammar, 'match?' do
|
4
|
+
|
5
|
+
context "tautology" do
|
6
|
+
subject{ Grammar[:tautology] }
|
7
|
+
|
8
|
+
it 'matches a tautology' do
|
9
|
+
subject.should be_match([:tautology, true])
|
10
|
+
end
|
11
|
+
it 'does no match a wrong one' do
|
12
|
+
subject.should_not be_match([:tautology, false])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "contradiction" do
|
17
|
+
subject{ Grammar[:contradiction] }
|
18
|
+
|
19
|
+
it 'matches a tautology' do
|
20
|
+
subject.should be_match([:contradiction, false])
|
21
|
+
end
|
22
|
+
it 'does no match a wrong one' do
|
23
|
+
subject.should_not be_match([:contradiction, true])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "identifier" do
|
28
|
+
subject{ Grammar[:identifier] }
|
29
|
+
|
30
|
+
it 'matches a valid ast' do
|
31
|
+
subject.should be_match([:identifier, :id])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not match an invalid ast' do
|
35
|
+
subject.should_not be_match([:identifier, 12])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "literal" do
|
40
|
+
subject{ Grammar[:literal] }
|
41
|
+
|
42
|
+
it 'matches valid ASTs' do
|
43
|
+
subject.should be_match([:literal, 12])
|
44
|
+
subject.should be_match([:literal, true])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "in" do
|
49
|
+
subject{ Grammar[:in] }
|
50
|
+
|
51
|
+
it 'matches valid ASTs' do
|
52
|
+
subject.should be_match([:in, [:identifier, :x], [2, 3]])
|
53
|
+
end
|
54
|
+
it 'does not match invalid ASTs' do
|
55
|
+
subject.should_not be_match([:in, :x])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "eq" do
|
60
|
+
subject{ Grammar[:eq] }
|
61
|
+
|
62
|
+
it 'matches valid ASTs' do
|
63
|
+
subject.should be_match([:eq, [:identifier, :age], [:literal, 12]])
|
64
|
+
end
|
65
|
+
it 'does not match invalid ASTs' do
|
66
|
+
subject.should_not be_match([:neq, [:identifier, :age], [:literal, 12]])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "neq" do
|
71
|
+
subject{ Grammar[:neq] }
|
72
|
+
|
73
|
+
it 'matches valid ASTs' do
|
74
|
+
subject.should be_match([:neq, [:identifier, :age], [:literal, 12]])
|
75
|
+
end
|
76
|
+
it 'does not match invalid ASTs' do
|
77
|
+
subject.should_not be_match([:eq, [:identifier, :age], [:literal, 12]])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "native" do
|
82
|
+
subject{ Grammar[:native] }
|
83
|
+
|
84
|
+
it 'matches valid ASTs' do
|
85
|
+
subject.should be_match([:native, lambda{}])
|
86
|
+
end
|
87
|
+
it 'does not match invalid ASTs' do
|
88
|
+
subject.should_not be_match([:native, 12])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe Grammar, "sexpr" do
|
4
|
+
|
5
|
+
subject{ Grammar.sexpr(expr) }
|
6
|
+
|
7
|
+
let(:contradiction){
|
8
|
+
[:contradiction, false]
|
9
|
+
}
|
10
|
+
let(:identifier){
|
11
|
+
[:identifier, :name]
|
12
|
+
}
|
13
|
+
|
14
|
+
before do
|
15
|
+
subject.should be_a(Sexpr)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "tautology" do
|
19
|
+
let(:expr){ [:tautology, true] }
|
20
|
+
|
21
|
+
it{ should be_a(Tautology) }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "contradiction" do
|
25
|
+
let(:expr){ [:contradiction, false] }
|
26
|
+
|
27
|
+
it{ should be_a(Contradiction) }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "identifier" do
|
31
|
+
let(:expr){ [:identifier, :name] }
|
32
|
+
|
33
|
+
it{ should be_a(Identifier) }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "and" do
|
37
|
+
let(:expr){ [:and, contradiction, contradiction] }
|
38
|
+
|
39
|
+
it{ should be_a(And) }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "or" do
|
43
|
+
let(:expr){ [:or, contradiction, contradiction] }
|
44
|
+
|
45
|
+
it{ should be_a(Or) }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "not" do
|
49
|
+
let(:expr){ [:not, contradiction] }
|
50
|
+
|
51
|
+
it{ should be_a(Not) }
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "eq" do
|
55
|
+
let(:expr){ [:eq, identifier, identifier] }
|
56
|
+
|
57
|
+
it{ should be_a(Eq) }
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "neq" do
|
61
|
+
let(:expr){ [:neq, identifier, identifier] }
|
62
|
+
|
63
|
+
it{ should be_a(Neq) }
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "gt" do
|
67
|
+
let(:expr){ [:gt, identifier, identifier] }
|
68
|
+
|
69
|
+
it{ should be_a(Gt) }
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "gte" do
|
73
|
+
let(:expr){ [:gte, identifier, identifier] }
|
74
|
+
|
75
|
+
it{ should be_a(Gte) }
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "lt" do
|
79
|
+
let(:expr){ [:lt, identifier, identifier] }
|
80
|
+
|
81
|
+
it{ should be_a(Lt) }
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "lte" do
|
85
|
+
let(:expr){ [:lte, identifier, identifier] }
|
86
|
+
|
87
|
+
it{ should be_a(Lte) }
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "literal" do
|
91
|
+
let(:expr){ [:literal, 12] }
|
92
|
+
|
93
|
+
it{ should be_a(Literal) }
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "native" do
|
97
|
+
let(:expr){ [:native, lambda{}] }
|
98
|
+
|
99
|
+
it{ should be_a(Native) }
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe And, "and_split" do
|
4
|
+
|
5
|
+
let(:tautology){ Factory.tautology }
|
6
|
+
|
7
|
+
subject{ predicate.and_split(list) }
|
8
|
+
|
9
|
+
context 'when attributes on one side' do
|
10
|
+
let(:predicate){ Factory.eq(:x, 2) & Factory.eq(:y, 3) }
|
11
|
+
|
12
|
+
context 'when fully covered' do
|
13
|
+
let(:list){ [:x, :y] }
|
14
|
+
|
15
|
+
it{ should eq([predicate, tautology]) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when not covered at all' do
|
19
|
+
let(:list){ [:name] }
|
20
|
+
|
21
|
+
it{ should eq([tautology, predicate]) }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when partially covered' do
|
25
|
+
let(:list){ [:x] }
|
26
|
+
|
27
|
+
it{ should eq([Factory.eq(:x, 2), Factory.eq(:y, 3)]) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when attributes on both sides' do
|
32
|
+
let(:predicate){ Factory.eq(:x, 2) & Factory.eq(:y, :z) }
|
33
|
+
|
34
|
+
context 'when fully covered' do
|
35
|
+
let(:list){ [:x, :y, :z] }
|
36
|
+
|
37
|
+
it{ should eq([predicate, tautology]) }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when not covered at all' do
|
41
|
+
let(:list){ [:name] }
|
42
|
+
|
43
|
+
it{ should eq([tautology, predicate]) }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when partially covered but split-able' do
|
47
|
+
let(:list){ [:x] }
|
48
|
+
|
49
|
+
it{ should eq([Factory.eq(:x, 2), Factory.eq(:y, :z)]) }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when partially covered but split-able (2)' do
|
53
|
+
let(:list){ [:y] }
|
54
|
+
|
55
|
+
it{ should eq([Factory.eq(:y, :z), Factory.eq(:x, 2)]) }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when partially covered but not split-able' do
|
59
|
+
let(:list){ [:x, :y] }
|
60
|
+
|
61
|
+
it{ should eq([predicate, tautology]) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe DyadicComp, "and_split" do
|
4
|
+
|
5
|
+
let(:predicate){ Factory.eq(:id, 2) }
|
6
|
+
let(:tautology){ Factory.tautology }
|
7
|
+
|
8
|
+
subject{ predicate.and_split(list) }
|
9
|
+
|
10
|
+
context 'when included' do
|
11
|
+
let(:list){ [:id, :name] }
|
12
|
+
|
13
|
+
it{ should eq([predicate, tautology]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when not include' do
|
17
|
+
let(:list){ [:name] }
|
18
|
+
|
19
|
+
it{ should eq([tautology, predicate]) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with attributes on both sides' do
|
23
|
+
let(:predicate){ Factory.eq(:x, :y) }
|
24
|
+
|
25
|
+
context 'when full at left' do
|
26
|
+
let(:list){ [:x, :y] }
|
27
|
+
|
28
|
+
it{ should eq([predicate, tautology]) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'none at left' do
|
32
|
+
let(:list){ [] }
|
33
|
+
|
34
|
+
it{ should eq([tautology, predicate]) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'mix' do
|
38
|
+
let(:list){ [:y] }
|
39
|
+
|
40
|
+
it{ should eq([predicate, tautology]) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe Identifier, "and_split" do
|
4
|
+
|
5
|
+
let(:predicate){ Factory.identifier(:id) }
|
6
|
+
let(:tautology){ Factory.tautology }
|
7
|
+
|
8
|
+
subject{ predicate.and_split(list) }
|
9
|
+
|
10
|
+
context 'when included' do
|
11
|
+
let(:list){ [:id, :name] }
|
12
|
+
|
13
|
+
it{ should eq([predicate, tautology]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when not include' do
|
17
|
+
let(:list){ [:name] }
|
18
|
+
|
19
|
+
it{ should eq([tautology, predicate]) }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe NadicBool, "free_variables" do
|
4
|
+
|
5
|
+
subject{ expr.free_variables }
|
6
|
+
|
7
|
+
context "on a complex attribute comparison" do
|
8
|
+
let(:expr){ Factory.comp(:neq, :x => :y, :z => 2) }
|
9
|
+
|
10
|
+
it{ should eq([:x, :y, :z]) }
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe QualifiedIdentifier, "and_split" do
|
4
|
+
|
5
|
+
let(:predicate){ Factory.qualified_identifier(:t, :id) }
|
6
|
+
let(:tautology){ Factory.tautology }
|
7
|
+
|
8
|
+
subject{ predicate.and_split(list) }
|
9
|
+
|
10
|
+
context 'when included' do
|
11
|
+
let(:list){ [:id, :name] }
|
12
|
+
|
13
|
+
it{ should eq([predicate, tautology]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when not include' do
|
17
|
+
let(:list){ [:name] }
|
18
|
+
|
19
|
+
it{ should eq([tautology, predicate]) }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe Predicate, "and_split" do
|
4
|
+
|
5
|
+
let(:p){ Predicate }
|
6
|
+
subject{ pred.and_split([:x]) }
|
7
|
+
|
8
|
+
context "on tautology" do
|
9
|
+
let(:pred){ p.tautology }
|
10
|
+
|
11
|
+
it{ should eq([p.tautology, p.tautology]) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "on contradiction" do
|
15
|
+
let(:pred){ p.contradiction }
|
16
|
+
|
17
|
+
it{ should eq([p.tautology, pred]) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "on identifier (included)" do
|
21
|
+
let(:pred){ p.identifier(:x) }
|
22
|
+
|
23
|
+
it{ should eq([ pred, p.tautology ]) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "on identifier (excluded)" do
|
27
|
+
let(:pred){ p.identifier(:y) }
|
28
|
+
|
29
|
+
it{ should eq([ p.tautology, pred ]) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "on not (included)" do
|
33
|
+
let(:pred){ p.not(:x) }
|
34
|
+
|
35
|
+
it{ should eq([ pred, p.tautology ]) }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "on not (excluded)" do
|
39
|
+
let(:pred){ p.not(:y) }
|
40
|
+
|
41
|
+
it{ should eq([ p.tautology, pred ]) }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "on eq (included)" do
|
45
|
+
let(:pred){ p.eq(:x, 2) }
|
46
|
+
|
47
|
+
it{ should eq([ pred, p.tautology ]) }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "on eq (excluded)" do
|
51
|
+
let(:pred){ p.eq(:y, 2) }
|
52
|
+
|
53
|
+
it{ should eq([ p.tautology, pred ]) }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe Predicate, "&" do
|
4
|
+
|
5
|
+
let(:left) { Predicate.coerce(x: 2) }
|
6
|
+
|
7
|
+
subject{ left & right }
|
8
|
+
|
9
|
+
before do
|
10
|
+
subject.should be_a(Predicate)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'with itself' do
|
14
|
+
let(:right){ left }
|
15
|
+
|
16
|
+
it{ should be(left) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with the same expression' do
|
20
|
+
let(:right){ Predicate.coerce(x: 2) }
|
21
|
+
|
22
|
+
it{ should be(left) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with another predicate' do
|
26
|
+
let(:right){ Predicate.coerce(y: 3) }
|
27
|
+
|
28
|
+
it 'should be a expected' do
|
29
|
+
subject.to_ruby_code.should eq("->(t){ (t[:x] == 2) && (t[:y] == 3) }")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class Predicate
|
3
|
+
describe Predicate, "!" do
|
4
|
+
|
5
|
+
subject{ !pred }
|
6
|
+
|
7
|
+
context "on tautology" do
|
8
|
+
let(:pred){ Predicate.tautology }
|
9
|
+
|
10
|
+
it{ should eq(Predicate.contradiction) }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "on contradiction" do
|
14
|
+
let(:pred){ Predicate.contradiction }
|
15
|
+
|
16
|
+
it{ should eq(Predicate.tautology) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "on not" do
|
20
|
+
let(:pred){ Predicate.not(:x) }
|
21
|
+
|
22
|
+
it{ should eq(Predicate.identifier(:x)) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "on comp" do
|
26
|
+
let(:pred){ Predicate.comp(:eq, :x => 2) }
|
27
|
+
|
28
|
+
it{ should eq(Predicate.comp(:neq, :x => 2)) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context "on eq" do
|
32
|
+
let(:pred){ Predicate.eq(:x => 2) }
|
33
|
+
|
34
|
+
it{ should eq(Predicate.neq(:x => 2)) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context "on neq" do
|
38
|
+
let(:pred){ Predicate.neq(:x => 2) }
|
39
|
+
|
40
|
+
it{ should eq(Predicate.eq(:x => 2)) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "on lt" do
|
44
|
+
let(:pred){ Predicate.lt(:x => 2) }
|
45
|
+
|
46
|
+
it{ should eq(Predicate.gte(:x => 2)) }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "on lte" do
|
50
|
+
let(:pred){ Predicate.lte(:x => 2) }
|
51
|
+
|
52
|
+
it{ should eq(Predicate.gt(:x => 2)) }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "on gt" do
|
56
|
+
let(:pred){ Predicate.gt(:x => 2) }
|
57
|
+
|
58
|
+
it{ should eq(Predicate.lte(:x => 2)) }
|
59
|
+
end
|
60
|
+
|
61
|
+
context "on gte" do
|
62
|
+
let(:pred){ Predicate.gte(:x => 2) }
|
63
|
+
|
64
|
+
it{ should eq(Predicate.lt(:x => 2)) }
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|