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.
Files changed (42) hide show
  1. data/lib/smartdown/engine/conditional_resolver.rb +1 -9
  2. data/lib/smartdown/engine/interpolator.rb +12 -1
  3. data/lib/smartdown/engine/state.rb +1 -10
  4. data/lib/smartdown/engine/transition.rb +2 -6
  5. data/lib/smartdown/engine.rb +2 -3
  6. data/lib/smartdown/model/predicate/combined.rb +9 -1
  7. data/lib/smartdown/model/predicate/comparison/base.rb +4 -1
  8. data/lib/smartdown/model/predicate/comparison/greater.rb +6 -1
  9. data/lib/smartdown/model/predicate/comparison/greater_or_equal.rb +6 -1
  10. data/lib/smartdown/model/predicate/comparison/less.rb +6 -1
  11. data/lib/smartdown/model/predicate/comparison/less_or_equal.rb +6 -1
  12. data/lib/smartdown/model/predicate/equality.rb +9 -1
  13. data/lib/smartdown/model/predicate/function.rb +28 -0
  14. data/lib/smartdown/model/predicate/named.rb +9 -1
  15. data/lib/smartdown/model/predicate/otherwise.rb +15 -0
  16. data/lib/smartdown/model/predicate/set_membership.rb +9 -1
  17. data/lib/smartdown/parser/node_transform.rb +14 -0
  18. data/lib/smartdown/parser/predicates.rb +18 -1
  19. data/lib/smartdown/version.rb +1 -1
  20. data/spec/acceptance/parsing_spec.rb +8 -0
  21. data/spec/engine/interpolator_spec.rb +14 -0
  22. data/spec/engine/state_spec.rb +0 -37
  23. data/spec/engine/transition_spec.rb +23 -19
  24. data/spec/engine_spec.rb +8 -11
  25. data/spec/fixtures/acceptance/animal-example-simple/animal-example-simple.txt +25 -0
  26. data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_safe_pet.txt +69 -0
  27. data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_tigers_are_fine.txt +9 -0
  28. data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_trained_with_lions.txt +3 -0
  29. data/spec/fixtures/acceptance/animal-example-simple/outcomes/outcome_untrained_with_lions.txt +3 -0
  30. data/spec/fixtures/acceptance/animal-example-simple/questions/question_1.txt +13 -0
  31. data/spec/fixtures/acceptance/animal-example-simple/questions/question_2.txt +10 -0
  32. data/spec/model/predicates/combined_spec.rb +47 -0
  33. data/spec/model/predicates/comparison_spec.rb +162 -0
  34. data/spec/model/predicates/equality_spec.rb +36 -0
  35. data/spec/model/predicates/function_spec.rb +85 -0
  36. data/spec/model/predicates/named_spec.rb +41 -0
  37. data/spec/model/predicates/set_membership_spec.rb +39 -0
  38. data/spec/parser/predicates_spec.rb +98 -16
  39. data/spec/support/model_builder.rb +4 -0
  40. metadata +39 -14
  41. data/lib/smartdown/engine/predicate_evaluator.rb +0 -27
  42. 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 "stricly greater" do
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 "lower" do
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 "strictly lower" do
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.3.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: &16437600 !ruby/object:Gem::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: *16437600
24
+ version_requirements: *10821840
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &16435640 !ruby/object:Gem::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: *16435640
35
+ version_requirements: *10820700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &16837980 !ruby/object:Gem::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: *16837980
46
+ version_requirements: *10818660
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: gem_publisher
49
- requirement: &16837320 !ruby/object:Gem::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: *16837320
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: 306060104431825323
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: 306060104431825323
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