stealth 1.0.0.pre1 → 1.0.0.pre2
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/Gemfile.lock +3 -3
- data/README.md +3 -0
- data/VERSION +1 -1
- data/lib/stealth/base.rb +3 -20
- data/lib/stealth/cli.rb +10 -16
- data/lib/stealth/commands/server.rb +33 -4
- data/lib/stealth/controller/controller.rb +14 -31
- data/lib/stealth/controller/helpers.rb +4 -1
- data/lib/stealth/flow/base.rb +28 -19
- data/lib/stealth/generators/builder/Gemfile +4 -0
- data/lib/stealth/generators/builder/bot/controllers/bot_controller.rb +3 -1
- data/lib/stealth/generators/builder/{bot/flow_map.rb.tt → config/flow_map.rb} +2 -2
- data/lib/stealth/generators/builder/readme.md +4 -4
- data/lib/stealth/generators/builder.rb +3 -0
- data/lib/stealth/generators/generate.rb +3 -0
- data/lib/stealth/logger.rb +37 -1
- data/lib/stealth/server.rb +0 -5
- data/lib/stealth/session.rb +3 -5
- data/spec/controller/callbacks_spec.rb +3 -7
- data/spec/controller/controller_spec.rb +256 -17
- data/spec/controller/helpers_spec.rb +26 -0
- data/spec/flow/flow_spec.rb +41 -20
- data/spec/flow/state_spec.rb +17 -20
- data/spec/session_spec.rb +14 -21
- data/stealth.gemspec +3 -3
- metadata +8 -7
@@ -5,7 +5,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', '/spec_helper')
|
|
5
5
|
|
6
6
|
describe "Stealth::Controller" do
|
7
7
|
|
8
|
-
class MrRobotsController <
|
8
|
+
class MrRobotsController < Stealth::Controller
|
9
9
|
def my_action
|
10
10
|
[:success, :my_action]
|
11
11
|
end
|
@@ -19,7 +19,7 @@ describe "Stealth::Controller" do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
class MrTronsController <
|
22
|
+
class MrTronsController < Stealth::Controller
|
23
23
|
def other_action
|
24
24
|
|
25
25
|
end
|
@@ -33,20 +33,16 @@ describe "Stealth::Controller" do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
class
|
36
|
+
class FlowMap
|
37
37
|
include Stealth::Flow
|
38
38
|
|
39
|
-
flow do
|
39
|
+
flow :mr_robot do
|
40
40
|
state :my_action
|
41
41
|
state :my_action2
|
42
42
|
state :my_action3
|
43
43
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class MrTronFlow
|
47
|
-
include Stealth::Flow
|
48
44
|
|
49
|
-
flow do
|
45
|
+
flow :mr_tron do
|
50
46
|
state :other_action
|
51
47
|
state :other_action2
|
52
48
|
state :other_action3
|
@@ -54,56 +50,299 @@ describe "Stealth::Controller" do
|
|
54
50
|
end
|
55
51
|
|
56
52
|
let(:facebook_message) { SampleMessage.new(service: 'facebook') }
|
53
|
+
let(:controller) { MrTronsController.new(service_message: facebook_message.message_with_text) }
|
57
54
|
|
58
55
|
describe "step_to" do
|
59
56
|
it "should raise an ArgumentError if a session, flow, or state is not specified" do
|
60
|
-
controller = MrTronsController.new(service_message: facebook_message.message_with_text)
|
61
57
|
expect {
|
62
58
|
controller.step_to
|
63
59
|
}.to raise_error(ArgumentError)
|
64
60
|
end
|
65
61
|
|
66
62
|
it "should call the flow's first state's controller action when only a flow is provided" do
|
67
|
-
|
63
|
+
expect_any_instance_of(MrRobotsController).to receive(:my_action)
|
64
|
+
controller.step_to flow: "mr_robot"
|
68
65
|
end
|
69
66
|
|
70
67
|
it "should call a controller's corresponding action when only a state is provided" do
|
68
|
+
expect_any_instance_of(MrTronsController).to receive(:other_action3)
|
69
|
+
|
70
|
+
controller.current_session.set(flow: 'mr_tron', state: 'other_action')
|
71
71
|
|
72
|
+
controller.step_to state: "other_action3"
|
72
73
|
end
|
73
74
|
|
74
75
|
it "should call a controller's corresponding action when a state and flow is provided" do
|
75
|
-
|
76
|
+
expect_any_instance_of(MrRobotsController).to receive(:my_action3)
|
77
|
+
controller.step_to flow: "mr_robot", state: "my_action3"
|
76
78
|
end
|
77
79
|
|
78
80
|
it "should call a controller's corresponding action when a session is provided" do
|
81
|
+
expect_any_instance_of(MrRobotsController).to receive(:my_action3)
|
79
82
|
|
83
|
+
allow(controller.current_session).to receive(:flow_string).and_return("mr_robot")
|
84
|
+
allow(controller.current_session).to receive(:state_string).and_return("my_action3")
|
85
|
+
|
86
|
+
controller.step_to session: controller.current_session
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should accept flow and string specified as symbols" do
|
90
|
+
expect_any_instance_of(MrRobotsController).to receive(:my_action3)
|
91
|
+
controller.step_to flow: :mr_robot, state: :my_action3
|
80
92
|
end
|
81
93
|
end
|
82
94
|
|
83
95
|
describe "update_session_to" do
|
84
96
|
it "should raise an ArgumentError if a session, flow, or state is not specified" do
|
85
|
-
controller = MrTronsController.new(service_message: facebook_message.message_with_text)
|
86
97
|
expect {
|
87
98
|
controller.update_session_to
|
88
99
|
}.to raise_error(ArgumentError)
|
89
100
|
end
|
101
|
+
|
102
|
+
it "should update session to flow's first state's controller action when only a flow is provided" do
|
103
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
104
|
+
|
105
|
+
controller.update_session_to flow: "mr_robot"
|
106
|
+
expect(controller.current_session.flow_string).to eq('mr_robot')
|
107
|
+
expect(controller.current_session.state_string).to eq('my_action')
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should update session to controller's corresponding action when only a state is provided" do
|
111
|
+
expect_any_instance_of(MrTronsController).to_not receive(:other_action3)
|
112
|
+
|
113
|
+
controller.current_session.set(flow: 'mr_tron', state: 'other_action')
|
114
|
+
|
115
|
+
controller.update_session_to state: "other_action3"
|
116
|
+
expect(controller.current_session.flow_string).to eq('mr_tron')
|
117
|
+
expect(controller.current_session.state_string).to eq('other_action3')
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should update session to controller's corresponding action when a state and flow is provided" do
|
121
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action3)
|
122
|
+
|
123
|
+
controller.update_session_to flow: "mr_robot", state: "my_action3"
|
124
|
+
expect(controller.current_session.flow_string).to eq('mr_robot')
|
125
|
+
expect(controller.current_session.state_string).to eq('my_action3')
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should update session to controller's corresponding action when a session is provided" do
|
129
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action3)
|
130
|
+
|
131
|
+
session = Stealth::Session.new(user_id: controller.current_user_id)
|
132
|
+
session.set(flow: 'mr_robot', state: 'my_action3')
|
133
|
+
|
134
|
+
controller.update_session_to session: session
|
135
|
+
expect(controller.current_session.flow_string).to eq('mr_robot')
|
136
|
+
expect(controller.current_session.state_string).to eq('my_action3')
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should accept flow and string specified as symbols" do
|
140
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action3)
|
141
|
+
|
142
|
+
controller.update_session_to flow: :mr_robot, state: :my_action3
|
143
|
+
expect(controller.current_session.flow_string).to eq('mr_robot')
|
144
|
+
expect(controller.current_session.state_string).to eq('my_action3')
|
145
|
+
end
|
90
146
|
end
|
91
147
|
|
92
148
|
describe "step_to_in" do
|
93
149
|
it "should raise an ArgumentError if a session, flow, or state is not specified" do
|
94
|
-
controller = MrTronsController.new(service_message: facebook_message.message_with_text)
|
95
150
|
expect {
|
96
151
|
controller.step_to_in
|
97
152
|
}.to raise_error(ArgumentError)
|
98
153
|
end
|
99
|
-
end
|
100
154
|
|
101
|
-
|
155
|
+
it "should raise an ArgumentError if delay is not specifed as an ActiveSupport::Duration" do
|
156
|
+
expect {
|
157
|
+
controller.step_to_in DateTime.now, flow: 'mr_robot'
|
158
|
+
}.to raise_error(ArgumentError)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should schedule a transition to flow's first state's controller action when only a flow is provided" do
|
162
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
163
|
+
|
164
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_in).with(
|
165
|
+
100.seconds,
|
166
|
+
controller.current_service,
|
167
|
+
controller.current_user_id,
|
168
|
+
'mr_robot',
|
169
|
+
'my_action'
|
170
|
+
)
|
171
|
+
|
172
|
+
expect {
|
173
|
+
controller.step_to_in 100.seconds, flow: "mr_robot"
|
174
|
+
}.to_not change(controller.current_session, :get)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should schedule a transition to controller's corresponding action when only a state is provided" do
|
178
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
179
|
+
|
180
|
+
controller.current_session.set(flow: 'mr_tron', state: 'other_action')
|
181
|
+
|
182
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_in).with(
|
183
|
+
100.seconds,
|
184
|
+
controller.current_service,
|
185
|
+
controller.current_user_id,
|
186
|
+
'mr_tron',
|
187
|
+
'other_action3'
|
188
|
+
)
|
189
|
+
|
190
|
+
expect {
|
191
|
+
controller.step_to_in 100.seconds, state: "other_action3"
|
192
|
+
}.to_not change(controller.current_session, :get)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should update session to controller's corresponding action when a state and flow is provided" do
|
196
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
197
|
+
|
198
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_in).with(
|
199
|
+
100.seconds,
|
200
|
+
controller.current_service,
|
201
|
+
controller.current_user_id,
|
202
|
+
'mr_robot',
|
203
|
+
'my_action3'
|
204
|
+
)
|
205
|
+
|
206
|
+
expect {
|
207
|
+
controller.step_to_in 100.seconds, flow: 'mr_robot', state: "my_action3"
|
208
|
+
}.to_not change(controller.current_session, :get)
|
209
|
+
end
|
102
210
|
|
211
|
+
it "should update session to controller's corresponding action when a session is provided" do
|
212
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
213
|
+
|
214
|
+
session = Stealth::Session.new(user_id: controller.current_user_id)
|
215
|
+
session.set(flow: 'mr_robot', state: 'my_action3')
|
216
|
+
|
217
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_in).with(
|
218
|
+
100.seconds,
|
219
|
+
controller.current_service,
|
220
|
+
controller.current_user_id,
|
221
|
+
'mr_robot',
|
222
|
+
'my_action3'
|
223
|
+
)
|
224
|
+
|
225
|
+
expect {
|
226
|
+
controller.step_to_in 100.seconds, session: session
|
227
|
+
}.to_not change(controller.current_session, :get)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should accept flow and string specified as symbols" do
|
231
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
232
|
+
|
233
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_in).with(
|
234
|
+
100.seconds,
|
235
|
+
controller.current_service,
|
236
|
+
controller.current_user_id,
|
237
|
+
'mr_robot',
|
238
|
+
'my_action3'
|
239
|
+
)
|
240
|
+
|
241
|
+
expect {
|
242
|
+
controller.step_to_in 100.seconds, flow: :mr_robot, state: :my_action3
|
243
|
+
}.to_not change(controller.current_session, :get)
|
244
|
+
end
|
103
245
|
end
|
104
246
|
|
105
|
-
describe "
|
247
|
+
describe "step_to_at" do
|
248
|
+
let(:future_timestamp) { DateTime.now + 10.hours }
|
106
249
|
|
250
|
+
it "should raise an ArgumentError if a session, flow, or state is not specified" do
|
251
|
+
expect {
|
252
|
+
controller.step_to_at
|
253
|
+
}.to raise_error(ArgumentError)
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should raise an ArgumentError if delay is not specifed as a DateTime" do
|
257
|
+
expect {
|
258
|
+
controller.step_to_at 100.seconds, flow: 'mr_robot'
|
259
|
+
}.to raise_error(ArgumentError)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should schedule a transition to flow's first state's controller action when only a flow is provided" do
|
263
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
264
|
+
|
265
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_at).with(
|
266
|
+
future_timestamp,
|
267
|
+
controller.current_service,
|
268
|
+
controller.current_user_id,
|
269
|
+
'mr_robot',
|
270
|
+
'my_action'
|
271
|
+
)
|
272
|
+
|
273
|
+
expect {
|
274
|
+
controller.step_to_at future_timestamp, flow: "mr_robot"
|
275
|
+
}.to_not change(controller.current_session, :get)
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should schedule a transition to controller's corresponding action when only a state is provided" do
|
279
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
280
|
+
|
281
|
+
controller.current_session.set(flow: 'mr_tron', state: 'other_action')
|
282
|
+
|
283
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_at).with(
|
284
|
+
future_timestamp,
|
285
|
+
controller.current_service,
|
286
|
+
controller.current_user_id,
|
287
|
+
'mr_tron',
|
288
|
+
'other_action3'
|
289
|
+
)
|
290
|
+
|
291
|
+
expect {
|
292
|
+
controller.step_to_at future_timestamp, state: "other_action3"
|
293
|
+
}.to_not change(controller.current_session, :get)
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should update session to controller's corresponding action when a state and flow is provided" do
|
297
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
298
|
+
|
299
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_at).with(
|
300
|
+
future_timestamp,
|
301
|
+
controller.current_service,
|
302
|
+
controller.current_user_id,
|
303
|
+
'mr_robot',
|
304
|
+
'my_action3'
|
305
|
+
)
|
306
|
+
|
307
|
+
expect {
|
308
|
+
controller.step_to_at future_timestamp, flow: 'mr_robot', state: "my_action3"
|
309
|
+
}.to_not change(controller.current_session, :get)
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should update session to controller's corresponding action when a session is provided" do
|
313
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
314
|
+
|
315
|
+
session = Stealth::Session.new(user_id: controller.current_user_id)
|
316
|
+
session.set(flow: 'mr_robot', state: 'my_action3')
|
317
|
+
|
318
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_at).with(
|
319
|
+
future_timestamp,
|
320
|
+
controller.current_service,
|
321
|
+
controller.current_user_id,
|
322
|
+
'mr_robot',
|
323
|
+
'my_action3'
|
324
|
+
)
|
325
|
+
|
326
|
+
expect {
|
327
|
+
controller.step_to_at future_timestamp, session: session
|
328
|
+
}.to_not change(controller.current_session, :get)
|
329
|
+
end
|
330
|
+
|
331
|
+
it "should accept flow and string specified as symbols" do
|
332
|
+
expect_any_instance_of(MrRobotsController).to_not receive(:my_action)
|
333
|
+
|
334
|
+
expect(Stealth::ScheduledReplyJob).to receive(:perform_at).with(
|
335
|
+
future_timestamp,
|
336
|
+
controller.current_service,
|
337
|
+
controller.current_user_id,
|
338
|
+
'mr_robot',
|
339
|
+
'my_action3'
|
340
|
+
)
|
341
|
+
|
342
|
+
expect {
|
343
|
+
controller.step_to_at future_timestamp, flow: :mr_robot, state: :my_action3
|
344
|
+
}.to_not change(controller.current_session, :get)
|
345
|
+
end
|
107
346
|
end
|
108
347
|
|
109
348
|
end
|
@@ -16,6 +16,10 @@ describe "Stealth::Controller helpers" do
|
|
16
16
|
def say_hello_world
|
17
17
|
hello_world
|
18
18
|
end
|
19
|
+
|
20
|
+
def say_kaboom
|
21
|
+
hello_world2
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
class PdfController < Stealth::Controller
|
@@ -33,6 +37,12 @@ describe "Stealth::Controller helpers" do
|
|
33
37
|
helper :all
|
34
38
|
end
|
35
39
|
|
40
|
+
class InheritedHelpersController < AllHelpersController
|
41
|
+
def say_hello_world
|
42
|
+
hello_world
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
36
46
|
class SizzleController < Stealth::Controller
|
37
47
|
helper :standalone
|
38
48
|
|
@@ -78,12 +88,28 @@ describe "Stealth::Controller helpers" do
|
|
78
88
|
expect(AllHelpersController._helpers.instance_methods).to match_array(all_helper_methods)
|
79
89
|
end
|
80
90
|
|
91
|
+
it "should load all helpers if parent class inherits all helpers" do
|
92
|
+
expect(InheritedHelpersController._helpers.instance_methods).to match_array(all_helper_methods)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should allow a controller that has inherited all helpers to access a helper method" do
|
96
|
+
expect {
|
97
|
+
InheritedHelpersController.new(service_message: facebook_message.message_with_text).say_hello_world
|
98
|
+
}.to_not raise_error
|
99
|
+
end
|
100
|
+
|
81
101
|
it "should allow a controller that has loaded all helpers to access a helper method" do
|
82
102
|
expect {
|
83
103
|
Fun::GamesController.new(service_message: facebook_message.message_with_text).say_hello_world
|
84
104
|
}.to_not raise_error
|
85
105
|
end
|
86
106
|
|
107
|
+
it "should raise an error if a helper method does not exist" do
|
108
|
+
expect {
|
109
|
+
Fun::GamesController.new(service_message: facebook_message.message_with_text).say_kaboom
|
110
|
+
}.to raise_error(NameError)
|
111
|
+
end
|
112
|
+
|
87
113
|
it "should allow a controller action to access a helper method" do
|
88
114
|
expect {
|
89
115
|
Fun::PdfController.new(service_message: facebook_message.message_with_text).say_pdf_name
|
data/spec/flow/flow_spec.rb
CHANGED
@@ -5,57 +5,78 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
5
5
|
|
6
6
|
describe Stealth::Flow do
|
7
7
|
|
8
|
-
class
|
8
|
+
class CustomFlowMap
|
9
9
|
include Stealth::Flow
|
10
10
|
|
11
|
-
flow do
|
11
|
+
flow :new_todo do
|
12
12
|
state :new
|
13
|
-
|
14
13
|
state :get_due_date
|
15
|
-
|
16
14
|
state :created
|
17
|
-
|
18
15
|
state :error
|
19
16
|
end
|
17
|
+
|
18
|
+
flow :hello do
|
19
|
+
state :say_hello
|
20
|
+
state :say_oi
|
21
|
+
end
|
22
|
+
|
23
|
+
flow "howdy" do
|
24
|
+
state :say_howdy
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
|
-
let(:
|
28
|
+
let(:flow_map) { CustomFlowMap.new }
|
23
29
|
|
24
30
|
describe "inititating with states" do
|
25
31
|
it "should init a state given a state name" do
|
26
|
-
|
27
|
-
expect(
|
32
|
+
flow_map.init(flow: 'new_todo', state: 'created')
|
33
|
+
expect(flow_map.current_state).to eq :created
|
28
34
|
|
29
|
-
|
30
|
-
expect(
|
35
|
+
flow_map.init(flow: 'new_todo', state: 'error')
|
36
|
+
expect(flow_map.current_state).to eq :error
|
31
37
|
end
|
32
38
|
|
33
39
|
it "should raise an error if an invalid state is specified" do
|
34
40
|
expect {
|
35
|
-
|
41
|
+
flow_map.init(flow: 'new_todo', state: 'invalid')
|
36
42
|
}.to raise_error(Stealth::Errors::InvalidStateTransition)
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
46
|
describe "accessing states" do
|
41
|
-
it "should
|
42
|
-
expect(
|
47
|
+
it "should default to the first flow and state" do
|
48
|
+
expect(flow_map.current_flow).to eq(:new_todo)
|
49
|
+
expect(flow_map.current_state).to eq(:new)
|
43
50
|
end
|
44
51
|
|
45
52
|
it "should support comparing states" do
|
46
|
-
first_state =
|
47
|
-
last_state =
|
53
|
+
first_state = CustomFlowMap.flow_spec[:new_todo].states[:new]
|
54
|
+
last_state = CustomFlowMap.flow_spec[:new_todo].states[:error]
|
48
55
|
expect(first_state < last_state).to be true
|
49
56
|
expect(last_state > first_state).to be true
|
50
57
|
end
|
51
58
|
|
52
|
-
it "should allow every state to be fetched for
|
53
|
-
expect(
|
54
|
-
expect(
|
59
|
+
it "should allow every state to be fetched for a flow" do
|
60
|
+
expect(CustomFlowMap.flow_spec[:new_todo].states.length).to eq 4
|
61
|
+
expect(CustomFlowMap.flow_spec[:hello].states.length).to eq 2
|
62
|
+
expect(CustomFlowMap.flow_spec[:new_todo].states.keys).to eq([:new, :get_due_date, :created, :error])
|
63
|
+
expect(CustomFlowMap.flow_spec[:hello].states.keys).to eq([:say_hello, :say_oi])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return the states in an array for a given FlowMap instance" do
|
67
|
+
expect(flow_map.states).to eq [:new, :get_due_date, :created, :error]
|
68
|
+
flow_map.init(flow: :hello, state: :say_oi)
|
69
|
+
expect(flow_map.states).to eq [:say_hello, :say_oi]
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should allow flows to be specified with strings" do
|
73
|
+
expect(CustomFlowMap.flow_spec[:howdy].states.length).to eq 1
|
74
|
+
expect(CustomFlowMap.flow_spec[:howdy].states.keys).to eq([:say_howdy])
|
55
75
|
end
|
56
76
|
|
57
|
-
it "should
|
58
|
-
|
77
|
+
it "should allow FlowMaps to be intialized with strings" do
|
78
|
+
flow_map.init(flow: "hello", state: "say_oi")
|
79
|
+
expect(flow_map.states).to eq [:say_hello, :say_oi]
|
59
80
|
end
|
60
81
|
end
|
61
82
|
|
data/spec/flow/state_spec.rb
CHANGED
@@ -5,66 +5,63 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
5
5
|
|
6
6
|
describe Stealth::Flow::State do
|
7
7
|
|
8
|
-
class
|
8
|
+
class SuperFlowMap
|
9
9
|
include Stealth::Flow
|
10
10
|
|
11
|
-
flow do
|
11
|
+
flow :new_todo do
|
12
12
|
state :new
|
13
|
-
|
14
13
|
state :get_due_date
|
15
|
-
|
16
14
|
state :created, fails_to: :new
|
17
|
-
|
18
15
|
state :error
|
19
16
|
end
|
20
17
|
end
|
21
18
|
|
22
|
-
let(:
|
19
|
+
let(:flow_map) { SuperFlowMap.new }
|
23
20
|
|
24
21
|
describe "flow states" do
|
25
22
|
it "should convert itself to a string" do
|
26
|
-
expect(
|
23
|
+
expect(flow_map.current_state.to_s).to be_a(String)
|
27
24
|
end
|
28
25
|
|
29
26
|
it "should convert itself to a symbol" do
|
30
|
-
expect(
|
27
|
+
expect(flow_map.current_state.to_sym).to be_a(Symbol)
|
31
28
|
end
|
32
29
|
end
|
33
30
|
|
34
31
|
describe "fails_to" do
|
35
32
|
it "should be nil for a state that has not specified a fails_to" do
|
36
|
-
expect(
|
33
|
+
expect(flow_map.current_state.fails_to).to be_nil
|
37
34
|
end
|
38
35
|
|
39
36
|
it "should return the fail_state if a fails_to was specified" do
|
40
|
-
|
41
|
-
expect(
|
42
|
-
expect(
|
37
|
+
flow_map.init(flow: :new_todo, state: :created)
|
38
|
+
expect(flow_map.current_state.fails_to).to be_a(Stealth::Flow::State)
|
39
|
+
expect(flow_map.current_state.fails_to).to eq :new
|
43
40
|
end
|
44
41
|
end
|
45
42
|
|
46
43
|
describe "state incrementing and decrementing" do
|
47
44
|
it "should increment the state" do
|
48
|
-
|
49
|
-
new_state =
|
45
|
+
flow_map.init(flow: :new_todo, state: :get_due_date)
|
46
|
+
new_state = flow_map.current_state + 1.state
|
50
47
|
expect(new_state).to eq(:created)
|
51
48
|
end
|
52
49
|
|
53
50
|
it "should decrement the state" do
|
54
|
-
|
55
|
-
new_state =
|
51
|
+
flow_map.init(flow: :new_todo, state: :error)
|
52
|
+
new_state = flow_map.current_state - 2.states
|
56
53
|
expect(new_state).to eq(:get_due_date)
|
57
54
|
end
|
58
55
|
|
59
56
|
it "should return the first state if the decrement is out of bounds" do
|
60
|
-
|
61
|
-
new_state =
|
57
|
+
flow_map.init(flow: :new_todo, state: :get_due_date)
|
58
|
+
new_state = flow_map.current_state - 5.states
|
62
59
|
expect(new_state).to eq(:new)
|
63
60
|
end
|
64
61
|
|
65
62
|
it "should return the last state if the increment is out of bounds" do
|
66
|
-
|
67
|
-
new_state =
|
63
|
+
flow_map.init(flow: :new_todo, state: :created)
|
64
|
+
new_state = flow_map.current_state + 5.states
|
68
65
|
expect(new_state).to eq(:error)
|
69
66
|
end
|
70
67
|
end
|
data/spec/session_spec.rb
CHANGED
@@ -3,18 +3,19 @@
|
|
3
3
|
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
5
5
|
|
6
|
-
class
|
6
|
+
class FlowMap
|
7
7
|
include Stealth::Flow
|
8
8
|
|
9
|
-
flow do
|
9
|
+
flow :new_todo do
|
10
10
|
state :new
|
11
|
-
|
12
11
|
state :get_due_date
|
13
|
-
|
14
12
|
state :created, fails_to: :new
|
15
|
-
|
16
13
|
state :error
|
17
14
|
end
|
15
|
+
|
16
|
+
flow :marco do
|
17
|
+
state :polo
|
18
|
+
end
|
18
19
|
end
|
19
20
|
|
20
21
|
describe "Stealth::Session" do
|
@@ -50,22 +51,14 @@ describe "Stealth::Session" do
|
|
50
51
|
end
|
51
52
|
|
52
53
|
describe "with a session" do
|
53
|
-
class MarcoFlow
|
54
|
-
include Stealth::Flow
|
55
|
-
|
56
|
-
flow do
|
57
|
-
state :polo
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
54
|
let(:session) do
|
62
55
|
session = Stealth::Session.new(user_id: user_id)
|
63
|
-
session.set(flow: '
|
56
|
+
session.set(flow: 'marco', state: 'polo')
|
64
57
|
session
|
65
58
|
end
|
66
59
|
|
67
|
-
it "should return the
|
68
|
-
expect(session.flow).to be_a(
|
60
|
+
it "should return the FlowMap" do
|
61
|
+
expect(session.flow).to be_a(FlowMap)
|
69
62
|
end
|
70
63
|
|
71
64
|
it "should return the state" do
|
@@ -74,7 +67,7 @@ describe "Stealth::Session" do
|
|
74
67
|
end
|
75
68
|
|
76
69
|
it "should return the flow_string" do
|
77
|
-
expect(session.flow_string).to eq "
|
70
|
+
expect(session.flow_string).to eq "marco"
|
78
71
|
end
|
79
72
|
|
80
73
|
it "should return the state_string" do
|
@@ -91,25 +84,25 @@ describe "Stealth::Session" do
|
|
91
84
|
let(:session) { Stealth::Session.new(user_id: user_id) }
|
92
85
|
|
93
86
|
it "should increment the state" do
|
94
|
-
session.set(flow: '
|
87
|
+
session.set(flow: 'new_todo', state: 'get_due_date')
|
95
88
|
new_session = session + 1.state
|
96
89
|
expect(new_session.state_string).to eq('created')
|
97
90
|
end
|
98
91
|
|
99
92
|
it "should decrement the state" do
|
100
|
-
session.set(flow: '
|
93
|
+
session.set(flow: 'new_todo', state: 'error')
|
101
94
|
new_session = session - 2.states
|
102
95
|
expect(new_session.state_string).to eq('get_due_date')
|
103
96
|
end
|
104
97
|
|
105
98
|
it "should return the first state if the decrement is out of bounds" do
|
106
|
-
session.set(flow: '
|
99
|
+
session.set(flow: 'new_todo', state: 'get_due_date')
|
107
100
|
new_session = session - 5.states
|
108
101
|
expect(new_session.state_string).to eq('new')
|
109
102
|
end
|
110
103
|
|
111
104
|
it "should return the last state if the increment is out of bounds" do
|
112
|
-
session.set(flow: '
|
105
|
+
session.set(flow: 'new_todo', state: 'created')
|
113
106
|
new_session = session + 5.states
|
114
107
|
expect(new_session.state_string).to eq('error')
|
115
108
|
end
|