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
@@ -0,0 +1,25 @@
|
|
1
|
+
meta_description: Animals eh?
|
2
|
+
satisfies_need: 100982
|
3
|
+
status: draft
|
4
|
+
|
5
|
+
# A simple example of smartdown
|
6
|
+
|
7
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
8
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
9
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
10
|
+
consequat.
|
11
|
+
|
12
|
+
Duis aute irure dolor in reprehenderit in voluptate velit esse
|
13
|
+
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
14
|
+
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
15
|
+
|
16
|
+
## Before you start, you will need
|
17
|
+
|
18
|
+
* To know the kind of feline you have
|
19
|
+
* Any animal training certification documents
|
20
|
+
|
21
|
+
[start: question_1]
|
22
|
+
|
23
|
+
## Devolved body
|
24
|
+
|
25
|
+
Which is really just body content after the start button
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# You picked a safe pet
|
2
|
+
|
3
|
+
Good call.
|
4
|
+
|
5
|
+
# Markdown/Govspeak examples
|
6
|
+
|
7
|
+
## H2 example
|
8
|
+
|
9
|
+
With answers, that are smart. Down with that?
|
10
|
+
|
11
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
12
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
13
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
14
|
+
|
15
|
+
### H3 example
|
16
|
+
|
17
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
18
|
+
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
19
|
+
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
20
|
+
|
21
|
+
## List
|
22
|
+
|
23
|
+
* one
|
24
|
+
* two
|
25
|
+
* three
|
26
|
+
|
27
|
+
## List 2
|
28
|
+
|
29
|
+
- A
|
30
|
+
- B
|
31
|
+
- C
|
32
|
+
|
33
|
+
## List 3
|
34
|
+
|
35
|
+
+ Up
|
36
|
+
+ Down
|
37
|
+
+ Left
|
38
|
+
+ Right
|
39
|
+
|
40
|
+
^This is an information callout.^
|
41
|
+
|
42
|
+
%This is a warning callout - use it when there’s a risk of getting a fine or going to prison.%
|
43
|
+
|
44
|
+
$E
|
45
|
+
**Example**
|
46
|
+
Your income for the last tax year was £30,000. You think your income will drop to £20,000 this tax year. Enter £22,500 into the calculator.
|
47
|
+
$E
|
48
|
+
|
49
|
+
{::highlight-answer}
|
50
|
+
The VAT rate is *20%*
|
51
|
+
{:/highlight-answer}
|
52
|
+
|
53
|
+
|
54
|
+
$C
|
55
|
+
**Student Finance England**
|
56
|
+
Telephone: 0845 300 5090
|
57
|
+
Minicom: 0845 604 4434
|
58
|
+
[Find out about call charges](http://www.gov.uk/call-charges)
|
59
|
+
$C
|
60
|
+
|
61
|
+
$A
|
62
|
+
Hercules House
|
63
|
+
Hercules Road
|
64
|
+
London SE1 7DU
|
65
|
+
$A
|
66
|
+
|
67
|
+
$D
|
68
|
+
[Download the 'Example application form' (PDF, 35KB)](http://example.com/ "Example form")
|
69
|
+
$D
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Amazing page title
|
2
|
+
|
3
|
+
# What type of feline do you have?
|
4
|
+
|
5
|
+
Check the serial number by the tail.
|
6
|
+
|
7
|
+
[choice: question_1]
|
8
|
+
* lion: Lion
|
9
|
+
* tiger: Tiger
|
10
|
+
* cat: Cat
|
11
|
+
|
12
|
+
* question_1 in {lion tiger} => question_2
|
13
|
+
* otherwise => outcome_safe_pet
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'smartdown/model/predicate/combined'
|
2
|
+
require 'smartdown/model/predicate/combined'
|
3
|
+
require 'smartdown/model/predicate/named'
|
4
|
+
require 'smartdown/engine/state'
|
5
|
+
|
6
|
+
describe Smartdown::Model::Predicate::Combined do
|
7
|
+
let(:predicate_1) { Smartdown::Model::Predicate::Named.new("my_pred?") }
|
8
|
+
let(:predicate_2) { Smartdown::Model::Predicate::Named.new("my_other_pred?") }
|
9
|
+
subject(:predicate) { described_class.new([predicate_1, predicate_2])}
|
10
|
+
|
11
|
+
describe "#evaluate" do
|
12
|
+
|
13
|
+
context "both states are true" do
|
14
|
+
let(:state) {
|
15
|
+
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => true, "my_other_pred?" => true )
|
16
|
+
}
|
17
|
+
|
18
|
+
it "evaluates as true" do
|
19
|
+
expect(predicate.evaluate(state)).to eq(true)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "both states are false" do
|
24
|
+
let(:state) {
|
25
|
+
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => false, "my_other_pred?" => false )
|
26
|
+
}
|
27
|
+
|
28
|
+
it "evaluates as false" do
|
29
|
+
expect(predicate.evaluate(state)).to eq(false)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "one of the states is false" do
|
34
|
+
let(:state) {
|
35
|
+
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => true, "my_other_pred?" => false )
|
36
|
+
}
|
37
|
+
|
38
|
+
it "evaluates as false" do
|
39
|
+
expect(predicate.evaluate(state)).to eq(false)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#humanize" do
|
45
|
+
it { expect(predicate.humanize).to eq("(my_pred? AND my_other_pred?)") }
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'smartdown/model/predicate/comparison/greater_or_equal'
|
2
|
+
require 'smartdown/model/predicate/comparison/greater'
|
3
|
+
require 'smartdown/model/predicate/comparison/less_or_equal'
|
4
|
+
require 'smartdown/model/predicate/comparison/less'
|
5
|
+
require 'smartdown/engine/state'
|
6
|
+
|
7
|
+
describe "comparison predicates" do
|
8
|
+
context "comparison predicates with integers" do
|
9
|
+
let(:greater_predicate) { Smartdown::Model::Predicate::Comparison::Greater.new("my_var", "5") }
|
10
|
+
let(:greater_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::GreaterOrEqual.new("my_var", "5") }
|
11
|
+
let(:less_predicate) { Smartdown::Model::Predicate::Comparison::Less.new("my_var", "5") }
|
12
|
+
let(:less_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::LessOrEqual.new("my_var", "5") }
|
13
|
+
let(:predicates) { {
|
14
|
+
:greater => greater_predicate,
|
15
|
+
:greater_or_equal => greater_or_equal_predicate,
|
16
|
+
:less => less_predicate,
|
17
|
+
:less_or_equal => less_or_equal_predicate
|
18
|
+
} }
|
19
|
+
|
20
|
+
describe "#evaluate" do
|
21
|
+
context "state missing expected variable" do
|
22
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
23
|
+
|
24
|
+
it "raises an UndefinedValue error" do
|
25
|
+
predicates.values.each do |predicate|
|
26
|
+
expect { predicate.evaluate(state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "state has lower value" do
|
32
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "4") }
|
33
|
+
let(:results) { {
|
34
|
+
:greater => false,
|
35
|
+
:greater_or_equal => false,
|
36
|
+
:less => true,
|
37
|
+
:less_or_equal => true
|
38
|
+
} }
|
39
|
+
it "evaluates correctly" do
|
40
|
+
predicates.each do |predicate_key, predicate|
|
41
|
+
expect(predicate.evaluate(state)).to eq(results[predicate_key])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "state has identical value" do
|
47
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "5") }
|
48
|
+
let(:results) { {
|
49
|
+
:greater => false,
|
50
|
+
:greater_or_equal => true,
|
51
|
+
:less => false,
|
52
|
+
:less_or_equal => true
|
53
|
+
} }
|
54
|
+
it "evaluates correctly" do
|
55
|
+
predicates.each do |predicate_key, predicate|
|
56
|
+
expect(predicate.evaluate(state)).to eq(results[predicate_key])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "state has higher value" do
|
62
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "6") }
|
63
|
+
let(:results) { {
|
64
|
+
:greater => true,
|
65
|
+
:greater_or_equal => true,
|
66
|
+
:less => false,
|
67
|
+
:less_or_equal => false
|
68
|
+
} }
|
69
|
+
it "evaluates correctly" do
|
70
|
+
predicates.each do |predicate_key, predicate|
|
71
|
+
expect(predicate.evaluate(state)).to eq(results[predicate_key])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#humanize" do
|
78
|
+
let(:results) { {
|
79
|
+
:greater => "my_var > 5",
|
80
|
+
:greater_or_equal => "my_var >= 5",
|
81
|
+
:less => "my_var < 5",
|
82
|
+
:less_or_equal => "my_var <= 5"
|
83
|
+
} }
|
84
|
+
|
85
|
+
it "has the right human representation" do
|
86
|
+
predicates.each do |predicate_key, predicate|
|
87
|
+
expect(predicate.humanize).to eq(results[predicate_key])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "comparison predicates with dates" do
|
94
|
+
let(:greater_predicate) { Smartdown::Model::Predicate::Comparison::Greater.new("my_var", "2014-1-31") }
|
95
|
+
let(:greater_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::GreaterOrEqual.new("my_var", "2014-1-31") }
|
96
|
+
let(:less_predicate) { Smartdown::Model::Predicate::Comparison::Less.new("my_var", "2014-1-31") }
|
97
|
+
let(:less_or_equal_predicate) { Smartdown::Model::Predicate::Comparison::LessOrEqual.new("my_var", "2014-1-31") }
|
98
|
+
let(:predicates) { {
|
99
|
+
:greater => greater_predicate,
|
100
|
+
:greater_or_equal => greater_or_equal_predicate,
|
101
|
+
:less => less_predicate,
|
102
|
+
:less_or_equal => less_or_equal_predicate
|
103
|
+
} }
|
104
|
+
|
105
|
+
describe "#evaluate" do
|
106
|
+
context "state missing expected variable" do
|
107
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
108
|
+
|
109
|
+
it "raises an UndefinedValue error" do
|
110
|
+
predicates.values.each do |predicate|
|
111
|
+
expect { predicate.evaluate(state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "state has lower value" do
|
117
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "2014-1-30") }
|
118
|
+
let(:results) { {
|
119
|
+
:greater => false,
|
120
|
+
:greater_or_equal => false,
|
121
|
+
:less => true,
|
122
|
+
:less_or_equal => true
|
123
|
+
} }
|
124
|
+
it "evaluates correctly" do
|
125
|
+
predicates.each do |predicate_key, predicate|
|
126
|
+
expect(predicate.evaluate(state)).to eq(results[predicate_key])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "state has identical value" do
|
132
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "2014-1-31") }
|
133
|
+
let(:results) { {
|
134
|
+
:greater => false,
|
135
|
+
:greater_or_equal => true,
|
136
|
+
:less => false,
|
137
|
+
:less_or_equal => true
|
138
|
+
} }
|
139
|
+
it "evaluates correctly" do
|
140
|
+
predicates.each do |predicate_key, predicate|
|
141
|
+
expect(predicate.evaluate(state)).to eq(results[predicate_key])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "state has higher value" do
|
147
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "2014-2-1") }
|
148
|
+
let(:results) { {
|
149
|
+
:greater => true,
|
150
|
+
:greater_or_equal => true,
|
151
|
+
:less => false,
|
152
|
+
:less_or_equal => false
|
153
|
+
} }
|
154
|
+
it "evaluates correctly" do
|
155
|
+
predicates.each do |predicate_key, predicate|
|
156
|
+
expect(predicate.evaluate(state)).to eq(results[predicate_key])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'smartdown/model/predicate/equality'
|
2
|
+
require 'smartdown/engine/state'
|
3
|
+
|
4
|
+
describe Smartdown::Model::Predicate::Equality do
|
5
|
+
subject(:predicate) { described_class.new("my_var", "some value") }
|
6
|
+
|
7
|
+
describe "#evaluate" do
|
8
|
+
context "state missing expected variable" do
|
9
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
10
|
+
|
11
|
+
it "raises an UndefinedValue error" do
|
12
|
+
expect { predicate.evaluate(state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "state has expected variable with same value" do
|
17
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "some value") }
|
18
|
+
|
19
|
+
it "evaluates to true" do
|
20
|
+
expect(predicate.evaluate(state)).to eq(true)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "state has expected variable with a different value" do
|
25
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", my_var: "some other value") }
|
26
|
+
|
27
|
+
it "evaluates to false" do
|
28
|
+
expect(predicate.evaluate(state)).to eq(false)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#humanize" do
|
34
|
+
it { expect(predicate.humanize).to eq("my_var == 'some value'") }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'smartdown/model/predicate/function'
|
2
|
+
require 'smartdown/engine/state'
|
3
|
+
|
4
|
+
describe Smartdown::Model::Predicate::Function do
|
5
|
+
let(:function_name) { "my_function" }
|
6
|
+
subject(:predicate) { described_class.new(function_name, []) }
|
7
|
+
|
8
|
+
describe "#evaluate" do
|
9
|
+
context "state missing expected function definition" do
|
10
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
11
|
+
|
12
|
+
it "raises an UndefinedValue error" do
|
13
|
+
expect { predicate.evaluate(state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with no arguments" do
|
18
|
+
let(:function_return) { "hello" }
|
19
|
+
let(:my_function) { ->() { "hello" } }
|
20
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", function_name => my_function) }
|
21
|
+
|
22
|
+
it "gets the return value of the function" do
|
23
|
+
expect(predicate.evaluate(state)).to eq(function_return)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with arguments" do
|
28
|
+
let(:my_function) { ->(x) { x * 100 } }
|
29
|
+
subject(:predicate) { described_class.new(function_name, ["number"]) }
|
30
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", "number" => 3, function_name => my_function) }
|
31
|
+
|
32
|
+
it "gets the return value of the function" do
|
33
|
+
expect(predicate.evaluate(state)).to eq(300)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with many arguments" do
|
38
|
+
let(:function_return) { "hello" }
|
39
|
+
let(:my_function) { ->(name, age) { "Hi #{name}, you were #{age-20}, 20 years ago" } }
|
40
|
+
subject(:predicate) { described_class.new(function_name, ["name", "age"]) }
|
41
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", "name" => "David", "age" => 30, function_name => my_function) }
|
42
|
+
|
43
|
+
it "gets the return value of the function" do
|
44
|
+
expect(predicate.evaluate(state)).to eq("Hi David, you were 10, 20 years ago")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with nested functions" do
|
49
|
+
# nesting looks like: function_1(function_2(5))
|
50
|
+
let(:function_1) { ->(x) { x - 1 } }
|
51
|
+
let(:function_2) { ->(x) { x * 100 } }
|
52
|
+
subject(:predicate) {
|
53
|
+
described_class.new("function_1", [
|
54
|
+
described_class.new("function_2", ['number'])
|
55
|
+
])
|
56
|
+
}
|
57
|
+
|
58
|
+
let(:state) { Smartdown::Engine::State.new(
|
59
|
+
current_node: "n",
|
60
|
+
"function_1" => function_1,
|
61
|
+
"function_2" => function_2,
|
62
|
+
"number" => 5
|
63
|
+
) }
|
64
|
+
|
65
|
+
it "gets the return value of the function" do
|
66
|
+
expect(predicate.evaluate(state)).to eq(499)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#humanize" do
|
72
|
+
context "with no arguments" do
|
73
|
+
subject(:predicate) { described_class.new(function_name, []) }
|
74
|
+
|
75
|
+
it { expect(predicate.humanize).to eq("my_function()") }
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with some arguments" do
|
79
|
+
let(:function_name) { "my_function" }
|
80
|
+
subject(:predicate) { described_class.new(function_name, ['foo', 'bar']) }
|
81
|
+
|
82
|
+
it { expect(predicate.humanize).to eq("my_function(foo bar)") }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'smartdown/model/predicate/named'
|
2
|
+
require 'smartdown/engine/state'
|
3
|
+
|
4
|
+
describe Smartdown::Model::Predicate::Named do
|
5
|
+
let(:predicate_name) { "my_pred?" }
|
6
|
+
subject(:predicate) { described_class.new(predicate_name) }
|
7
|
+
|
8
|
+
describe "#evaluate" do
|
9
|
+
context "state missing predicate definition" do
|
10
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
11
|
+
|
12
|
+
it "raises an UndefinedValue error" do
|
13
|
+
expect { predicate.evaluate(state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "state has predicate definition" do
|
18
|
+
let(:state) {
|
19
|
+
Smartdown::Engine::State.new("current_node" => "n", "my_pred?" => true )
|
20
|
+
}
|
21
|
+
|
22
|
+
it "fetches the predicate value from the state" do
|
23
|
+
expect(predicate.evaluate(state)).to eq(true)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#humanize" do
|
29
|
+
context "predicate name without question mark" do
|
30
|
+
subject(:predicate) { described_class.new("my_pred") }
|
31
|
+
|
32
|
+
it { expect(predicate.humanize).to eq("my_pred?") }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "predicate name with question mark" do
|
36
|
+
subject(:predicate) { described_class.new("my_pred?") }
|
37
|
+
|
38
|
+
it { expect(predicate.humanize).to eq("my_pred?") }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'smartdown/model/predicate/set_membership'
|
2
|
+
require 'smartdown/engine/state'
|
3
|
+
|
4
|
+
describe Smartdown::Model::Predicate::SetMembership do
|
5
|
+
let(:expected_values) { ["v1", "v2", "v3"] }
|
6
|
+
let(:varname) { "my_var" }
|
7
|
+
subject(:predicate) { described_class.new(varname, expected_values) }
|
8
|
+
|
9
|
+
describe "#evaluate" do
|
10
|
+
context "state missing expected variable" do
|
11
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n") }
|
12
|
+
|
13
|
+
it "raises an UndefinedValue error" do
|
14
|
+
expect { predicate.evaluate(state) }.to raise_error(Smartdown::Engine::UndefinedValue)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "state has expected variable with one of the expected values" do
|
19
|
+
it "evaluates to true" do
|
20
|
+
expected_values.each do |value|
|
21
|
+
state = Smartdown::Engine::State.new(current_node: "n", varname => value)
|
22
|
+
expect(predicate.evaluate(state)).to eq(true)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "state has expected variable with a value not in the list of expected values" do
|
28
|
+
let(:state) { Smartdown::Engine::State.new(current_node: "n", varname => "some other value") }
|
29
|
+
|
30
|
+
it "evaluates to false" do
|
31
|
+
expect(predicate.evaluate(state)).to eq(false)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#humanize" do
|
37
|
+
it { expect(predicate.humanize).to eq("my_var in [v1, v2, v3]") }
|
38
|
+
end
|
39
|
+
end
|