predicate 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|