xip 0.0.1 → 2.0.0.beta2
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/.circleci/config.yml +116 -0
- data/.gitignore +12 -0
- data/CHANGELOG.md +135 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +65 -15
- data/LICENSE +6 -4
- data/README.md +51 -1
- data/VERSION +1 -0
- data/bin/xip +3 -11
- data/lib/xip.rb +1 -3
- data/lib/xip/base.rb +189 -0
- data/lib/xip/cli.rb +273 -0
- data/lib/xip/cli_base.rb +24 -0
- data/lib/xip/commands/command.rb +13 -0
- data/lib/xip/commands/console.rb +74 -0
- data/lib/xip/commands/server.rb +63 -0
- data/lib/xip/configuration.rb +56 -0
- data/lib/xip/controller/callbacks.rb +63 -0
- data/lib/xip/controller/catch_all.rb +84 -0
- data/lib/xip/controller/controller.rb +274 -0
- data/lib/xip/controller/dev_jumps.rb +40 -0
- data/lib/xip/controller/dynamic_delay.rb +61 -0
- data/lib/xip/controller/helpers.rb +128 -0
- data/lib/xip/controller/interrupt_detect.rb +99 -0
- data/lib/xip/controller/messages.rb +283 -0
- data/lib/xip/controller/nlp.rb +49 -0
- data/lib/xip/controller/replies.rb +281 -0
- data/lib/xip/controller/unrecognized_message.rb +61 -0
- data/lib/xip/core_ext.rb +5 -0
- data/lib/xip/core_ext/numeric.rb +10 -0
- data/lib/xip/core_ext/string.rb +18 -0
- data/lib/xip/dispatcher.rb +68 -0
- data/lib/xip/errors.rb +55 -0
- data/lib/xip/flow/base.rb +69 -0
- data/lib/xip/flow/specification.rb +56 -0
- data/lib/xip/flow/state.rb +82 -0
- data/lib/xip/generators/builder.rb +41 -0
- data/lib/xip/generators/builder/.gitignore +30 -0
- data/lib/xip/generators/builder/Gemfile +19 -0
- data/lib/xip/generators/builder/Procfile.dev +2 -0
- data/lib/xip/generators/builder/README.md +9 -0
- data/lib/xip/generators/builder/Rakefile +2 -0
- data/lib/xip/generators/builder/bot/controllers/bot_controller.rb +55 -0
- data/lib/xip/generators/builder/bot/controllers/catch_alls_controller.rb +21 -0
- data/lib/xip/generators/builder/bot/controllers/concerns/.keep +0 -0
- data/lib/xip/generators/builder/bot/controllers/goodbyes_controller.rb +9 -0
- data/lib/xip/generators/builder/bot/controllers/hellos_controller.rb +9 -0
- data/lib/xip/generators/builder/bot/controllers/interrupts_controller.rb +9 -0
- data/lib/xip/generators/builder/bot/controllers/unrecognized_messages_controller.rb +9 -0
- data/lib/xip/generators/builder/bot/helpers/bot_helper.rb +2 -0
- data/lib/xip/generators/builder/bot/models/bot_record.rb +3 -0
- data/lib/xip/generators/builder/bot/models/concerns/.keep +0 -0
- data/lib/xip/generators/builder/bot/replies/catch_alls/level1.yml +2 -0
- data/lib/xip/generators/builder/bot/replies/goodbyes/say_goodbye.yml +2 -0
- data/lib/xip/generators/builder/bot/replies/hellos/say_hello.yml +2 -0
- data/lib/xip/generators/builder/config.ru +4 -0
- data/lib/xip/generators/builder/config/boot.rb +6 -0
- data/lib/xip/generators/builder/config/database.yml +25 -0
- data/lib/xip/generators/builder/config/environment.rb +2 -0
- data/lib/xip/generators/builder/config/flow_map.rb +25 -0
- data/lib/xip/generators/builder/config/initializers/autoload.rb +8 -0
- data/lib/xip/generators/builder/config/initializers/inflections.rb +16 -0
- data/lib/xip/generators/builder/config/puma.rb +25 -0
- data/lib/xip/generators/builder/config/services.yml +35 -0
- data/lib/xip/generators/builder/config/sidekiq.yml +3 -0
- data/lib/xip/generators/builder/db/seeds.rb +7 -0
- data/lib/xip/generators/generate.rb +39 -0
- data/lib/xip/generators/generate/flow/controllers/controller.tt +7 -0
- data/lib/xip/generators/generate/flow/helpers/helper.tt +3 -0
- data/lib/xip/generators/generate/flow/replies/ask_example.tt +9 -0
- data/lib/xip/helpers/redis.rb +40 -0
- data/lib/xip/jobs.rb +9 -0
- data/lib/xip/lock.rb +82 -0
- data/lib/xip/logger.rb +9 -3
- data/lib/xip/migrations/configurator.rb +73 -0
- data/lib/xip/migrations/generators.rb +16 -0
- data/lib/xip/migrations/railtie_config.rb +14 -0
- data/lib/xip/migrations/tasks.rb +43 -0
- data/lib/xip/nlp/client.rb +21 -0
- data/lib/xip/nlp/result.rb +56 -0
- data/lib/xip/reloader.rb +89 -0
- data/lib/xip/reply.rb +36 -0
- data/lib/xip/scheduled_reply.rb +18 -0
- data/lib/xip/server.rb +63 -0
- data/lib/xip/service_message.rb +17 -0
- data/lib/xip/service_reply.rb +44 -0
- data/lib/xip/services/base_client.rb +24 -0
- data/lib/xip/services/base_message_handler.rb +27 -0
- data/lib/xip/services/base_reply_handler.rb +72 -0
- data/lib/xip/services/jobs/handle_message_job.rb +21 -0
- data/lib/xip/session.rb +203 -0
- data/lib/xip/version.rb +7 -1
- data/logo.svg +17 -0
- data/spec/configuration_spec.rb +93 -0
- data/spec/controller/callbacks_spec.rb +217 -0
- data/spec/controller/catch_all_spec.rb +154 -0
- data/spec/controller/controller_spec.rb +889 -0
- data/spec/controller/dynamic_delay_spec.rb +70 -0
- data/spec/controller/helpers_spec.rb +119 -0
- data/spec/controller/interrupt_detect_spec.rb +171 -0
- data/spec/controller/messages_spec.rb +744 -0
- data/spec/controller/nlp_spec.rb +93 -0
- data/spec/controller/replies_spec.rb +694 -0
- data/spec/controller/unrecognized_message_spec.rb +168 -0
- data/spec/dispatcher_spec.rb +79 -0
- data/spec/flow/flow_spec.rb +82 -0
- data/spec/flow/state_spec.rb +109 -0
- data/spec/helpers/redis_spec.rb +77 -0
- data/spec/lock_spec.rb +100 -0
- data/spec/nlp/client_spec.rb +23 -0
- data/spec/nlp/result_spec.rb +57 -0
- data/spec/replies/hello.yml.erb +15 -0
- data/spec/replies/messages/say_hola.yml+facebook.erb +6 -0
- data/spec/replies/messages/say_hola.yml+twilio.erb +6 -0
- data/spec/replies/messages/say_hola.yml.erb +6 -0
- data/spec/replies/messages/say_howdy_with_dynamic.yml +79 -0
- data/spec/replies/messages/say_msgs_without_breaks.yml +4 -0
- data/spec/replies/messages/say_offer.yml +6 -0
- data/spec/replies/messages/say_offer_with_dynamic.yml +6 -0
- data/spec/replies/messages/say_oi.yml.erb +15 -0
- data/spec/replies/messages/say_randomize_speech.yml +10 -0
- data/spec/replies/messages/say_randomize_text.yml +10 -0
- data/spec/replies/messages/say_yo.yml +6 -0
- data/spec/replies/messages/say_yo.yml+twitter +6 -0
- data/spec/replies/messages/sub1/sub2/say_nested.yml +10 -0
- data/spec/reply_spec.rb +61 -0
- data/spec/scheduled_reply_spec.rb +23 -0
- data/spec/service_reply_spec.rb +92 -0
- data/spec/session_spec.rb +366 -0
- data/spec/spec_helper.rb +22 -66
- data/spec/support/alternate_helpers/foo_helper.rb +5 -0
- data/spec/support/controllers/vaders_controller.rb +24 -0
- data/spec/support/helpers/fun/games_helper.rb +7 -0
- data/spec/support/helpers/fun/pdf_helper.rb +7 -0
- data/spec/support/helpers/standalone_helper.rb +5 -0
- data/spec/support/helpers_typo/users_helper.rb +2 -0
- data/spec/support/nlp_clients/dialogflow.rb +9 -0
- data/spec/support/nlp_clients/luis.rb +9 -0
- data/spec/support/nlp_results/luis_result.rb +163 -0
- data/spec/support/sample_messages.rb +66 -0
- data/spec/support/services.yml +31 -0
- data/spec/support/services_with_erb.yml +31 -0
- data/spec/version_spec.rb +16 -0
- data/xip.gemspec +25 -14
- metadata +320 -18
data/spec/lock_spec.rb
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe "Xip::Lock" do
|
|
6
|
+
let(:session_id) { SecureRandom.hex(14) }
|
|
7
|
+
let(:session_slug) { 'hello->say_hello' }
|
|
8
|
+
|
|
9
|
+
before(:each) do
|
|
10
|
+
Xip.config.lock_autorelease = 30
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "create" do
|
|
14
|
+
it "should raise an ArgumentError if the session_slug was not provided" do
|
|
15
|
+
lock = Xip::Lock.new(session_id: session_id)
|
|
16
|
+
expect {
|
|
17
|
+
lock.create
|
|
18
|
+
}.to raise_error(ArgumentError)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should save the lock using a canonical key and value" do
|
|
22
|
+
lock = Xip::Lock.new(session_id: session_id, session_slug: session_slug)
|
|
23
|
+
canonical_key = "#{session_id}-lock"
|
|
24
|
+
expected_value = "#{lock.tid}##{session_slug}"
|
|
25
|
+
lock.create
|
|
26
|
+
expect($redis.get(canonical_key)).to eq expected_value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should include the reply file position in the lock" do
|
|
30
|
+
lock = Xip::Lock.new(
|
|
31
|
+
session_id: session_id,
|
|
32
|
+
session_slug: session_slug,
|
|
33
|
+
position: 3
|
|
34
|
+
)
|
|
35
|
+
canonical_key = "#{session_id}-lock"
|
|
36
|
+
expected_value = "#{lock.tid}##{session_slug}:3"
|
|
37
|
+
lock.create
|
|
38
|
+
expect($redis.get(canonical_key)).to eq expected_value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should set the lock expiration to lock_autorelease" do
|
|
42
|
+
lock = Xip::Lock.new(session_id: session_id, session_slug: session_slug)
|
|
43
|
+
canonical_key = "#{session_id}-lock"
|
|
44
|
+
expected_value = "#{lock.tid}##{session_slug}"
|
|
45
|
+
lock.create
|
|
46
|
+
expect($redis.ttl(canonical_key)).to be_between(1, 30).inclusive
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "release" do
|
|
51
|
+
it "should delete the key in Redis" do
|
|
52
|
+
lock = Xip::Lock.new(session_id: session_id, session_slug: session_slug)
|
|
53
|
+
canonical_key = "#{session_id}-lock"
|
|
54
|
+
lock.create
|
|
55
|
+
expect($redis.get(canonical_key)).to_not be_nil
|
|
56
|
+
lock.release
|
|
57
|
+
expect($redis.get(canonical_key)).to be_nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe "slug" do
|
|
62
|
+
it "should return the lock slug from Redis" do
|
|
63
|
+
lock = Xip::Lock.new(session_id: session_id, session_slug: session_slug)
|
|
64
|
+
lock.create
|
|
65
|
+
canonical_key = "#{session_id}-lock"
|
|
66
|
+
expect(lock.slug).to eq "#{lock.tid}##{session_slug}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "flow_and_state" do
|
|
71
|
+
it "should return a hash containing the flow and state" do
|
|
72
|
+
lock = Xip::Lock.new(session_id: session_id, session_slug: session_slug)
|
|
73
|
+
expect(lock.flow_and_state[:flow]).to eq 'hello'
|
|
74
|
+
expect(lock.flow_and_state[:state]).to eq 'say_hello'
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe "self.find_lock" do
|
|
79
|
+
it "should load the lock from Redis" do
|
|
80
|
+
lock_key = "#{session_id}-lock"
|
|
81
|
+
example_tid = 'ovefhgJvx'
|
|
82
|
+
example_session = 'goodbye->say_goodbye'
|
|
83
|
+
example_position = 2
|
|
84
|
+
example_lock = "#{example_tid}##{example_session}:#{example_position}"
|
|
85
|
+
$redis.set(lock_key, example_lock)
|
|
86
|
+
|
|
87
|
+
lock = Xip::Lock.find_lock(session_id: session_id)
|
|
88
|
+
expect(lock.tid).to eq example_tid
|
|
89
|
+
expect(lock.session_slug).to eq example_session
|
|
90
|
+
expect(lock.position).to eq example_position
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should return nil if the lock is not found" do
|
|
94
|
+
lock_key = "#{session_id}-lock"
|
|
95
|
+
lock = Xip::Lock.find_lock(session_id: session_id)
|
|
96
|
+
expect($redis.get(lock_key)).to be_nil
|
|
97
|
+
expect(lock).to be_nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe "Xip::Nlp::Client" do
|
|
6
|
+
|
|
7
|
+
describe 'blank client' do
|
|
8
|
+
let(:nlp_client) { Xip::Nlp::Client.new }
|
|
9
|
+
|
|
10
|
+
it 'should return nil for client' do
|
|
11
|
+
expect(nlp_client.client).to be_nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should return nil for the understand call' do
|
|
15
|
+
expect(nlp_client.understand(query: 'hello world!')).to be_nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should return nil for the understand_speec call' do
|
|
19
|
+
expect(nlp_client.understand_speech(audio_file: 'https://path.to/audio.mp3')).to be_nil
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe "Xip::Nlp::Result" do
|
|
6
|
+
|
|
7
|
+
it 'should return the built-in entity types' do
|
|
8
|
+
expect(Xip::Nlp::Result::ENTITY_TYPES).to eq %i(number currency email percentage phone age
|
|
9
|
+
url ordinal geo dimension temp datetime duration
|
|
10
|
+
key_phrase name)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe 'blank result' do
|
|
14
|
+
let(:xip_result) { Xip::Nlp::Result.new(result: 1234) }
|
|
15
|
+
|
|
16
|
+
it 'should initialize @result to the value provided during instantiation' do
|
|
17
|
+
expect(xip_result.result).to eq 1234
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should return nil for parsed_result' do
|
|
21
|
+
expect(xip_result.parsed_result).to be_nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should return nil for intent_id' do
|
|
25
|
+
expect(xip_result.intent_id).to be_nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should return nil for intent' do
|
|
29
|
+
expect(xip_result.intent).to be_nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should return nil for intent_score' do
|
|
33
|
+
expect(xip_result.intent_score).to be_nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should return {} for raw_entities' do
|
|
37
|
+
expect(xip_result.raw_entities).to eq({})
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should return {} for entities' do
|
|
41
|
+
expect(xip_result.entities).to eq({})
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should return nil for sentiment' do
|
|
45
|
+
expect(xip_result.sentiment).to be_nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should return nil for sentiment_score' do
|
|
49
|
+
expect(xip_result.sentiment_score).to be_nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'should return false for present?' do
|
|
53
|
+
expect(xip_result.present?).to be false
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
- reply_type: text
|
|
2
|
+
text: "Hi, <%= first_name %>. Welcome to Xip bot..."
|
|
3
|
+
- reply_type: delay
|
|
4
|
+
duration: 2
|
|
5
|
+
- reply_type: text
|
|
6
|
+
text: "We offer users an awesome Ruby framework for building chat bots."
|
|
7
|
+
- reply_type: delay
|
|
8
|
+
duration: 2
|
|
9
|
+
- reply_type: text
|
|
10
|
+
text: "What do you think of our bot?"
|
|
11
|
+
buttons:
|
|
12
|
+
- text: "Cool"
|
|
13
|
+
payload: cool
|
|
14
|
+
- text: "Show me more"
|
|
15
|
+
payload: more
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
- reply_type: delay # position 0
|
|
2
|
+
duration: dynamic
|
|
3
|
+
- reply_type: text
|
|
4
|
+
text: "Lorem ipsum dolor sit amet posuere."
|
|
5
|
+
- reply_type: delay # position 2
|
|
6
|
+
duration: dynamic
|
|
7
|
+
- reply_type: text
|
|
8
|
+
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in lobortis ante. Duis elementum lacus sit amet volutpat."
|
|
9
|
+
- reply_type: delay # position 4
|
|
10
|
+
duration: dynamic
|
|
11
|
+
- reply_type: text
|
|
12
|
+
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer quis fermentum arcu, eget maximus metus. Vivamus ante tortor, scelerisque vel laoreet sit amet, sodales in augue. Nam vel quam a tellus mattis vestibulum non a amet."
|
|
13
|
+
buttons:
|
|
14
|
+
- text: "Cool"
|
|
15
|
+
payload: cool
|
|
16
|
+
- text: "Show me more"
|
|
17
|
+
payload: more
|
|
18
|
+
- reply_type: delay # position 6
|
|
19
|
+
duration: dynamic
|
|
20
|
+
- reply_type: text
|
|
21
|
+
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis consequat dolor. Suspendisse sed egestas lacus. Nam a viverra risus. Aliquam erat volutpat. Nunc molestie, metus ut cursus varius, purus quam pharetra nisi, sit amet porttitor tellus nisl sit amet est. Nam volutpat id lorem a condimentum. Sed quam mauris, faucibus sed pharetra sed."
|
|
22
|
+
- reply_type: delay # position 8
|
|
23
|
+
duration: dynamic
|
|
24
|
+
- reply_type: image
|
|
25
|
+
text: "https://via.placeholder.com/350x150"
|
|
26
|
+
- reply_type: delay # position 10
|
|
27
|
+
duration: dynamic
|
|
28
|
+
- reply_type: video
|
|
29
|
+
text: "https://via.placeholder.com/350x150"
|
|
30
|
+
- reply_type: delay # position 12
|
|
31
|
+
duration: dynamic
|
|
32
|
+
- reply_type: audio
|
|
33
|
+
text: "https://via.placeholder.com/350x150"
|
|
34
|
+
- reply_type: delay # position 14
|
|
35
|
+
duration: dynamic
|
|
36
|
+
- reply_type: file
|
|
37
|
+
text: "https://via.placeholder.com/350x150"
|
|
38
|
+
- reply_type: delay # position 16
|
|
39
|
+
duration: dynamic
|
|
40
|
+
- reply_type: cards
|
|
41
|
+
sharable: true
|
|
42
|
+
aspect_ratio: horizontal
|
|
43
|
+
elements:
|
|
44
|
+
- title: My App
|
|
45
|
+
subtitle: Download our app below or visit our website for more info.
|
|
46
|
+
image_url: "https://my-app.com/app-image.png"
|
|
47
|
+
buttons:
|
|
48
|
+
- type: url
|
|
49
|
+
url: "https://my-app.com"
|
|
50
|
+
text: 'View'
|
|
51
|
+
webview_height: 'tall'
|
|
52
|
+
- type: url
|
|
53
|
+
url: "https://itunes.apple.com/us/app/my-app"
|
|
54
|
+
text: 'Download iOS App'
|
|
55
|
+
- reply_type: delay # position 18
|
|
56
|
+
duration: dynamic
|
|
57
|
+
- reply_type: list
|
|
58
|
+
top_element_style: large
|
|
59
|
+
buttons:
|
|
60
|
+
- type: payload
|
|
61
|
+
text: View More
|
|
62
|
+
payload: view_more
|
|
63
|
+
elements:
|
|
64
|
+
- title: Your Daily News Update
|
|
65
|
+
subtitle: The following stories have been curated just for you.
|
|
66
|
+
image_url: "https://loremflickr.com/320/240"
|
|
67
|
+
buttons:
|
|
68
|
+
- type: url
|
|
69
|
+
url: "https://news-articles.com/199"
|
|
70
|
+
text: 'View'
|
|
71
|
+
webview_height: 'tall'
|
|
72
|
+
- title: Breakthrough in AI
|
|
73
|
+
subtitle: Major breakthrough in the AI space.
|
|
74
|
+
image_url: "https://loremflickr.com/320/320"
|
|
75
|
+
default_action:
|
|
76
|
+
- url: "https://news-articles.com/232"
|
|
77
|
+
webview_height: 'tall'
|
|
78
|
+
- reply_type: delay # position 20
|
|
79
|
+
duration: dynamic
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
- reply_type: text
|
|
2
|
+
text: "Hi, <%= @first_name %>. Welcome to Xip bot..."
|
|
3
|
+
- reply_type: delay
|
|
4
|
+
duration: 2
|
|
5
|
+
- reply_type: text
|
|
6
|
+
text: "We offer users an awesome Ruby framework for building chat bots."
|
|
7
|
+
- reply_type: delay
|
|
8
|
+
duration: 2
|
|
9
|
+
- reply_type: text
|
|
10
|
+
text: "What do you think of our bot?"
|
|
11
|
+
buttons:
|
|
12
|
+
- text: "Cool"
|
|
13
|
+
payload: cool
|
|
14
|
+
- text: "Show me more"
|
|
15
|
+
payload: more
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
- reply_type: speech
|
|
2
|
+
text:
|
|
3
|
+
- Build amazing chatbots with tools you know and love.
|
|
4
|
+
- Xip is an open source Ruby framework for voice and text chatbots.
|
|
5
|
+
- From our MVC architecture to our convention over configuration philosophy, you'll feel right at home with Xip.
|
|
6
|
+
- Every service integration in Xip is a Ruby gem.
|
|
7
|
+
- From web servers to continuous integration testing, Xip is built to take advantage of all the great work done by the web development community.
|
|
8
|
+
- Xip is a Rack application.
|
|
9
|
+
- Xip already powers bots for large, well-known brands.
|
|
10
|
+
- Xip is MIT licensed to ensure you own your bot.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
- reply_type: text
|
|
2
|
+
text:
|
|
3
|
+
- Build amazing chatbots with tools you know and love.
|
|
4
|
+
- Xip is an open source Ruby framework for voice and text chatbots.
|
|
5
|
+
- From our MVC architecture to our convention over configuration philosophy, you'll feel right at home with Xip.
|
|
6
|
+
- Every service integration in Xip is a Ruby gem.
|
|
7
|
+
- From web servers to continuous integration testing, Xip is built to take advantage of all the great work done by the web development community.
|
|
8
|
+
- Xip is a Rack application.
|
|
9
|
+
- Xip already powers bots for large, well-known brands.
|
|
10
|
+
- Xip is MIT licensed to ensure you own your bot.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
- reply_type: text
|
|
2
|
+
text: "Hi, Morty. Welcome to Xip bot..."
|
|
3
|
+
- reply_type: delay
|
|
4
|
+
duration: 2
|
|
5
|
+
- reply_type: text
|
|
6
|
+
text: "We offer users an awesome Ruby framework for building chat bots."
|
|
7
|
+
- reply_type: delay
|
|
8
|
+
duration: 2
|
|
9
|
+
- reply_type: text
|
|
10
|
+
text: "This reply was nested."
|
data/spec/reply_spec.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe "Xip::Reply" do
|
|
6
|
+
|
|
7
|
+
let!(:unstructured_text) {
|
|
8
|
+
{ 'reply_type' => 'text', 'text' => 'Hello World!' }
|
|
9
|
+
}
|
|
10
|
+
let!(:unstructured_delay) {
|
|
11
|
+
{ 'reply_type' => 'delay', 'duration' => 'dynamic' }
|
|
12
|
+
}
|
|
13
|
+
let(:text_reply) { Xip::Reply.new(unstructured_reply: unstructured_text) }
|
|
14
|
+
let(:delay_reply) { Xip::Reply.new(unstructured_reply: unstructured_delay) }
|
|
15
|
+
|
|
16
|
+
describe 'hash-like [] getter' do
|
|
17
|
+
it 'should return the values' do
|
|
18
|
+
expect(text_reply['text']).to eq 'Hello World!'
|
|
19
|
+
expect(delay_reply['duration']).to eq 'dynamic'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'hash-like []= setter' do
|
|
24
|
+
it 'should return the values' do
|
|
25
|
+
text_reply['woot'] = 'root'
|
|
26
|
+
delay_reply['duration'] = 4.3
|
|
27
|
+
expect(text_reply['woot']).to eq 'root'
|
|
28
|
+
expect(delay_reply['duration']).to eq 4.3
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe 'reply_type' do
|
|
33
|
+
it 'should act as a getter method for reply_type' do
|
|
34
|
+
expect(text_reply.reply_type).to eq 'text'
|
|
35
|
+
expect(delay_reply.reply_type).to eq 'delay'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe 'delay?' do
|
|
40
|
+
it 'should return false for a text reply' do
|
|
41
|
+
expect(text_reply.delay?).to be false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should return true for a delay reply' do
|
|
45
|
+
expect(delay_reply.delay?).to be true
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe 'self.dynamic_delay' do
|
|
50
|
+
it 'should return a new Xip::Reply' do
|
|
51
|
+
expect(Xip::Reply.dynamic_delay).to be_a(Xip::Reply)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should be a dynamic delay' do
|
|
55
|
+
expect(Xip::Reply.dynamic_delay.delay?).to be true
|
|
56
|
+
expect(Xip::Reply.dynamic_delay.reply_type).to eq 'delay'
|
|
57
|
+
expect(Xip::Reply.dynamic_delay['duration']).to eq 'dynamic'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|