rudelo 0.1.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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +9 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +1 -0
- data/SET_LOGIC_MATCHER.md +100 -0
- data/lib/rudelo/matchers/set_logic.rb +68 -0
- data/lib/rudelo/parsers/set_logic_parser.rb +88 -0
- data/lib/rudelo/parsers/set_logic_transform.rb +160 -0
- data/lib/rudelo/parsers/set_value_parser.rb +68 -0
- data/lib/rudelo/parsers/set_value_transform.rb +10 -0
- data/lib/rudelo/version.rb +3 -0
- data/lib/rudelo.rb +6 -0
- data/rudelo.gemspec +26 -0
- data/spec/matchers/set_logic_spec.rb +59 -0
- data/spec/parsers/set_logic_parser_spec.rb +147 -0
- data/spec/parsers/set_logic_transform_spec.rb +269 -0
- data/spec/parsers/set_value_parser_spec.rb +89 -0
- data/spec/parsers/set_value_transform_spec.rb +21 -0
- data/spec/spec_helper.rb +17 -0
- metadata +160 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
require 'rudelo'
|
4
|
+
require 'rufus-decision'
|
5
|
+
describe "Rudelo::Matchers::SetLogic" do
|
6
|
+
subject{Rudelo::Matchers::SetLogic.new}
|
7
|
+
|
8
|
+
it "matches multiple values against multiple cells correctly" do
|
9
|
+
cell1 = "$in same-as $(a b c)"
|
10
|
+
cell2 = "$in same-as $(k f r)"
|
11
|
+
expect(subject.matches?(cell1, 'a b c')).to be_true
|
12
|
+
expect(subject.matches?(cell2, 'a b c')).to be_false
|
13
|
+
expect(subject.matches?(cell1, 'k f r')).to be_false
|
14
|
+
expect(subject.matches?(cell2, 'k f r')).to be_true
|
15
|
+
expect(subject.matches?(cell1, 'a b c')).to be_true
|
16
|
+
expect(subject.matches?(cell2, 'a b c')).to be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
context "rufus-decision" do
|
20
|
+
let(:table){
|
21
|
+
table = Rufus::Decision::Table.new(%{
|
22
|
+
in:group, out:situation
|
23
|
+
$(bob jeff mary alice ralph) & $in #= 2, company
|
24
|
+
$(bob jeff mary alice ralph) & $in same-as $in #= 3, crowd
|
25
|
+
$(bob jeff mary alice ralph) >= $in #> 3, exclusive-party
|
26
|
+
$(bob jeff mary alice ralph) & $in < $in #> 5, PARTY!
|
27
|
+
$(bob jeff mary alice ralph) & $in < $in #> 3, party
|
28
|
+
})
|
29
|
+
table.matchers.unshift Rudelo::Matchers::SetLogic.new
|
30
|
+
table
|
31
|
+
}
|
32
|
+
it "transforms values" do
|
33
|
+
expect(
|
34
|
+
table.transform({'group' => "bob alice"})
|
35
|
+
).to eq({'group' => "bob alice", 'situation' => "company"})
|
36
|
+
|
37
|
+
expect(
|
38
|
+
table.transform({'group' => "bob alice jeff"})
|
39
|
+
).to eq({'group' => "bob alice jeff", 'situation' => "crowd"})
|
40
|
+
|
41
|
+
expect(
|
42
|
+
table.transform({'group' => "bob alice jeff ralph"})
|
43
|
+
).to eq({'group' => "bob alice jeff ralph", 'situation' => "exclusive-party"})
|
44
|
+
|
45
|
+
expect(
|
46
|
+
table.transform({'group' => "bob alice jeff don"})
|
47
|
+
).to eq({'group' => "bob alice jeff don", 'situation' => "party"})
|
48
|
+
|
49
|
+
expect(
|
50
|
+
table.transform({'group' => "bob alice jeff mary ralph don"})
|
51
|
+
).to eq({'group' => "bob alice jeff mary ralph don", 'situation' => "PARTY!"})
|
52
|
+
|
53
|
+
expect(
|
54
|
+
table.transform({'group' => "bob alice jeff mary don bev"})
|
55
|
+
).to eq({'group' => "bob alice jeff mary don bev", 'situation' => "PARTY!"})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
require 'rudelo/parsers/set_logic_parser'
|
5
|
+
|
6
|
+
describe "Rudelo::Parsers::SetLogicParser" do
|
7
|
+
let(:parser) { Rudelo::Parsers::SetLogicParser.new }
|
8
|
+
|
9
|
+
context "cardinality_expression" do
|
10
|
+
let(:expr_parser){ parser.cardinality_expression }
|
11
|
+
|
12
|
+
it "parses cardinality (symbols)" do
|
13
|
+
expect(expr_parser).to parse('#= 5', trace: true).as({
|
14
|
+
:cardinality_expression=>{ :op=>'#=', :qty=>"5"}
|
15
|
+
})
|
16
|
+
expect(expr_parser).to parse('#> 5', trace: true)
|
17
|
+
expect(expr_parser).to parse('#< 4', trace: true)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "parses cardinality (words)" do
|
21
|
+
expect(expr_parser).to parse('cardinality-equals 5', trace: true).as({
|
22
|
+
:cardinality_expression=>{ :op=>'cardinality-equals', :qty=>"5"}
|
23
|
+
})
|
24
|
+
expect(expr_parser).to parse('cardinality-greater-than 5', trace: true)
|
25
|
+
expect(expr_parser).to parse('cardinality-less-than 4', trace: true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "set construction expression" do
|
30
|
+
let(:expr_parser){ parser.set_construction_expression }
|
31
|
+
|
32
|
+
it "parses set construction to an iterative operation list" do
|
33
|
+
|
34
|
+
expect(expr_parser).to parse('$(bob mary) union $(ralph jeff) & $in', trace: true).as({
|
35
|
+
:set_construction_expression=>{
|
36
|
+
:left=>{:element_list=>[{:element=>"bob"}, {:element=>"mary"}] },
|
37
|
+
:right=>[
|
38
|
+
{ set_op: {
|
39
|
+
left: {op: "union"},
|
40
|
+
right: {element_list:[
|
41
|
+
{:element=>"ralph"}, {:element=>"jeff"}
|
42
|
+
]}
|
43
|
+
}},
|
44
|
+
{ set_op: {
|
45
|
+
left: {op: "&"},
|
46
|
+
right: {:in_set=>"$in"}}}
|
47
|
+
]
|
48
|
+
}
|
49
|
+
})
|
50
|
+
end
|
51
|
+
it "parses set construction ops in symbol form" do
|
52
|
+
expect(expr_parser).to parse('$(bob mary) & $in', trace: true)
|
53
|
+
expect(expr_parser).to parse('$(bob mary) + $in', trace: true)
|
54
|
+
expect(expr_parser).to parse('$(bob mary)-$in', trace: true)
|
55
|
+
expect(expr_parser).to parse('$(bob mary) ^ $in', trace: true)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "parses set construction ops in word form" do
|
59
|
+
expect(expr_parser).to parse('$in intersection $(bob mary)', trace: true)
|
60
|
+
expect(expr_parser).to parse('$in union $(bob mary)', trace: true)
|
61
|
+
expect(expr_parser).to parse('$in difference $(bob mary)', trace: true)
|
62
|
+
expect(expr_parser).to parse('$in exclusive $(bob mary)', trace: true)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context "set logic expression" do
|
68
|
+
let(:expr_parser){ parser.set_logic_expression }
|
69
|
+
|
70
|
+
it "parses set logic to a left-right tree" do
|
71
|
+
expect(expr_parser).to parse('$(bob mary) < $(ralph jeff bob mary)', trace: true).as({
|
72
|
+
:set_logic_expression=>{
|
73
|
+
:left=>{:element_list=>[
|
74
|
+
{:element=>"bob"}, {:element=>"mary"}] },
|
75
|
+
:op => "<",
|
76
|
+
:right=>{:element_list=>[
|
77
|
+
{:element=>"ralph"}, {:element=>"jeff"}, {:element=>"bob"}, {:element=>"mary"}]}
|
78
|
+
}
|
79
|
+
})
|
80
|
+
end
|
81
|
+
|
82
|
+
it "parses the left hand side as a set construction expression" do
|
83
|
+
expect(expr_parser).to parse('$(bob mary) union $in < $(ralph jeff bob mary)', trace: true).as({
|
84
|
+
:set_logic_expression=>{
|
85
|
+
:left=> {
|
86
|
+
:set_construction_expression=>{
|
87
|
+
:left=>{
|
88
|
+
:element_list=>[{:element=>"bob"}, {:element=>"mary"}]
|
89
|
+
},
|
90
|
+
:right=>[{set_op: { left: {:op=>"union"}, right: {:in_set=>"$in"}}}]
|
91
|
+
}
|
92
|
+
},
|
93
|
+
:op => "<",
|
94
|
+
:right=>{:element_list=>[
|
95
|
+
{:element=>"ralph"}, {:element=>"jeff"}, {:element=>"bob"}, {:element=>"mary"}]}
|
96
|
+
}
|
97
|
+
})
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses set logic ops in symbol form" do
|
101
|
+
expect(expr_parser).to parse('$(bob mary) < $in', trace: true)
|
102
|
+
expect(expr_parser).to parse('$(bob mary) <= $in', trace: true)
|
103
|
+
expect(expr_parser).to parse('$(bob mary)>$in', trace: true)
|
104
|
+
expect(expr_parser).to parse('$(bob mary) >= $in', trace: true)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "parses set logic ops in word form" do
|
108
|
+
expect(expr_parser).to parse('$in superset $(bob mary)', trace: true)
|
109
|
+
expect(expr_parser).to parse('$in subset $(bob mary)', trace: true)
|
110
|
+
expect(expr_parser).to parse('$in proper-superset $(bob mary)', trace: true)
|
111
|
+
expect(expr_parser).to parse('$in proper-subset $(bob mary)', trace: true)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
context "set logic expression" do
|
117
|
+
let(:expr_parser){ parser.match_expression }
|
118
|
+
it "parses a bare cardinality expression" do
|
119
|
+
expect(expr_parser).to parse('#= 5', trace: true).as({
|
120
|
+
match_expression: {
|
121
|
+
right: {
|
122
|
+
cardinality_expression: {op: "#=", qty: "5"}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
})
|
126
|
+
end
|
127
|
+
|
128
|
+
it "parses an explicit set expression" do
|
129
|
+
expect(expr_parser).to parse('$(bob, jeff)', trace: true).as({
|
130
|
+
superset_match_expression: {
|
131
|
+
element_list: [{element: "bob"}, {element: "jeff"}]
|
132
|
+
}
|
133
|
+
})
|
134
|
+
end
|
135
|
+
|
136
|
+
it "parses a set construction expression with optional cardinality" do
|
137
|
+
expect(expr_parser).to parse('$(bob, jeff) + $in', trace: true)
|
138
|
+
expect(expr_parser).to parse('$(bob, jeff) + $in #> 3', trace: true)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "parses a set logic expression with optional cardinality" do
|
142
|
+
expect(expr_parser).to parse('$(bob, jeff) <= $in', trace: true)
|
143
|
+
expect(expr_parser).to parse('$(bob, jeff) <= $in #> 3', trace: true)
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
require 'rudelo/parsers/set_logic_parser'
|
4
|
+
require 'rudelo/parsers/set_logic_transform'
|
5
|
+
|
6
|
+
describe "Rudelo::Parsers::SetLogicTransform" do
|
7
|
+
let(:parser) { Rudelo::Parsers::SetLogicParser.new }
|
8
|
+
let(:in_set){ Set.new(%w{a b c}) }
|
9
|
+
let(:xform) { Rudelo::Parsers::SetLogicTransform.new(in_set) }
|
10
|
+
let(:empty_set) { Set.new }
|
11
|
+
|
12
|
+
context "ops" do
|
13
|
+
specify{expect(xform.apply(:op => "+")).to eq(:"+")}
|
14
|
+
specify{expect(xform.apply(:op => "#=")).to eq(:"==")}
|
15
|
+
specify{expect(xform.apply(:op => "cardinality-equals")).to eq(:"==")}
|
16
|
+
specify{expect(xform.apply(:op => "#>")).to eq(:>)}
|
17
|
+
specify{expect(xform.apply(:op => "cardinality-greater-than")).to eq(:>)}
|
18
|
+
specify{expect(xform.apply(:op => "proper-superset")).to eq(:proper_superset?)}
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
context "CardinalityExpr" do
|
23
|
+
subject{ Rudelo::Parsers::SetLogicTransform::CardinalityExpr }
|
24
|
+
let(:set){ Set.new(%w{a b c}) }
|
25
|
+
specify{ expect(subject.new(:>, 2).eval(set)).to be_true }
|
26
|
+
specify{ expect(subject.new(:<, 2).eval(set)).to be_false }
|
27
|
+
specify{ expect(subject.new(:==, 2).eval(set)).to be_false }
|
28
|
+
specify{ expect(subject.new(:==, 3).eval(set)).to be_true }
|
29
|
+
end
|
30
|
+
|
31
|
+
context "SetLogicExpr" do
|
32
|
+
subject{ Rudelo::Parsers::SetLogicTransform::SetLogicExpr }
|
33
|
+
let(:set1){ Set.new(%w{a b c}) }
|
34
|
+
let(:set2){ Set.new(%w{b c}) }
|
35
|
+
let(:set3){ Set.new(%w{b c d}) }
|
36
|
+
specify{ expect(
|
37
|
+
subject.new(set1, :proper_superset?, set2).eval
|
38
|
+
).to be_true }
|
39
|
+
specify{ expect(subject.new(set1, :proper_subset?, set2).eval).to be_false }
|
40
|
+
specify{ expect(subject.new(set3, :proper_subset?, set1).eval).to be_false }
|
41
|
+
specify{ expect(subject.new(set1, :==, set1).eval).to be_true }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "SetOp" do
|
45
|
+
subject{ Rudelo::Parsers::SetLogicTransform::SetOp }
|
46
|
+
let(:set1){ Set.new(%w{a b c}) }
|
47
|
+
let(:set2){ Set.new(%w{b c}) }
|
48
|
+
let(:set3){ Set.new(%w{b c d}) }
|
49
|
+
let(:set4){ Set.new(%w{a b c d}) }
|
50
|
+
let(:set5){ Set.new(%w{a}) }
|
51
|
+
specify{ expect(
|
52
|
+
subject.new(:+, set1).eval(set3)
|
53
|
+
).to eq(set4) }
|
54
|
+
specify{ expect(
|
55
|
+
subject.new(:-, set3).eval(set4)
|
56
|
+
).to eq(set5) }
|
57
|
+
specify{ expect(
|
58
|
+
subject.new(:-, set4).eval(set3)
|
59
|
+
).to eq(empty_set) }
|
60
|
+
end
|
61
|
+
|
62
|
+
context "SetOp" do
|
63
|
+
subject{ Rudelo::Parsers::SetLogicTransform::EmptyExpr.new }
|
64
|
+
specify{ expect(subject.eval).to be_true }
|
65
|
+
specify{ expect(subject.eval(false)).to be_true }
|
66
|
+
end
|
67
|
+
|
68
|
+
context "Set#eval" do
|
69
|
+
let(:set1){ Set.new(%w{a b c}) }
|
70
|
+
specify{ expect(empty_set.eval).to eq(empty_set) }
|
71
|
+
specify{ expect(set1.eval).to eq(set1) }
|
72
|
+
end
|
73
|
+
|
74
|
+
context "MatchExpr" do
|
75
|
+
subject{ Rudelo::Parsers::SetLogicTransform::MatchExpr }
|
76
|
+
before do
|
77
|
+
@scon_full = mock('SetConstructionExpr')
|
78
|
+
@scon_full.stub(:eval).and_return(Set.new['a'])
|
79
|
+
@scon_empty = mock('SetConstructionExpr')
|
80
|
+
@scon_empty.stub(:eval).and_return(Set.new)
|
81
|
+
|
82
|
+
@slog_true = mock('SetLogicExpr')
|
83
|
+
@slog_true.stub(:eval).and_return(true)
|
84
|
+
@slog_true.stub(:set).and_return(Set.new['a'])
|
85
|
+
|
86
|
+
@slog_false = mock('SetLogicExpr')
|
87
|
+
@slog_false.stub(:eval).and_return(false)
|
88
|
+
@slog_false.stub(:set).and_return(Set.new)
|
89
|
+
|
90
|
+
@scar_one = CardinalityExpr.new(:==, 1)
|
91
|
+
@scar_two = CardinalityExpr.new(:==, 2)
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when right is empty" do
|
95
|
+
context "when left is SetConstructionExpr" do
|
96
|
+
it "returns true if the result size is > 0"
|
97
|
+
it "returns false if the result size is < 1"
|
98
|
+
end
|
99
|
+
context "when left is SetLogicExpr" do
|
100
|
+
it "returns true if the result is true"
|
101
|
+
it "returns true if the result is false"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
context "when right is CardinalityExpr" do
|
105
|
+
context "when left is SetConstructionExpr" do
|
106
|
+
it "runs cardinality expression on left result"
|
107
|
+
end
|
108
|
+
context "when left is SetLogicExpr" do
|
109
|
+
it "runs cardinality expression on left set"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
context "match expressions" do
|
116
|
+
subject{ xform.apply(parser.parse(expr)) }
|
117
|
+
context "cardinality expressions alone" do
|
118
|
+
let(:set){ Set.new(%w{a b c}) }
|
119
|
+
let(:expr){ "#> 2" }
|
120
|
+
it "should transform cardinality_expressions as match_expression.right" do
|
121
|
+
expect(subject.right).to be_a_kind_of(
|
122
|
+
Rudelo::Parsers::SetLogicTransform::CardinalityExpr)
|
123
|
+
end
|
124
|
+
it "should set match_expression.left to in_set" do
|
125
|
+
expect(subject.left).to eq(in_set)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should eval correctly" do
|
129
|
+
expect(subject.right.eval(set)
|
130
|
+
).to be_true
|
131
|
+
expect(subject.eval).to be_true
|
132
|
+
|
133
|
+
expect(
|
134
|
+
xform.apply(
|
135
|
+
parser.parse("#< 2")
|
136
|
+
).right.eval(set)
|
137
|
+
).to be_false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "logic expression" do
|
142
|
+
context "alone" do
|
143
|
+
let(:expr){ "$(k z v) > $in" }
|
144
|
+
it "transforms logic expression as match_expression.left" do
|
145
|
+
expect(subject.left).to be_a_kind_of(
|
146
|
+
Rudelo::Parsers::SetLogicTransform::SetLogicExpr)
|
147
|
+
end
|
148
|
+
it "should set match_expression.right to nil" do
|
149
|
+
expect(subject.right).to be_a_kind_of(
|
150
|
+
Rudelo::Parsers::SetLogicTransform::EmptyExpr)
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
context "with cardinality" do
|
155
|
+
let(:expr){ "$(k z v) > $in #= 2" }
|
156
|
+
it "transforms logic expression as match_expression.left" do
|
157
|
+
expect(subject.left).to be_a_kind_of(
|
158
|
+
Rudelo::Parsers::SetLogicTransform::SetLogicExpr)
|
159
|
+
end
|
160
|
+
it "should set match_expression.right to nil" do
|
161
|
+
expect(subject.right).to be_a_kind_of(
|
162
|
+
Rudelo::Parsers::SetLogicTransform::CardinalityExpr)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "construction expression" do
|
168
|
+
context "alone" do
|
169
|
+
let(:expr){ "$(k z v) + $in" }
|
170
|
+
it "transforms construction expression as match_expression.left" do
|
171
|
+
expect(subject.left).to be_a_kind_of(
|
172
|
+
Rudelo::Parsers::SetLogicTransform::SetConstructionExpr)
|
173
|
+
end
|
174
|
+
it "should set match_expression.right to nil expr" do
|
175
|
+
expect(subject.right).to be_a_kind_of(
|
176
|
+
Rudelo::Parsers::SetLogicTransform::EmptyExpr)
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
context "with cardinality" do
|
181
|
+
let(:expr){ "$(k z v) + $in #= 2" }
|
182
|
+
it "transforms construction expression as match_expression.left" do
|
183
|
+
expect(subject.left).to be_a_kind_of(
|
184
|
+
Rudelo::Parsers::SetLogicTransform::SetConstructionExpr)
|
185
|
+
end
|
186
|
+
it "should set match_expression.right to nil" do
|
187
|
+
expect(subject.right).to be_a_kind_of(
|
188
|
+
Rudelo::Parsers::SetLogicTransform::CardinalityExpr)
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def matching(expr, opts)
|
196
|
+
in_set = Set.new(opts[:in_set])
|
197
|
+
Rudelo::Parsers::SetLogicTransform.new(in_set).apply(
|
198
|
+
Rudelo::Parsers::SetLogicParser.new.parse(expr)
|
199
|
+
).eval
|
200
|
+
end
|
201
|
+
|
202
|
+
context "cardinality examples" do
|
203
|
+
specify{ expect(matching(
|
204
|
+
'#= 2', in_set: %w{a b})).to be_true }
|
205
|
+
specify{ expect(matching(
|
206
|
+
'#< 3', in_set: %w{a b})).to be_true }
|
207
|
+
specify{ expect(matching(
|
208
|
+
'#> 1', in_set: %w{a b})).to be_true }
|
209
|
+
specify{ expect(matching(
|
210
|
+
'#= 3', in_set: %w{a b})).to be_false }
|
211
|
+
specify{ expect(matching(
|
212
|
+
'#> 3', in_set: %w{a b})).to be_false }
|
213
|
+
specify{ expect(matching(
|
214
|
+
'#< 1', in_set: %w{a b})).to be_false }
|
215
|
+
end
|
216
|
+
|
217
|
+
context "construction examples" do
|
218
|
+
specify{ expect(matching(
|
219
|
+
'$(a b c) & $in #= 2', in_set: %w{a b d})).to be_true }
|
220
|
+
specify{ expect(matching(
|
221
|
+
'$(a b c) & $in', in_set: %w{a b d})).to be_true }
|
222
|
+
specify{ expect(matching(
|
223
|
+
'$(a b c) & $in', in_set: %w{d e f})).to be_false }
|
224
|
+
specify{ expect(matching(
|
225
|
+
'$(a b c) & $in #= 2', in_set: %w{a k d})).to be_false }
|
226
|
+
specify{ expect(matching(
|
227
|
+
'$(a b c) + $in + $(e) #= 5', in_set: %w{b c d})).to be_true }
|
228
|
+
end
|
229
|
+
|
230
|
+
context "explicit set examples" do
|
231
|
+
specify{ expect(matching(
|
232
|
+
'$(a b c)', in_set: %w{a b})).to be_true }
|
233
|
+
specify{ expect(matching(
|
234
|
+
'$(a b c)', in_set: %w{a k d})).to be_false }
|
235
|
+
end
|
236
|
+
|
237
|
+
context "logic examples" do
|
238
|
+
specify{ expect(matching(
|
239
|
+
'$(a b c) > $in', in_set: %w{a b})).to be_true }
|
240
|
+
specify{ expect(matching(
|
241
|
+
'$(a b c) > $in #=2', in_set: %w{a b})).to be_true }
|
242
|
+
specify{ expect(matching(
|
243
|
+
'$(a b c) > $in #=1', in_set: %w{a})).to be_true }
|
244
|
+
specify{ expect(matching(
|
245
|
+
'$(a b c) ^ $in < $(a d k f)', in_set: %w{b c d})).to be_true }
|
246
|
+
specify{ expect(matching(
|
247
|
+
'$(a b c) ^ $in < $(a e k f)', in_set: %w{b c d})).to be_false }
|
248
|
+
end
|
249
|
+
|
250
|
+
context "using transform with multiple in-set values" do
|
251
|
+
it "allows re-using a transform" do
|
252
|
+
abc = Set.new(%w{a b c})
|
253
|
+
efg = Set.new(%w{e f g})
|
254
|
+
expr = '$in same-as $(a b c)'
|
255
|
+
|
256
|
+
transform = Rudelo::Parsers::SetLogicTransform.new(abc)
|
257
|
+
ast = transform.apply(parser.parse(expr))
|
258
|
+
|
259
|
+
expect(ast.eval).to be_true
|
260
|
+
|
261
|
+
expect(ast.eval(efg)).to be_false
|
262
|
+
|
263
|
+
expect(ast.eval(abc)).to be_true
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
require 'rudelo/parsers/set_value_parser'
|
4
|
+
|
5
|
+
describe "Rudelo::Parsers::SetValueParser" do
|
6
|
+
let(:parser) { Rudelo::Parsers::SetValueParser.new }
|
7
|
+
context "set parsing" do
|
8
|
+
it "parses bare sets" do
|
9
|
+
expect(parser).to parse(%Q{bob, mary}, trace: true).as({
|
10
|
+
element_list: [
|
11
|
+
{element: "bob"},
|
12
|
+
{element: "mary"}
|
13
|
+
]
|
14
|
+
})
|
15
|
+
expect(parser).to parse(%Q{bob}, trace: true).as({
|
16
|
+
element_list:
|
17
|
+
{element: "bob"}
|
18
|
+
|
19
|
+
})
|
20
|
+
|
21
|
+
expect(parser).to parse(%Q{bob, mary, jeff}, trace: true).as({
|
22
|
+
element_list: [
|
23
|
+
{element: "bob"},
|
24
|
+
{element: "mary"},
|
25
|
+
{element: "jeff"}
|
26
|
+
]
|
27
|
+
})
|
28
|
+
|
29
|
+
expect(parser).to parse(%Q{bob mary}, trace: true).as({
|
30
|
+
element_list: [
|
31
|
+
{element: "bob"},
|
32
|
+
{element: "mary"}
|
33
|
+
]
|
34
|
+
})
|
35
|
+
|
36
|
+
expect(parser).to parse(%Q{bob mary, ralph}, trace: true).as({
|
37
|
+
element_list: [
|
38
|
+
{element: "bob"},
|
39
|
+
{element: "mary"},
|
40
|
+
{element: "ralph"}
|
41
|
+
]
|
42
|
+
})
|
43
|
+
|
44
|
+
expect(parser).to parse(%Q{"bob mary", ralph}, trace: true).as({
|
45
|
+
element_list: [
|
46
|
+
{element: "bob mary"},
|
47
|
+
{element: "ralph"}
|
48
|
+
]
|
49
|
+
})
|
50
|
+
|
51
|
+
expect(parser).to parse(%Q{"bob, mary", ralph}, trace: true).as({
|
52
|
+
element_list: [
|
53
|
+
{element: "bob, mary"},
|
54
|
+
{element: "ralph"}
|
55
|
+
]
|
56
|
+
})
|
57
|
+
end
|
58
|
+
|
59
|
+
it "parses explicit sets" do
|
60
|
+
expect(parser).to parse(%Q{$(bob, mary)}, trace: true).as({
|
61
|
+
element_list: [
|
62
|
+
{element: "bob"},
|
63
|
+
{element: "mary"}
|
64
|
+
]
|
65
|
+
})
|
66
|
+
expect(parser).to parse(%Q{$("bob", mary)}, trace: true).as({
|
67
|
+
element_list: [
|
68
|
+
{element: "bob"},
|
69
|
+
{element: "mary"}
|
70
|
+
]
|
71
|
+
})
|
72
|
+
expect(parser).to parse(%Q{$("bob)dad", mary)}, trace: true).as({
|
73
|
+
element_list: [
|
74
|
+
{element: "bob)dad"},
|
75
|
+
{element: "mary"}
|
76
|
+
]
|
77
|
+
})
|
78
|
+
expect(parser).to parse(%Q{$("bob", mary jeff)}, trace: true).as({
|
79
|
+
element_list: [
|
80
|
+
{element: "bob"},
|
81
|
+
{element: "mary"},
|
82
|
+
{element: "jeff"},
|
83
|
+
]
|
84
|
+
})
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
require 'rudelo/parsers/set_value_parser'
|
4
|
+
require 'rudelo/parsers/set_value_transform'
|
5
|
+
|
6
|
+
describe "Rudelo::Parsers::SetValueTransform" do
|
7
|
+
let(:parser) { Rudelo::Parsers::SetValueParser.new }
|
8
|
+
let(:xform) { Rudelo::Parsers::SetValueTransform.new }
|
9
|
+
|
10
|
+
it "transforms an element to a string" do
|
11
|
+
expect(xform.apply(:element => "bob")).to eq("bob")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "transforms a set to a Set" do
|
15
|
+
expect(xform.apply({:element_list=>[{:element=>"bob"}, {:element=>"mary"}]})).to eq(Set['mary', 'bob'])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "works on a single element" do
|
19
|
+
expect(xform.apply(parser.parse('bob'))).to eq(Set['bob'])
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require 'rudelo'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.expect_with :rspec do |c|
|
9
|
+
c.syntax = :expect
|
10
|
+
end
|
11
|
+
|
12
|
+
config.order = 'random'
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
require "parslet"
|
17
|
+
require "parslet/rig/rspec"
|