stealth 1.0.0.pre1 → 1.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|