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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +116 -0
  3. data/.gitignore +12 -0
  4. data/CHANGELOG.md +135 -0
  5. data/Gemfile +4 -1
  6. data/Gemfile.lock +65 -15
  7. data/LICENSE +6 -4
  8. data/README.md +51 -1
  9. data/VERSION +1 -0
  10. data/bin/xip +3 -11
  11. data/lib/xip.rb +1 -3
  12. data/lib/xip/base.rb +189 -0
  13. data/lib/xip/cli.rb +273 -0
  14. data/lib/xip/cli_base.rb +24 -0
  15. data/lib/xip/commands/command.rb +13 -0
  16. data/lib/xip/commands/console.rb +74 -0
  17. data/lib/xip/commands/server.rb +63 -0
  18. data/lib/xip/configuration.rb +56 -0
  19. data/lib/xip/controller/callbacks.rb +63 -0
  20. data/lib/xip/controller/catch_all.rb +84 -0
  21. data/lib/xip/controller/controller.rb +274 -0
  22. data/lib/xip/controller/dev_jumps.rb +40 -0
  23. data/lib/xip/controller/dynamic_delay.rb +61 -0
  24. data/lib/xip/controller/helpers.rb +128 -0
  25. data/lib/xip/controller/interrupt_detect.rb +99 -0
  26. data/lib/xip/controller/messages.rb +283 -0
  27. data/lib/xip/controller/nlp.rb +49 -0
  28. data/lib/xip/controller/replies.rb +281 -0
  29. data/lib/xip/controller/unrecognized_message.rb +61 -0
  30. data/lib/xip/core_ext.rb +5 -0
  31. data/lib/xip/core_ext/numeric.rb +10 -0
  32. data/lib/xip/core_ext/string.rb +18 -0
  33. data/lib/xip/dispatcher.rb +68 -0
  34. data/lib/xip/errors.rb +55 -0
  35. data/lib/xip/flow/base.rb +69 -0
  36. data/lib/xip/flow/specification.rb +56 -0
  37. data/lib/xip/flow/state.rb +82 -0
  38. data/lib/xip/generators/builder.rb +41 -0
  39. data/lib/xip/generators/builder/.gitignore +30 -0
  40. data/lib/xip/generators/builder/Gemfile +19 -0
  41. data/lib/xip/generators/builder/Procfile.dev +2 -0
  42. data/lib/xip/generators/builder/README.md +9 -0
  43. data/lib/xip/generators/builder/Rakefile +2 -0
  44. data/lib/xip/generators/builder/bot/controllers/bot_controller.rb +55 -0
  45. data/lib/xip/generators/builder/bot/controllers/catch_alls_controller.rb +21 -0
  46. data/lib/xip/generators/builder/bot/controllers/concerns/.keep +0 -0
  47. data/lib/xip/generators/builder/bot/controllers/goodbyes_controller.rb +9 -0
  48. data/lib/xip/generators/builder/bot/controllers/hellos_controller.rb +9 -0
  49. data/lib/xip/generators/builder/bot/controllers/interrupts_controller.rb +9 -0
  50. data/lib/xip/generators/builder/bot/controllers/unrecognized_messages_controller.rb +9 -0
  51. data/lib/xip/generators/builder/bot/helpers/bot_helper.rb +2 -0
  52. data/lib/xip/generators/builder/bot/models/bot_record.rb +3 -0
  53. data/lib/xip/generators/builder/bot/models/concerns/.keep +0 -0
  54. data/lib/xip/generators/builder/bot/replies/catch_alls/level1.yml +2 -0
  55. data/lib/xip/generators/builder/bot/replies/goodbyes/say_goodbye.yml +2 -0
  56. data/lib/xip/generators/builder/bot/replies/hellos/say_hello.yml +2 -0
  57. data/lib/xip/generators/builder/config.ru +4 -0
  58. data/lib/xip/generators/builder/config/boot.rb +6 -0
  59. data/lib/xip/generators/builder/config/database.yml +25 -0
  60. data/lib/xip/generators/builder/config/environment.rb +2 -0
  61. data/lib/xip/generators/builder/config/flow_map.rb +25 -0
  62. data/lib/xip/generators/builder/config/initializers/autoload.rb +8 -0
  63. data/lib/xip/generators/builder/config/initializers/inflections.rb +16 -0
  64. data/lib/xip/generators/builder/config/puma.rb +25 -0
  65. data/lib/xip/generators/builder/config/services.yml +35 -0
  66. data/lib/xip/generators/builder/config/sidekiq.yml +3 -0
  67. data/lib/xip/generators/builder/db/seeds.rb +7 -0
  68. data/lib/xip/generators/generate.rb +39 -0
  69. data/lib/xip/generators/generate/flow/controllers/controller.tt +7 -0
  70. data/lib/xip/generators/generate/flow/helpers/helper.tt +3 -0
  71. data/lib/xip/generators/generate/flow/replies/ask_example.tt +9 -0
  72. data/lib/xip/helpers/redis.rb +40 -0
  73. data/lib/xip/jobs.rb +9 -0
  74. data/lib/xip/lock.rb +82 -0
  75. data/lib/xip/logger.rb +9 -3
  76. data/lib/xip/migrations/configurator.rb +73 -0
  77. data/lib/xip/migrations/generators.rb +16 -0
  78. data/lib/xip/migrations/railtie_config.rb +14 -0
  79. data/lib/xip/migrations/tasks.rb +43 -0
  80. data/lib/xip/nlp/client.rb +21 -0
  81. data/lib/xip/nlp/result.rb +56 -0
  82. data/lib/xip/reloader.rb +89 -0
  83. data/lib/xip/reply.rb +36 -0
  84. data/lib/xip/scheduled_reply.rb +18 -0
  85. data/lib/xip/server.rb +63 -0
  86. data/lib/xip/service_message.rb +17 -0
  87. data/lib/xip/service_reply.rb +44 -0
  88. data/lib/xip/services/base_client.rb +24 -0
  89. data/lib/xip/services/base_message_handler.rb +27 -0
  90. data/lib/xip/services/base_reply_handler.rb +72 -0
  91. data/lib/xip/services/jobs/handle_message_job.rb +21 -0
  92. data/lib/xip/session.rb +203 -0
  93. data/lib/xip/version.rb +7 -1
  94. data/logo.svg +17 -0
  95. data/spec/configuration_spec.rb +93 -0
  96. data/spec/controller/callbacks_spec.rb +217 -0
  97. data/spec/controller/catch_all_spec.rb +154 -0
  98. data/spec/controller/controller_spec.rb +889 -0
  99. data/spec/controller/dynamic_delay_spec.rb +70 -0
  100. data/spec/controller/helpers_spec.rb +119 -0
  101. data/spec/controller/interrupt_detect_spec.rb +171 -0
  102. data/spec/controller/messages_spec.rb +744 -0
  103. data/spec/controller/nlp_spec.rb +93 -0
  104. data/spec/controller/replies_spec.rb +694 -0
  105. data/spec/controller/unrecognized_message_spec.rb +168 -0
  106. data/spec/dispatcher_spec.rb +79 -0
  107. data/spec/flow/flow_spec.rb +82 -0
  108. data/spec/flow/state_spec.rb +109 -0
  109. data/spec/helpers/redis_spec.rb +77 -0
  110. data/spec/lock_spec.rb +100 -0
  111. data/spec/nlp/client_spec.rb +23 -0
  112. data/spec/nlp/result_spec.rb +57 -0
  113. data/spec/replies/hello.yml.erb +15 -0
  114. data/spec/replies/messages/say_hola.yml+facebook.erb +6 -0
  115. data/spec/replies/messages/say_hola.yml+twilio.erb +6 -0
  116. data/spec/replies/messages/say_hola.yml.erb +6 -0
  117. data/spec/replies/messages/say_howdy_with_dynamic.yml +79 -0
  118. data/spec/replies/messages/say_msgs_without_breaks.yml +4 -0
  119. data/spec/replies/messages/say_offer.yml +6 -0
  120. data/spec/replies/messages/say_offer_with_dynamic.yml +6 -0
  121. data/spec/replies/messages/say_oi.yml.erb +15 -0
  122. data/spec/replies/messages/say_randomize_speech.yml +10 -0
  123. data/spec/replies/messages/say_randomize_text.yml +10 -0
  124. data/spec/replies/messages/say_yo.yml +6 -0
  125. data/spec/replies/messages/say_yo.yml+twitter +6 -0
  126. data/spec/replies/messages/sub1/sub2/say_nested.yml +10 -0
  127. data/spec/reply_spec.rb +61 -0
  128. data/spec/scheduled_reply_spec.rb +23 -0
  129. data/spec/service_reply_spec.rb +92 -0
  130. data/spec/session_spec.rb +366 -0
  131. data/spec/spec_helper.rb +22 -66
  132. data/spec/support/alternate_helpers/foo_helper.rb +5 -0
  133. data/spec/support/controllers/vaders_controller.rb +24 -0
  134. data/spec/support/helpers/fun/games_helper.rb +7 -0
  135. data/spec/support/helpers/fun/pdf_helper.rb +7 -0
  136. data/spec/support/helpers/standalone_helper.rb +5 -0
  137. data/spec/support/helpers_typo/users_helper.rb +2 -0
  138. data/spec/support/nlp_clients/dialogflow.rb +9 -0
  139. data/spec/support/nlp_clients/luis.rb +9 -0
  140. data/spec/support/nlp_results/luis_result.rb +163 -0
  141. data/spec/support/sample_messages.rb +66 -0
  142. data/spec/support/services.yml +31 -0
  143. data/spec/support/services_with_erb.yml +31 -0
  144. data/spec/version_spec.rb +16 -0
  145. data/xip.gemspec +25 -14
  146. metadata +320 -18
@@ -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,6 @@
1
+ - reply_type: text
2
+ text: "Hi, Facebook. 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."
@@ -0,0 +1,6 @@
1
+ - reply_type: text
2
+ text: "Hi, Twilio. 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."
@@ -0,0 +1,6 @@
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."
@@ -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,4 @@
1
+ - reply_type: text
2
+ text: "Hi, Morty. Welcome to Xip bot..."
3
+ - reply_type: text
4
+ text: "We offer users an awesome Ruby framework for building chat bots."
@@ -0,0 +1,6 @@
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."
@@ -0,0 +1,6 @@
1
+ - reply_type: text
2
+ text: "Hi, Morty. Welcome to Xip bot..."
3
+ - reply_type: delay
4
+ duration: dynamic
5
+ - reply_type: text
6
+ text: "We offer users an awesome Ruby framework for building chat bots."
@@ -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,6 @@
1
+ - reply_type: text
2
+ text: "Yo, 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."
@@ -0,0 +1,6 @@
1
+ - reply_type: text
2
+ text: "Yo, Morty from Twitter! 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."
@@ -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."
@@ -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