smartdown 0.3.0 → 0.4.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/lib/smartdown/engine/conditional_resolver.rb +1 -9
- data/lib/smartdown/engine/interpolator.rb +12 -1
- data/lib/smartdown/engine/state.rb +1 -10
- data/lib/smartdown/engine/transition.rb +2 -6
- data/lib/smartdown/engine.rb +2 -3
- data/lib/smartdown/model/predicate/combined.rb +9 -1
- data/lib/smartdown/model/predicate/comparison/base.rb +4 -1
- data/lib/smartdown/model/predicate/comparison/greater.rb +6 -1
- data/lib/smartdown/model/predicate/comparison/greater_or_equal.rb +6 -1
- data/lib/smartdown/model/predicate/comparison/less.rb +6 -1
- data/lib/smartdown/model/predicate/comparison/less_or_equal.rb +6 -1
- data/lib/smartdown/model/predicate/equality.rb +9 -1
- data/lib/smartdown/model/predicate/function.rb +28 -0
- data/lib/smartdown/model/predicate/named.rb +9 -1
- data/lib/smartdown/model/predicate/otherwise.rb +15 -0
- data/lib/smartdown/model/predicate/set_membership.rb +9 -1
- data/lib/smartdown/parser/node_transform.rb +14 -0
- data/lib/smartdown/parser/predicates.rb +18 -1
- data/lib/smartdown/version.rb +1 -1
- data/spec/acceptance/parsing_spec.rb +8 -0
- data/spec/engine/interpolator_spec.rb +14 -0
- data/spec/engine/state_spec.rb +0 -37
- data/spec/engine/transition_spec.rb +23 -19
- data/spec/engine_spec.rb +8 -11
- data/spec/fixtures/acceptance/animal-example-simple/animal-example-simple.txt +25 -0
- data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_safe_pet.txt +69 -0
- data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_tigers_are_fine.txt +9 -0
- data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_trained_with_lions.txt +3 -0
- data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_untrained_with_lions.txt +3 -0
- data/spec/fixtures/acceptance/animal-example-simple/questions/question_1.txt +13 -0
- data/spec/fixtures/acceptance/animal-example-simple/questions/question_2.txt +10 -0
- data/spec/model/predicates/combined_spec.rb +47 -0
- data/spec/model/predicates/comparison_spec.rb +162 -0
- data/spec/model/predicates/equality_spec.rb +36 -0
- data/spec/model/predicates/function_spec.rb +85 -0
- data/spec/model/predicates/named_spec.rb +41 -0
- data/spec/model/predicates/set_membership_spec.rb +39 -0
- data/spec/parser/predicates_spec.rb +98 -16
- data/spec/support/model_builder.rb +4 -0
- metadata +39 -14
- data/lib/smartdown/engine/predicate_evaluator.rb +0 -27
- data/spec/engine/predicate_evaluator_spec.rb +0 -284
@@ -47,39 +47,56 @@ describe Smartdown::Parser::Predicates do
|
|
47
47
|
describe "named predicate" do
|
48
48
|
subject(:parser) { described_class.new }
|
49
49
|
|
50
|
-
it { should parse("my_pred").as(named_predicate: "my_pred") }
|
51
50
|
it { should parse("my_pred?").as(named_predicate: "my_pred?") }
|
51
|
+
it { should_not parse("my_pred") }
|
52
52
|
it { should_not parse("my pred") }
|
53
53
|
|
54
54
|
describe "transformed" do
|
55
55
|
let(:node_name) { "my_node" }
|
56
|
-
let(:source) { "my_pred" }
|
56
|
+
let(:source) { "my_pred?" }
|
57
57
|
subject(:transformed) {
|
58
58
|
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
59
59
|
}
|
60
60
|
|
61
|
-
it { should eq(Smartdown::Model::Predicate::Named.new("my_pred")) }
|
61
|
+
it { should eq(Smartdown::Model::Predicate::Named.new("my_pred?")) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "otherwise predicate" do
|
66
|
+
subject(:parser) { described_class.new }
|
67
|
+
|
68
|
+
it { should parse("otherwise").as(otherwise_predicate: "otherwise") }
|
69
|
+
it { should_not parse("other") }
|
70
|
+
|
71
|
+
describe "transformed" do
|
72
|
+
let(:node_name) { "my_node" }
|
73
|
+
let(:source) { "otherwise" }
|
74
|
+
subject(:transformed) {
|
75
|
+
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
76
|
+
}
|
77
|
+
|
78
|
+
it { should eq(Smartdown::Model::Predicate::Otherwise.new) }
|
62
79
|
end
|
63
80
|
end
|
64
81
|
|
65
82
|
describe "predicate AND predicate" do
|
66
83
|
subject(:parser) { described_class.new }
|
67
84
|
|
68
|
-
it { should parse("my_pred AND my_other_pred").as(
|
85
|
+
it { should parse("my_pred? AND my_other_pred?").as(
|
69
86
|
{ combined_predicate: {
|
70
|
-
first_predicate: { named_predicate: "my_pred" },
|
87
|
+
first_predicate: { named_predicate: "my_pred?" },
|
71
88
|
and_predicates:
|
72
89
|
[
|
73
|
-
{named_predicate: "my_other_pred"},
|
90
|
+
{named_predicate: "my_other_pred?"},
|
74
91
|
]
|
75
92
|
} }
|
76
93
|
) }
|
77
|
-
it { should parse("my_pred AND my_other_pred AND varname in {a b c}").as(
|
94
|
+
it { should parse("my_pred? AND my_other_pred? AND varname in {a b c}").as(
|
78
95
|
{ combined_predicate: {
|
79
|
-
first_predicate: { named_predicate: "my_pred" },
|
96
|
+
first_predicate: { named_predicate: "my_pred?" },
|
80
97
|
and_predicates:
|
81
98
|
[
|
82
|
-
{named_predicate: "my_other_pred"},
|
99
|
+
{named_predicate: "my_other_pred?"},
|
83
100
|
{set_membership_predicate:
|
84
101
|
{varname: "varname", values: [{set_value: "a"}, {set_value: "b"}, {set_value: "c"}]}
|
85
102
|
}
|
@@ -90,20 +107,85 @@ describe Smartdown::Parser::Predicates do
|
|
90
107
|
|
91
108
|
describe "transformed" do
|
92
109
|
let(:node_name) { "my_node" }
|
93
|
-
let(:source) { "my_pred AND my_other_pred" }
|
110
|
+
let(:source) { "my_pred? AND my_other_pred?" }
|
94
111
|
subject(:transformed) {
|
95
112
|
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
96
113
|
}
|
97
114
|
|
98
115
|
it { should eq(Smartdown::Model::Predicate::Combined.new(
|
99
116
|
[
|
100
|
-
Smartdown::Model::Predicate::Named.new("my_pred"),
|
101
|
-
Smartdown::Model::Predicate::Named.new("my_other_pred")
|
117
|
+
Smartdown::Model::Predicate::Named.new("my_pred?"),
|
118
|
+
Smartdown::Model::Predicate::Named.new("my_other_pred?")
|
102
119
|
]
|
103
120
|
)) }
|
104
121
|
end
|
105
122
|
end
|
106
123
|
|
124
|
+
describe "function predicate" do
|
125
|
+
subject(:parser) { described_class.new }
|
126
|
+
|
127
|
+
context "no arguments" do
|
128
|
+
let(:source) { "function_name()" }
|
129
|
+
|
130
|
+
it { should parse(source).as(function_predicate: { name: "function_name" }) }
|
131
|
+
it { should_not parse("function_name(") }
|
132
|
+
|
133
|
+
describe "transformed" do
|
134
|
+
let(:node_name) { "my_node" }
|
135
|
+
subject(:transformed) {
|
136
|
+
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
137
|
+
}
|
138
|
+
|
139
|
+
it { should eq(Smartdown::Model::Predicate::Function.new("function_name", [])) }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "single argument" do
|
144
|
+
let(:source) { "function_name(arg_1)" }
|
145
|
+
|
146
|
+
it { should parse(source).as(function_predicate: { name: "function_name", arguments: {function_argument: "arg_1"} }) }
|
147
|
+
it { should_not parse("function_name(hello") }
|
148
|
+
it { should_not parse("function name(hello)") }
|
149
|
+
it { should_not parse("function_name(hello) foo") }
|
150
|
+
|
151
|
+
describe "transformed" do
|
152
|
+
let(:node_name) { "my_node" }
|
153
|
+
subject(:transformed) {
|
154
|
+
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
155
|
+
}
|
156
|
+
|
157
|
+
it { should eq(Smartdown::Model::Predicate::Function.new("function_name", ["arg_1"])) }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "multiple arguments" do
|
162
|
+
let(:source) { "function_name(arg_1 arg_2 arg_3)" }
|
163
|
+
|
164
|
+
it { should parse(source).as(
|
165
|
+
{ function_predicate: {
|
166
|
+
name: "function_name", arguments:
|
167
|
+
[
|
168
|
+
{function_argument: "arg_1"},
|
169
|
+
{function_argument: "arg_2"},
|
170
|
+
{function_argument: "arg_3"}
|
171
|
+
]
|
172
|
+
} }
|
173
|
+
) }
|
174
|
+
|
175
|
+
it { should_not parse("function_name(hello, foo") }
|
176
|
+
it { should_not parse("function name(hello, foo, bar) bar") }
|
177
|
+
|
178
|
+
describe "transformed" do
|
179
|
+
let(:node_name) { "my_node" }
|
180
|
+
subject(:transformed) {
|
181
|
+
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
182
|
+
}
|
183
|
+
|
184
|
+
it { should eq(Smartdown::Model::Predicate::Function.new("function_name", ["arg_1", "arg_2", "arg_3"])) }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
107
189
|
describe "comparison predicate" do
|
108
190
|
subject(:parser) { described_class.new }
|
109
191
|
let(:greater_equal_source) { "varname >= 'value'" }
|
@@ -122,19 +204,19 @@ describe Smartdown::Parser::Predicates do
|
|
122
204
|
subject(:transformed) {
|
123
205
|
Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
|
124
206
|
}
|
125
|
-
context "greater" do
|
207
|
+
context "greater or equal" do
|
126
208
|
let(:source) { greater_equal_source }
|
127
209
|
it { should eq(Smartdown::Model::Predicate::Comparison::GreaterOrEqual.new("varname", "value")) }
|
128
210
|
end
|
129
|
-
context "
|
211
|
+
context "greater" do
|
130
212
|
let(:source) { greater_source }
|
131
213
|
it { should eq(Smartdown::Model::Predicate::Comparison::Greater.new("varname", "value")) }
|
132
214
|
end
|
133
|
-
context "
|
215
|
+
context "less than or equal" do
|
134
216
|
let(:source) { less_equal_source }
|
135
217
|
it { should eq(Smartdown::Model::Predicate::Comparison::LessOrEqual.new("varname", "value")) }
|
136
218
|
end
|
137
|
-
context "
|
219
|
+
context "less than" do
|
138
220
|
let(:source) { less_source }
|
139
221
|
it { should eq(Smartdown::Model::Predicate::Comparison::Less.new("varname", "value")) }
|
140
222
|
end
|
@@ -120,6 +120,10 @@ class ModelBuilder
|
|
120
120
|
@predicate = Smartdown::Model::Predicate::Named.new(name)
|
121
121
|
end
|
122
122
|
|
123
|
+
def set_membership_predicate(varname, values)
|
124
|
+
@predicate = Smartdown::Model::Predicate::SetMembership.new(varname, values)
|
125
|
+
end
|
126
|
+
|
123
127
|
def outcome(name)
|
124
128
|
@outcome = name
|
125
129
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smartdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2014-07-09 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parslet
|
16
|
-
requirement: &
|
16
|
+
requirement: &10821840 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.6.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *10821840
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &10820700 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.0.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *10820700
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &10818660 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *10818660
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: gem_publisher
|
49
|
-
requirement: &
|
49
|
+
requirement: &10832280 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *10832280
|
58
58
|
description:
|
59
59
|
email: david.heath@digital.cabinet-office.gov.uk
|
60
60
|
executables:
|
@@ -100,11 +100,11 @@ files:
|
|
100
100
|
- lib/smartdown/engine/conditional_resolver.rb
|
101
101
|
- lib/smartdown/engine/transition.rb
|
102
102
|
- lib/smartdown/engine/interpolator.rb
|
103
|
-
- lib/smartdown/engine/predicate_evaluator.rb
|
104
103
|
- lib/smartdown/engine/errors.rb
|
105
104
|
- lib/smartdown/model/flow.rb
|
106
105
|
- lib/smartdown/model/predicate/named.rb
|
107
106
|
- lib/smartdown/model/predicate/set_membership.rb
|
107
|
+
- lib/smartdown/model/predicate/function.rb
|
108
108
|
- lib/smartdown/model/predicate/equality.rb
|
109
109
|
- lib/smartdown/model/predicate/comparison/less_or_equal.rb
|
110
110
|
- lib/smartdown/model/predicate/comparison/greater_or_equal.rb
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- lib/smartdown/model/predicate/comparison/greater.rb
|
113
113
|
- lib/smartdown/model/predicate/comparison/less.rb
|
114
114
|
- lib/smartdown/model/predicate/combined.rb
|
115
|
+
- lib/smartdown/model/predicate/otherwise.rb
|
115
116
|
- lib/smartdown/model/node.rb
|
116
117
|
- lib/smartdown/model/front_matter.rb
|
117
118
|
- lib/smartdown/model/element/conditional.rb
|
@@ -149,7 +150,6 @@ files:
|
|
149
150
|
- spec/spec_helper.rb
|
150
151
|
- spec/engine/state_spec.rb
|
151
152
|
- spec/engine/interpolator_spec.rb
|
152
|
-
- spec/engine/predicate_evaluator_spec.rb
|
153
153
|
- spec/engine/transition_spec.rb
|
154
154
|
- spec/engine/conditional_resolver_spec.rb
|
155
155
|
- spec/fixtures/directory_input/scenarios/s1.txt
|
@@ -159,6 +159,13 @@ files:
|
|
159
159
|
- spec/fixtures/acceptance/question-and-outcome/question-and-outcome.txt
|
160
160
|
- spec/fixtures/acceptance/question-and-outcome/outcomes/o1.txt
|
161
161
|
- spec/fixtures/acceptance/question-and-outcome/questions/q1.txt
|
162
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_untrained_with_lions.txt
|
163
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_tigers_are_fine.txt
|
164
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_safe_pet.txt
|
165
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_trained_with_lions.txt
|
166
|
+
- spec/fixtures/acceptance/animal-example-simple/animal-example-simple.txt
|
167
|
+
- spec/fixtures/acceptance/animal-example-simple/questions/question_1.txt
|
168
|
+
- spec/fixtures/acceptance/animal-example-simple/questions/question_2.txt
|
162
169
|
- spec/fixtures/acceptance/cover-sheet/cover-sheet.txt
|
163
170
|
- spec/fixtures/acceptance/one-question/one-question.txt
|
164
171
|
- spec/fixtures/acceptance/one-question/questions/q1.txt
|
@@ -167,6 +174,12 @@ files:
|
|
167
174
|
- spec/engine_spec.rb
|
168
175
|
- spec/model/node_spec.rb
|
169
176
|
- spec/model/flow_spec.rb
|
177
|
+
- spec/model/predicates/set_membership_spec.rb
|
178
|
+
- spec/model/predicates/combined_spec.rb
|
179
|
+
- spec/model/predicates/comparison_spec.rb
|
180
|
+
- spec/model/predicates/equality_spec.rb
|
181
|
+
- spec/model/predicates/named_spec.rb
|
182
|
+
- spec/model/predicates/function_spec.rb
|
170
183
|
homepage: https://github.com/alphagov/smartdown
|
171
184
|
licenses:
|
172
185
|
- MIT
|
@@ -182,7 +195,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
195
|
version: '0'
|
183
196
|
segments:
|
184
197
|
- 0
|
185
|
-
hash:
|
198
|
+
hash: -1672361924519016433
|
186
199
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
200
|
none: false
|
188
201
|
requirements:
|
@@ -191,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
204
|
version: '0'
|
192
205
|
segments:
|
193
206
|
- 0
|
194
|
-
hash:
|
207
|
+
hash: -1672361924519016433
|
195
208
|
requirements: []
|
196
209
|
rubyforge_project:
|
197
210
|
rubygems_version: 1.8.11
|
@@ -220,7 +233,6 @@ test_files:
|
|
220
233
|
- spec/spec_helper.rb
|
221
234
|
- spec/engine/state_spec.rb
|
222
235
|
- spec/engine/interpolator_spec.rb
|
223
|
-
- spec/engine/predicate_evaluator_spec.rb
|
224
236
|
- spec/engine/transition_spec.rb
|
225
237
|
- spec/engine/conditional_resolver_spec.rb
|
226
238
|
- spec/fixtures/directory_input/scenarios/s1.txt
|
@@ -230,6 +242,13 @@ test_files:
|
|
230
242
|
- spec/fixtures/acceptance/question-and-outcome/question-and-outcome.txt
|
231
243
|
- spec/fixtures/acceptance/question-and-outcome/outcomes/o1.txt
|
232
244
|
- spec/fixtures/acceptance/question-and-outcome/questions/q1.txt
|
245
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_untrained_with_lions.txt
|
246
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_tigers_are_fine.txt
|
247
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_safe_pet.txt
|
248
|
+
- spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_trained_with_lions.txt
|
249
|
+
- spec/fixtures/acceptance/animal-example-simple/animal-example-simple.txt
|
250
|
+
- spec/fixtures/acceptance/animal-example-simple/questions/question_1.txt
|
251
|
+
- spec/fixtures/acceptance/animal-example-simple/questions/question_2.txt
|
233
252
|
- spec/fixtures/acceptance/cover-sheet/cover-sheet.txt
|
234
253
|
- spec/fixtures/acceptance/one-question/one-question.txt
|
235
254
|
- spec/fixtures/acceptance/one-question/questions/q1.txt
|
@@ -238,3 +257,9 @@ test_files:
|
|
238
257
|
- spec/engine_spec.rb
|
239
258
|
- spec/model/node_spec.rb
|
240
259
|
- spec/model/flow_spec.rb
|
260
|
+
- spec/model/predicates/set_membership_spec.rb
|
261
|
+
- spec/model/predicates/combined_spec.rb
|
262
|
+
- spec/model/predicates/comparison_spec.rb
|
263
|
+
- spec/model/predicates/equality_spec.rb
|
264
|
+
- spec/model/predicates/named_spec.rb
|
265
|
+
- spec/model/predicates/function_spec.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Smartdown
|
2
|
-
class Engine
|
3
|
-
class PredicateEvaluator
|
4
|
-
def evaluate(predicate, state)
|
5
|
-
evaluator_for(predicate).call(state)
|
6
|
-
end
|
7
|
-
|
8
|
-
private
|
9
|
-
def evaluator_for(predicate)
|
10
|
-
case predicate
|
11
|
-
when Smartdown::Model::Predicate::Equality
|
12
|
-
->(state) { state.get(predicate.varname) == predicate.expected_value }
|
13
|
-
when Smartdown::Model::Predicate::SetMembership
|
14
|
-
->(state) { predicate.values.include?(state.get(predicate.varname)) }
|
15
|
-
when Smartdown::Model::Predicate::Named
|
16
|
-
->(state) { state.get(predicate.name) }
|
17
|
-
when Smartdown::Model::Predicate::Comparison::Base
|
18
|
-
->(state) { predicate.evaluate(state.get(predicate.varname)) }
|
19
|
-
when Smartdown::Model::Predicate::Combined
|
20
|
-
->(state) { predicate.predicates.map { |p| evaluate(p, state) }.all? }
|
21
|
-
else
|
22
|
-
raise "Unknown predicate type #{predicate.class}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,284 +0,0 @@
|
|
1
|
-
require 'smartdown/engine/predicate_evaluator'
|
2
|
-
require 'smartdown/model/predicate/equality'
|
3
|
-
require 'smartdown/model/predicate/set_membership'
|
4
|
-
require 'smartdown/model/predicate/named'
|
5
|
-
require 'smartdown/model/predicate/combined'
|
6
|
-
require 'smartdown/model/predicate/comparison/greater_or_equal'
|
7
|
-
require 'smartdown/model/predicate/comparison/greater'
|
8
|
-
require 'smartdown/model/predicate/comparison/less_or_equal'
|
9
|
-
require 'smartdown/model/predicate/comparison/less'
|
10
|
-
require 'smartdown/engine/state'
|
11
|
-
|
12
|
-
describe Smartdown::Engine::PredicateEvaluator do
|
13
|
-
subject(:evaluator) { described_class.new }
|
14
|
-
|
15
|
-
context "equality predicate" do
|
16
|
-
let(:predicate) { Smartdown::Model::Predicate::Equality.new("my_var", "some value") }
|
17
|
-
|
18
|
-
describe "#evaluate" do
|
19
|
-
context "state missing expected variable" do
|
20
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
21
|
-
|
22
|
-
it "raises an UndefinedValue error" do
|
23
|
-
expect { evaluator.evaluate(predicate, state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context "state has expected variable with same value" do
|
28
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "some value") }
|
29
|
-
|
30
|
-
it "evaluates to true" do
|
31
|
-
expect(evaluator.evaluate(predicate, state)).to eq(true)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "state has expected variable with a different value" do
|
36
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "some other value") }
|
37
|
-
|
38
|
-
it "evaluates to false" do
|
39
|
-
expect(evaluator.evaluate(predicate, state)).to eq(false)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "set membership predicate" do
|
46
|
-
let(:expected_values) { ["v1", "v2", "v3"] }
|
47
|
-
let(:varname) { "my_var" }
|
48
|
-
let(:predicate) { Smartdown::Model::Predicate::SetMembership.new(varname, expected_values) }
|
49
|
-
|
50
|
-
describe "#evaluate" do
|
51
|
-
context "state missing expected variable" do
|
52
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
53
|
-
|
54
|
-
it "raises an UndefinedValue error" do
|
55
|
-
expect { evaluator.evaluate(predicate, state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context "state has expected variable with one of the expected values" do
|
60
|
-
it "evaluates to true" do
|
61
|
-
expected_values.each do |value|
|
62
|
-
state = Smartdown::Engine::State.new(current_node: "n", varname => value)
|
63
|
-
expect(evaluator.evaluate(predicate, state)).to eq(true)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context "state has expected variable with a value not in the list of expected values" do
|
69
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", varname => "some other value") }
|
70
|
-
|
71
|
-
it "evaluates to false" do
|
72
|
-
expect(evaluator.evaluate(predicate, state)).to eq(false)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context "named predicate" do
|
79
|
-
let(:predicate_name) { "my_pred?" }
|
80
|
-
let(:predicate) { Smartdown::Model::Predicate::Named.new(predicate_name) }
|
81
|
-
|
82
|
-
describe "#evaluate" do
|
83
|
-
context "state missing predicate definition" do
|
84
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
85
|
-
|
86
|
-
it "raises an UndefinedValue error" do
|
87
|
-
expect { evaluator.evaluate(predicate, state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "state has predicate definition" do
|
92
|
-
let(:state) {
|
93
|
-
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => true )
|
94
|
-
}
|
95
|
-
|
96
|
-
it "fetches the predicate value from the state" do
|
97
|
-
expect(evaluator.evaluate(predicate, state)).to eq(true)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context "combined predicate" do
|
104
|
-
let(:predicate_name) { "my_pred?" }
|
105
|
-
let(:predicate_name_2) { "my_other_pred?" }
|
106
|
-
let(:predicate) { Smartdown::Model::Predicate::Named.new(predicate_name) }
|
107
|
-
let(:predicate_2) { Smartdown::Model::Predicate::Named.new(predicate_name_2) }
|
108
|
-
let(:combined_predicate) { Smartdown::Model::Predicate::Combined.new([predicate, predicate_2])}
|
109
|
-
|
110
|
-
describe "#evaluate" do
|
111
|
-
|
112
|
-
context "both states are true" do
|
113
|
-
let(:state) {
|
114
|
-
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => true, "my_other_pred?" => true )
|
115
|
-
}
|
116
|
-
|
117
|
-
it "evaluates as true" do
|
118
|
-
expect(evaluator.evaluate(combined_predicate, state)).to eq(true)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
context "both states are false" do
|
123
|
-
let(:state) {
|
124
|
-
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => false, "my_other_pred?" => false )
|
125
|
-
}
|
126
|
-
|
127
|
-
it "evaluates as false" do
|
128
|
-
expect(evaluator.evaluate(combined_predicate, state)).to eq(false)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
context "one of the states is false" do
|
133
|
-
let(:state) {
|
134
|
-
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => true, "my_other_pred?" => false )
|
135
|
-
}
|
136
|
-
|
137
|
-
it "evaluates as false" do
|
138
|
-
expect(evaluator.evaluate(combined_predicate, state)).to eq(false)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
context "comparison predicates with integers" do
|
146
|
-
let(:greater_predicate) { Smartdown::Model::Predicate::Comparison::Greater.new("my_var", "5") }
|
147
|
-
let(:greater_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::GreaterOrEqual.new("my_var", "5") }
|
148
|
-
let(:less_predicate) { Smartdown::Model::Predicate::Comparison::Less.new("my_var", "5") }
|
149
|
-
let(:less_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::LessOrEqual.new("my_var", "5") }
|
150
|
-
let(:predicates) { {
|
151
|
-
:greater => greater_predicate,
|
152
|
-
:greater_or_equal => greater_or_equal_predicate,
|
153
|
-
:less => less_predicate,
|
154
|
-
:less_or_equal => less_or_equal_predicate
|
155
|
-
} }
|
156
|
-
|
157
|
-
describe "#evaluate" do
|
158
|
-
context "state missing expected variable" do
|
159
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
160
|
-
|
161
|
-
it "raises an UndefinedValue error" do
|
162
|
-
predicates.values.each do |predicate|
|
163
|
-
expect { evaluator.evaluate(predicate, state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
context "state has lower value" do
|
169
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "4") }
|
170
|
-
let(:results) { {
|
171
|
-
:greater => false,
|
172
|
-
:greater_or_equal => false,
|
173
|
-
:less => true,
|
174
|
-
:less_or_equal => true
|
175
|
-
} }
|
176
|
-
it "evaluates correctly" do
|
177
|
-
predicates.each do |predicate_key, predicate|
|
178
|
-
expect(evaluator.evaluate(predicate, state)).to eq(results[predicate_key])
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
context "state has identical value" do
|
184
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "5") }
|
185
|
-
let(:results) { {
|
186
|
-
:greater => false,
|
187
|
-
:greater_or_equal => true,
|
188
|
-
:less => false,
|
189
|
-
:less_or_equal => true
|
190
|
-
} }
|
191
|
-
it "evaluates correctly" do
|
192
|
-
predicates.each do |predicate_key, predicate|
|
193
|
-
expect(evaluator.evaluate(predicate, state)).to eq(results[predicate_key])
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
context "state has higher value" do
|
199
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "6") }
|
200
|
-
let(:results) { {
|
201
|
-
:greater => true,
|
202
|
-
:greater_or_equal => true,
|
203
|
-
:less => false,
|
204
|
-
:less_or_equal => false
|
205
|
-
} }
|
206
|
-
it "evaluates correctly" do
|
207
|
-
predicates.each do |predicate_key, predicate|
|
208
|
-
expect(evaluator.evaluate(predicate, state)).to eq(results[predicate_key])
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
context "comparison predicates with dates" do
|
216
|
-
let(:greater_predicate) { Smartdown::Model::Predicate::Comparison::Greater.new("my_var", "2014-1-31") }
|
217
|
-
let(:greater_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::GreaterOrEqual.new("my_var", "2014-1-31") }
|
218
|
-
let(:less_predicate) { Smartdown::Model::Predicate::Comparison::Less.new("my_var", "2014-1-31") }
|
219
|
-
let(:less_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::LessOrEqual.new("my_var", "2014-1-31") }
|
220
|
-
let(:predicates) { {
|
221
|
-
:greater => greater_predicate,
|
222
|
-
:greater_or_equal => greater_or_equal_predicate,
|
223
|
-
:less => less_predicate,
|
224
|
-
:less_or_equal => less_or_equal_predicate
|
225
|
-
} }
|
226
|
-
|
227
|
-
describe "#evaluate" do
|
228
|
-
context "state missing expected variable" do
|
229
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
230
|
-
|
231
|
-
it "raises an UndefinedValue error" do
|
232
|
-
predicates.values.each do |predicate|
|
233
|
-
expect { evaluator.evaluate(predicate, state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
context "state has lower value" do
|
239
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "2014-1-30") }
|
240
|
-
let(:results) { {
|
241
|
-
:greater => false,
|
242
|
-
:greater_or_equal => false,
|
243
|
-
:less => true,
|
244
|
-
:less_or_equal => true
|
245
|
-
} }
|
246
|
-
it "evaluates correctly" do
|
247
|
-
predicates.each do |predicate_key, predicate|
|
248
|
-
expect(evaluator.evaluate(predicate, state)).to eq(results[predicate_key])
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
context "state has identical value" do
|
254
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "2014-1-31") }
|
255
|
-
let(:results) { {
|
256
|
-
:greater => false,
|
257
|
-
:greater_or_equal => true,
|
258
|
-
:less => false,
|
259
|
-
:less_or_equal => true
|
260
|
-
} }
|
261
|
-
it "evaluates correctly" do
|
262
|
-
predicates.each do |predicate_key, predicate|
|
263
|
-
expect(evaluator.evaluate(predicate, state)).to eq(results[predicate_key])
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
context "state has higher value" do
|
269
|
-
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "2014-2-1") }
|
270
|
-
let(:results) { {
|
271
|
-
:greater => true,
|
272
|
-
:greater_or_equal => true,
|
273
|
-
:less => false,
|
274
|
-
:less_or_equal => false
|
275
|
-
} }
|
276
|
-
it "evaluates correctly" do
|
277
|
-
predicates.each do |predicate_key, predicate|
|
278
|
-
expect(evaluator.evaluate(predicate, state)).to eq(results[predicate_key])
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|