akiva 0.1.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +80 -0
- data/Guardfile +11 -0
- data/LICENSE +9 -0
- data/README.md +131 -0
- data/Rakefile +5 -0
- data/akiva.gemspec +38 -0
- data/lib/akiva.rb +11 -0
- data/lib/akiva/brain.rb +47 -0
- data/lib/akiva/cli.rb +58 -0
- data/lib/akiva/core_brain/actions/get_answers_from_subjects_and_properties.rb +73 -0
- data/lib/akiva/core_brain/actions/preparators/compare_two_subjects_properties_from_comparison_adjective.rb +19 -0
- data/lib/akiva/core_brain/actions/preparators/extract_property_from_comparison_adjective.rb +10 -0
- data/lib/akiva/core_brain/actions/preparators/regroup_separated_subjects.rb +10 -0
- data/lib/akiva/core_brain/actions/preparators/sort_answers_by_units.rb +35 -0
- data/lib/akiva/core_brain/actions/template.rb +23 -0
- data/lib/akiva/core_brain/filters/get_answers_from_subjects_and_properties.rb +15 -0
- data/lib/akiva/core_brain/filters/template.rb +9 -0
- data/lib/akiva/core_brain/formatters/boolean_from_comparison.rb +17 -0
- data/lib/akiva/core_brain/formatters/list_all_answers.rb +28 -0
- data/lib/akiva/core_brain/formatters/template.rb +19 -0
- data/lib/akiva/core_brain/helpers/comparison_adjectives_to_properties.rb +151 -0
- data/lib/akiva/core_brain/helpers/misc.rb +28 -0
- data/lib/akiva/core_brain/helpers/units.rb +167 -0
- data/lib/akiva/core_brain/loader.rb +3 -0
- data/lib/akiva/question.rb +88 -0
- data/lib/akiva/version.rb +9 -0
- data/spec/lib/akiva/brain_spec.rb +89 -0
- data/spec/lib/akiva/core_brain/actions/get_answers_from_subjects_and_properties_spec.rb +77 -0
- data/spec/lib/akiva/core_brain/actions/preparators/compare_two_subjects_properties_from_comparison_adjective_spec.rb +22 -0
- data/spec/lib/akiva/core_brain/actions/preparators/extract_property_from_comparison_adjective_spec.rb +11 -0
- data/spec/lib/akiva/core_brain/actions/preparators/regroup_separated_subjects_spec.rb +11 -0
- data/spec/lib/akiva/core_brain/actions/preparators/sort_answers_by_units_spec.rb +36 -0
- data/spec/lib/akiva/core_brain/filters/get_answers_from_subjects_and_properties_spec.rb +44 -0
- data/spec/lib/akiva/core_brain/formatters/boolean_from_comparison_spec.rb +38 -0
- data/spec/lib/akiva/core_brain/formatters/list_all_answers_spec.rb +60 -0
- data/spec/lib/akiva/core_brain/helpers/misc_spec.rb +26 -0
- data/spec/lib/akiva/core_brain/helpers/units_spec.rb +141 -0
- data/spec/lib/akiva/core_brain/question_spec.rb +170 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/akiva_brain_helpers.rb +13 -0
- data/spec/support/akiva_statements_helpers.rb +66 -0
- metadata +75 -16
@@ -0,0 +1,88 @@
|
|
1
|
+
module Akiva
|
2
|
+
class Question
|
3
|
+
attr_reader :content, :filter_matched, :filter_captures, :response
|
4
|
+
|
5
|
+
def initialize(content, meta = {})
|
6
|
+
@content = content
|
7
|
+
@ran_filters = @executed_action = @executed_formatter = false
|
8
|
+
@anonymous_action = AnonymousAction.new
|
9
|
+
@response = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_filters
|
13
|
+
return self if @ran_filters
|
14
|
+
|
15
|
+
Akiva::Brain.filters.each do |filter|
|
16
|
+
if match_data = filter[:regex].match(@content)
|
17
|
+
@filter_matched = filter
|
18
|
+
@filter_captures = Hash[match_data.names.zip(match_data.captures)]
|
19
|
+
break
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@ran_filters = true
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute_action
|
28
|
+
return self if @executed_action or @filter_matched.nil?
|
29
|
+
|
30
|
+
actions_chain = (@filter_matched[:before_action] || []) + [@filter_matched[:action]] + (@filter_matched[:after_action] || [])
|
31
|
+
|
32
|
+
@response.merge!(filter_matched: @filter_matched, filter_captures: @filter_captures, formatter: @filter_matched[:formatter], actions_chain: actions_chain)
|
33
|
+
|
34
|
+
actions_chain.each do |action_name|
|
35
|
+
if action = Akiva::Brain.actions[action_name]
|
36
|
+
if action.is_a?(Proc)
|
37
|
+
@anonymous_action.instance_exec(@response, &action)
|
38
|
+
else
|
39
|
+
@response = action.process(@response)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
raise "The action #{action_name} isn't registered"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
@executed_action = true
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def execute_formatter
|
51
|
+
return self if @executed_formatter
|
52
|
+
|
53
|
+
if @response[:formatter]
|
54
|
+
if formatter = Akiva::Brain.formatters[@response[:formatter]]
|
55
|
+
if formatter.is_a?(Proc)
|
56
|
+
@anonymous_action.instance_exec(@response, &formatter)
|
57
|
+
else
|
58
|
+
@response = formatter.process(@response)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
raise "The formatter #{@response[:formatter]} isn't registered"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
@executed_formatter = true
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def process
|
70
|
+
# shortcut method
|
71
|
+
run_filters
|
72
|
+
execute_action
|
73
|
+
execute_formatter
|
74
|
+
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def formatted_response
|
79
|
+
# shortcut method
|
80
|
+
process
|
81
|
+
@response[:formatted]
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
class AnonymousAction; end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva Brain" do
|
4
|
+
before { reload_core_brain }
|
5
|
+
after { reload_core_brain }
|
6
|
+
|
7
|
+
describe "adding filters" do
|
8
|
+
it "is correctly reflected in the filters list" do
|
9
|
+
Akiva::Brain.update do
|
10
|
+
add_filter :action_name, /first filter/
|
11
|
+
end
|
12
|
+
|
13
|
+
Akiva::Brain::filters.first.should == {
|
14
|
+
regex: /first filter/,
|
15
|
+
action: :action_name
|
16
|
+
}
|
17
|
+
|
18
|
+
Akiva::Brain.update do
|
19
|
+
add_filter :action_name, /second filter/, other_options: [:a, :b, :c]
|
20
|
+
end
|
21
|
+
|
22
|
+
Akiva::Brain::filters.first.should == {
|
23
|
+
regex: /second filter/,
|
24
|
+
action: :action_name,
|
25
|
+
other_options: [:a, :b, :c]
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe "adding action" do
|
32
|
+
it "as a block is correctly reflected in the actions list" do
|
33
|
+
action = ->(response){ }
|
34
|
+
|
35
|
+
Akiva::Brain.update do
|
36
|
+
add_action :foobar, &action
|
37
|
+
end
|
38
|
+
|
39
|
+
Akiva::Brain::actions[:foobar].should == action
|
40
|
+
end
|
41
|
+
|
42
|
+
it "as an instance is correctly reflected in the actions list" do
|
43
|
+
class MyCustomAction
|
44
|
+
def process(response)
|
45
|
+
response.merge(processed: true)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
action = MyCustomAction.new
|
50
|
+
|
51
|
+
Akiva::Brain.update do
|
52
|
+
add_action :foobar, action
|
53
|
+
end
|
54
|
+
|
55
|
+
Akiva::Brain::actions[:foobar].should == action
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "adding formatters" do
|
60
|
+
it "as a block is correctly reflected in the formatters list" do
|
61
|
+
formatter = ->(response){ }
|
62
|
+
|
63
|
+
Akiva::Brain.update do
|
64
|
+
add_formatter :foobar, &formatter
|
65
|
+
end
|
66
|
+
|
67
|
+
Akiva::Brain::formatters[:foobar].should == formatter
|
68
|
+
end
|
69
|
+
|
70
|
+
it "as an instance is correctly reflected in the formatters list" do
|
71
|
+
class MyCustomFormatter
|
72
|
+
def process(response)
|
73
|
+
response.merge(processed: true)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
formatter = MyCustomFormatter.new
|
78
|
+
|
79
|
+
Akiva::Brain.update do
|
80
|
+
add_formatter :foobar, formatter
|
81
|
+
end
|
82
|
+
|
83
|
+
Akiva::Brain::formatters[:foobar].should == formatter
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
# TODO rebuild specs like the preparators
|
4
|
+
|
5
|
+
describe "Akiva CoreBrain Actions" do
|
6
|
+
it "executes on « What's the weight of an iPhone 5s »" do
|
7
|
+
stub_statements(:a0)
|
8
|
+
|
9
|
+
question = Akiva::Question.new("What's the weight of an iPhone 5s").run_filters.execute_action
|
10
|
+
question.response.should be_instance_of(Hash)
|
11
|
+
question.response.should include(subjects: ["iPhone 5s"])
|
12
|
+
question.response.should include(properties: {"iPhone 5s" => ["weight"]})
|
13
|
+
question.response.should include(answers: {"iPhone 5s" => {"weight" => "112 grams"}})
|
14
|
+
end
|
15
|
+
|
16
|
+
it "executes on « What are the weight and height of an iPhone 5s »" do
|
17
|
+
stub_statements(:a0, :a1, :a2)
|
18
|
+
|
19
|
+
question = Akiva::Question.new("What are the weight and height of an iPhone 5s").run_filters.execute_action
|
20
|
+
question.response.should be_instance_of(Hash)
|
21
|
+
question.response.should include(subjects: ["iPhone 5s"])
|
22
|
+
question.response.should include(properties: {"iPhone 5s" => ["weight", "height"]})
|
23
|
+
question.response.should include(answers: {"iPhone 5s" => {"weight" => "112 grams", "height" => "123.8 mm"}})
|
24
|
+
end
|
25
|
+
|
26
|
+
it "executes on « What are the weight of an iPhone 5s and a Galaxy S4 »" do
|
27
|
+
stub_statements(:a0, :a3, :a4)
|
28
|
+
|
29
|
+
question = Akiva::Question.new("What are the weight of an iPhone 5s and a Galaxy S4").run_filters.execute_action
|
30
|
+
question.response.should be_instance_of(Hash)
|
31
|
+
question.response.should include(subjects: ["iPhone 5s", "Galaxy S4"])
|
32
|
+
question.response.should include(properties: {"iPhone 5s" => ["weight"], "Galaxy S4" => ["weight"]})
|
33
|
+
question.response.should include(answers: {"iPhone 5s" => {"weight" => "112 grams"}, "Galaxy S4" => {"weight" => "130 grams"}})
|
34
|
+
end
|
35
|
+
|
36
|
+
it "executes on « What are the weight and height of an iPhone 5s and a Galaxy S4 »" do
|
37
|
+
stub_statements(:a0, :a1, :a2, :a3, :a4, :a5, :a6)
|
38
|
+
|
39
|
+
question = Akiva::Question.new("What are the weight and height of an iPhone 5s and a Galaxy S4").run_filters.execute_action
|
40
|
+
question.response.should be_instance_of(Hash)
|
41
|
+
question.response.should include(subjects: ["iPhone 5s", "Galaxy S4"])
|
42
|
+
question.response.should include(properties: {"iPhone 5s" => ["weight", "height"], "Galaxy S4" => ["weight", "height"]})
|
43
|
+
question.response.should include(answers: {"iPhone 5s" => {"weight" => "112 grams", "height" => "123.8 mm"}, "Galaxy S4" => {"weight" => "130 grams", "height" => "136.6 mm"}})
|
44
|
+
end
|
45
|
+
|
46
|
+
it "executes on « What is the salary of the Director of Public Affairs and Communication »" do
|
47
|
+
stub_statements(:b0)
|
48
|
+
|
49
|
+
question = Akiva::Question.new("What is the salary of the Director of Public Affairs and Communication").run_filters.execute_action
|
50
|
+
question.response.should be_instance_of(Hash)
|
51
|
+
question.response.should include(subjects: ["Director of Public Affairs and Communication"])
|
52
|
+
question.response.should include(properties: {"Director of Public Affairs and Communication" => ["salary"]})
|
53
|
+
question.response.should include(answers: {"Director of Public Affairs and Communication" => {"salary" => "$10,000"}})
|
54
|
+
end
|
55
|
+
|
56
|
+
it "executes on « What is the salary and benefits of the Director of Public Affairs and Communication »" do
|
57
|
+
stub_statements(:b0, :b1, :b2)
|
58
|
+
|
59
|
+
question = Akiva::Question.new("What is the salary and benefits of the Director of Public Affairs and Communication").run_filters.execute_action
|
60
|
+
question.response.should be_instance_of(Hash)
|
61
|
+
question.response.should include(subjects: ["Director of Public Affairs and Communication"])
|
62
|
+
question.response.should include(properties: {"Director of Public Affairs and Communication" => ["salary", "benefits"]})
|
63
|
+
question.response.should include(answers: {"Director of Public Affairs and Communication" => {"salary" => "$10,000", "benefits" => "Dental"}})
|
64
|
+
end
|
65
|
+
|
66
|
+
it "executes on « Is the iPhone 5s heavier than the Galaxy S4 »" do
|
67
|
+
stub_statements(:a0, :a3, :a4)
|
68
|
+
|
69
|
+
question = Akiva::Question.new("Is the iPhone 5s heavier than the Galaxy S4").run_filters.execute_action
|
70
|
+
question.response.should be_instance_of(Hash)
|
71
|
+
question.response.should include(subjects: ["iPhone 5s", "Galaxy S4"])
|
72
|
+
question.response.should include(properties: {"iPhone 5s" => ["weight"], "Galaxy S4" => ["weight"]})
|
73
|
+
question.response.should include(answers: {"iPhone 5s" => {"weight" => "112 grams"}, "Galaxy S4" => {"weight" => "130 grams"}})
|
74
|
+
question.response.should include(comparison_boolean_result: false)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Actions Preparator compare_two_subjects_properties_from_comparison_adjective" do
|
4
|
+
it "updates the response correctly" do
|
5
|
+
proc = Akiva::Brain.actions[:compare_two_subjects_properties_from_comparison_adjective]
|
6
|
+
response = {
|
7
|
+
filter_captures: {"comparison_adjective" => "heavier"},
|
8
|
+
answers: {"subject1" => {"property" => "112 grams"}, "subject2" => {"property" => "2 kg"}}
|
9
|
+
}
|
10
|
+
proc.call(response)
|
11
|
+
|
12
|
+
response.should include(comparison_boolean_result: false)
|
13
|
+
|
14
|
+
response = {
|
15
|
+
filter_captures: {"comparison_adjective" => "heavier"},
|
16
|
+
answers: {"subject1" => {"property" => "112 grams"}, "subject2" => {"property" => "111 g"}}
|
17
|
+
}
|
18
|
+
proc.call(response)
|
19
|
+
|
20
|
+
response.should include(comparison_boolean_result: true)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Actions Preparator extract_property_from_comparison_adjective" do
|
4
|
+
it "updates the response correctly" do
|
5
|
+
proc = Akiva::Brain.actions[:extract_property_from_comparison_adjective]
|
6
|
+
response = {filter_captures: {"comparison_adjective" => "heavier"}}
|
7
|
+
proc.call(response)
|
8
|
+
|
9
|
+
response.should include(defined_properties: ["weight"])
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Actions Preparator regroup_separated_subjects" do
|
4
|
+
it "updates the response correctly" do
|
5
|
+
proc = Akiva::Brain.actions[:regroup_separated_subjects]
|
6
|
+
response = {filter_captures: {"subject1" => "the iPhone 5s", "subject2" => "a Galaxy S4", "something_else" => "foobar"}}
|
7
|
+
proc.call(response)
|
8
|
+
|
9
|
+
response.should include(defined_subjects: ["iPhone 5s", "Galaxy S4"])
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Actions Preparator sort_answers_by_units" do
|
4
|
+
it "updates the response correctly" do
|
5
|
+
proc = Akiva::Brain.actions[:sort_answers_by_units]
|
6
|
+
response = {answers: {"subject1" => {"property" => "112 grams"}, "subject2" => {"property" => "2 kg"}, "subject3" => {"property" => "10 g"}}}
|
7
|
+
proc.call(response)
|
8
|
+
|
9
|
+
response.should include(sorted_answers_by_units: [
|
10
|
+
{
|
11
|
+
"subject3" => {
|
12
|
+
"property" => {
|
13
|
+
value: "10 g",
|
14
|
+
# value_with_adjusted_unit: nil
|
15
|
+
}
|
16
|
+
}
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"subject1" => {
|
20
|
+
"property" => {
|
21
|
+
value: "112 g",
|
22
|
+
# value_with_adjusted_unit: nil
|
23
|
+
}
|
24
|
+
}
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"subject2" => {
|
28
|
+
"property" => {
|
29
|
+
value: "2 kg",
|
30
|
+
# value_with_adjusted_unit: nil
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
])
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Filters" do
|
4
|
+
it "matches « What's the weight of an iPhone 5s »" do
|
5
|
+
question = Akiva::Question.new("What's the weight of an iPhone 5s").run_filters
|
6
|
+
question.filter_matched.should be_instance_of(Hash)
|
7
|
+
question.filter_matched.should include(action: :get_answers_from_subjects_and_properties)
|
8
|
+
question.filter_captures["subjects"].should == "iPhone 5s"
|
9
|
+
question.filter_captures["properties"].should == "weight"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "matches « What are the weight and height of an iPhone 5s »" do
|
13
|
+
question = Akiva::Question.new("What are the weight and height of an iPhone 5s").run_filters
|
14
|
+
question.filter_matched.should be_instance_of(Hash)
|
15
|
+
question.filter_matched.should include(action: :get_answers_from_subjects_and_properties)
|
16
|
+
question.filter_captures["subjects"].should == "iPhone 5s"
|
17
|
+
question.filter_captures["properties"].should == "weight and height"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "matches « What are the weight, height and width of an iPhone 5s »" do
|
21
|
+
question = Akiva::Question.new("What are the weight, height and width of an iPhone 5s").run_filters
|
22
|
+
question.filter_matched.should be_instance_of(Hash)
|
23
|
+
question.filter_matched.should include(action: :get_answers_from_subjects_and_properties)
|
24
|
+
question.filter_captures["subjects"].should == "iPhone 5s"
|
25
|
+
question.filter_captures["properties"].should == "weight, height and width"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "matches « What are the weight, height and width of the iPhone 5s and the Galaxy S4 »" do
|
29
|
+
question = Akiva::Question.new("What are the weight, height and width of the iPhone 5s and the Galaxy S4").run_filters
|
30
|
+
question.filter_matched.should be_instance_of(Hash)
|
31
|
+
question.filter_matched.should include(action: :get_answers_from_subjects_and_properties)
|
32
|
+
question.filter_captures["subjects"].should == "iPhone 5s and the Galaxy S4"
|
33
|
+
question.filter_captures["properties"].should == "weight, height and width"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "matches « Is the iPhone 5s heavier than the Galaxy S4 »" do
|
37
|
+
question = Akiva::Question.new("Is the iPhone 5s heavier than the Galaxy S4").run_filters
|
38
|
+
question.filter_matched.should be_instance_of(Hash)
|
39
|
+
question.filter_matched.should include(action: :get_answers_from_subjects_and_properties)
|
40
|
+
question.filter_captures["subject1"].should == "the iPhone 5s"
|
41
|
+
question.filter_captures["subject2"].should == "the Galaxy S4"
|
42
|
+
question.filter_captures["comparison_adjective"].should == "heavier"
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Formatter boolean_from_comparison" do
|
4
|
+
it "updates the response correctly" do
|
5
|
+
proc = Akiva::Brain.formatters[:boolean_from_comparison]
|
6
|
+
response = {
|
7
|
+
comparison_boolean_result: true
|
8
|
+
}
|
9
|
+
proc.call(response)
|
10
|
+
|
11
|
+
response[:formatted].should == "Yes"
|
12
|
+
|
13
|
+
response = {
|
14
|
+
comparison_boolean_result: false
|
15
|
+
}
|
16
|
+
proc.call(response)
|
17
|
+
|
18
|
+
response[:formatted].should == "No"
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
describe "with the action compare_two_subjects_properties_from_comparison_adjective among the list called" do
|
23
|
+
it "updates the response correctly" do
|
24
|
+
proc = Akiva::Brain.formatters[:boolean_from_comparison]
|
25
|
+
response = {
|
26
|
+
actions_chain: [:compare_two_subjects_properties_from_comparison_adjective],
|
27
|
+
comparison_boolean_result: false,
|
28
|
+
subjects: ["iPhone 5s", "Galaxy S4"],
|
29
|
+
properties: {"iPhone 5s" => ["weight"], "Galaxy S4" => ["weight"]},
|
30
|
+
answers: {"iPhone 5s" => {"weight" => "112 grams"}, "Galaxy S4" => {"weight" => "130 grams"}}
|
31
|
+
}
|
32
|
+
proc.call(response)
|
33
|
+
|
34
|
+
response[:formatted].should == "No (iPhone 5s => 112 grams; Galaxy S4 => 130 grams)"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Akiva CoreBrain Formatter list_all_answers" do
|
4
|
+
describe "with one subject and one property" do
|
5
|
+
it "updates the response correctly" do
|
6
|
+
proc = Akiva::Brain.formatters[:list_all_answers]
|
7
|
+
response = {
|
8
|
+
subjects: ["iPhone 5s"],
|
9
|
+
properties: {"iPhone 5s" => ["weight"]},
|
10
|
+
answers: {"iPhone 5s" => {"weight" => "112 grams"}}
|
11
|
+
}
|
12
|
+
proc.call(response)
|
13
|
+
|
14
|
+
response[:formatted].should == "112 grams"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "with one subject and multiple properties" do
|
19
|
+
it "updates the response correctly" do
|
20
|
+
proc = Akiva::Brain.formatters[:list_all_answers]
|
21
|
+
response = {
|
22
|
+
subjects: ["iPhone 5s"],
|
23
|
+
properties: {"iPhone 5s" => ["weight", "height"]},
|
24
|
+
answers: {"iPhone 5s" => {"weight" => "112 grams", "height" => "123.8 mm"}}
|
25
|
+
}
|
26
|
+
proc.call(response)
|
27
|
+
|
28
|
+
response[:formatted].should == "Weight: 112 grams, Height: 123.8 mm"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "with multiple subjects and one property" do
|
33
|
+
it "updates the response correctly" do
|
34
|
+
proc = Akiva::Brain.formatters[:list_all_answers]
|
35
|
+
response = {
|
36
|
+
subjects: ["iPhone 5s", "Galaxy S4"],
|
37
|
+
properties: {"iPhone 5s" => ["weight"], "Galaxy S4" => ["weight"]},
|
38
|
+
answers: {"iPhone 5s" => {"weight" => "112 grams"}, "Galaxy S4" => {"weight" => "130 grams"}}
|
39
|
+
}
|
40
|
+
proc.call(response)
|
41
|
+
|
42
|
+
response[:formatted].should == "iPhone 5s => 112 grams; Galaxy S4 => 130 grams"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "with multiple subjects and multiple properties" do
|
47
|
+
it "updates the response correctly" do
|
48
|
+
proc = Akiva::Brain.formatters[:list_all_answers]
|
49
|
+
response = {
|
50
|
+
subjects: ["iPhone 5s", "Galaxy S4"],
|
51
|
+
properties: {"iPhone 5s" => ["weight", "height"], "Galaxy S4" => ["weight", "height"]},
|
52
|
+
answers: {"iPhone 5s" => {"weight" => "112 grams", "height" => "123.8 mm"}, "Galaxy S4" => {"weight" => "130 grams", "height" => "136.6 mm"}}
|
53
|
+
}
|
54
|
+
proc.call(response)
|
55
|
+
|
56
|
+
response[:formatted].should == "iPhone 5s => Weight: 112 grams, Height: 123.8 mm; Galaxy S4 => Weight: 130 grams, Height: 136.6 mm"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|