spinach 0.1.4 → 0.1.5
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.
- data/.gitignore +1 -0
- data/.yardopts +6 -0
- data/Gemfile +1 -0
- data/Guardfile +7 -0
- data/Rakefile +1 -0
- data/Readme.md +147 -10
- data/features/{generate_features.feature → automatic_feature_generation.feature} +0 -0
- data/features/steps/automatic_feature_generation.rb +5 -2
- data/features/steps/exit_status.rb +8 -3
- data/features/steps/feature_name_guessing.rb +4 -1
- data/features/steps/reporting/display_run_summary.rb +7 -4
- data/features/steps/reporting/error_reporting.rb +7 -2
- data/features/steps/reporting/show_step_source_location.rb +9 -5
- data/features/steps/reporting/undefined_feature_reporting.rb +4 -1
- data/features/steps/rspec_compatibility.rb +6 -2
- data/features/support/spinach_runner.rb +2 -9
- data/lib/spinach/capybara.rb +3 -4
- data/lib/spinach/cli.rb +0 -1
- data/lib/spinach/config.rb +0 -8
- data/lib/spinach/dsl.rb +4 -13
- data/lib/spinach/exceptions.rb +1 -1
- data/lib/spinach/feature_steps.rb +1 -9
- data/lib/spinach/generators/feature_generator.rb +3 -2
- data/lib/spinach/generators.rb +1 -1
- data/lib/spinach/hookable.rb +81 -0
- data/lib/spinach/hooks.rb +132 -0
- data/lib/spinach/reporter/stdout/error_reporting.rb +163 -0
- data/lib/spinach/reporter/stdout.rb +3 -151
- data/lib/spinach/reporter.rb +39 -25
- data/lib/spinach/runner/{feature.rb → feature_runner.rb} +5 -15
- data/lib/spinach/runner/scenario_runner.rb +65 -0
- data/lib/spinach/runner.rb +5 -11
- data/lib/spinach/version.rb +1 -1
- data/lib/spinach.rb +20 -8
- data/spinach.gemspec +2 -3
- data/test/spinach/capybara_test.rb +4 -3
- data/test/spinach/cli_test.rb +0 -1
- data/test/spinach/feature_steps_test.rb +6 -23
- data/test/spinach/generators/feature_generator_test.rb +2 -2
- data/test/spinach/generators_test.rb +2 -2
- data/test/spinach/hookable_test.rb +59 -0
- data/test/spinach/hooks_test.rb +28 -0
- data/test/spinach/reporter/stdout/error_reporting_test.rb +265 -0
- data/test/spinach/reporter/stdout_test.rb +1 -238
- data/test/spinach/reporter_test.rb +58 -103
- data/test/spinach/runner/{feature_test.rb → feature_runner_test.rb} +21 -23
- data/test/spinach/runner/scenario_runner_test.rb +111 -0
- data/test/spinach/runner_test.rb +1 -1
- data/test/spinach_test.rb +19 -18
- data/test/test_helper.rb +1 -1
- metadata +60 -61
- data/lib/spinach/runner/scenario.rb +0 -77
- data/test/spinach/runner/scenario_test.rb +0 -120
@@ -0,0 +1,132 @@
|
|
1
|
+
require_relative 'hookable'
|
2
|
+
|
3
|
+
module Spinach
|
4
|
+
# Spinach's hooks is a subscription mechanism to allow developers to define
|
5
|
+
# certain callbacks given several Spinach signals, like running a feature,
|
6
|
+
# executing a particular step and such.
|
7
|
+
class Hooks
|
8
|
+
include Hookable
|
9
|
+
|
10
|
+
# Runs before the entire spinach run
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# Spinach.before_run do
|
14
|
+
# # Whatever
|
15
|
+
# end
|
16
|
+
hook :before_run
|
17
|
+
|
18
|
+
# Runs after the entire spinach run
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# Spinach.after_run do |status|
|
22
|
+
# # status is true when the run is successful, false otherwise
|
23
|
+
# end
|
24
|
+
hook :after_run
|
25
|
+
|
26
|
+
# Runs before every feature,
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# Spinach.before_feature do |feature_data|
|
30
|
+
# # feature_data is a hash of the parsed feature data
|
31
|
+
# end
|
32
|
+
hook :before_feature
|
33
|
+
|
34
|
+
# Runs after every feature
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# Spinach.after_feature do |feature_data|
|
38
|
+
# # feature_data is a hash of the parsed feature data
|
39
|
+
# end
|
40
|
+
hook :after_feature
|
41
|
+
|
42
|
+
# Runs when an undefined feature is found
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# Spinach.on_undefined_feature do |feature_data, exception|
|
46
|
+
# # feature_data is a hash of the parsed feature data
|
47
|
+
# # exception contains the thrown exception
|
48
|
+
# end
|
49
|
+
hook :on_undefined_feature
|
50
|
+
|
51
|
+
# Runs before every scenario
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# Spinach.before_scenario do |scenario_data|
|
55
|
+
# # feature_data is a hash of the parsed scenario data
|
56
|
+
# end
|
57
|
+
hook :before_scenario
|
58
|
+
|
59
|
+
# Runs after every scenario
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# Spinach.after_scenario do |scenario_data|
|
63
|
+
# # feature_data is a hash of the parsed scenario data
|
64
|
+
# end
|
65
|
+
hook :after_scenario
|
66
|
+
|
67
|
+
# Runs before every step execution
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# Spinach.before_step do |step_data|
|
71
|
+
# # step_data contains a hash with this step's data
|
72
|
+
# end
|
73
|
+
hook :before_step
|
74
|
+
|
75
|
+
# Runs after every step execution
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# Spinach.before_step do |step_data|
|
79
|
+
# # step_data contains a hash with this step's data
|
80
|
+
# end
|
81
|
+
hook :after_step
|
82
|
+
|
83
|
+
# Runs after every successful step execution
|
84
|
+
#
|
85
|
+
# @example
|
86
|
+
# Spinach.on_successful_step do |step_data, location|
|
87
|
+
# # step_data contains a hash with this step's data
|
88
|
+
# # step_location contains a string indication this step definition's
|
89
|
+
# # location
|
90
|
+
# end
|
91
|
+
hook :on_successful_step
|
92
|
+
|
93
|
+
# Runs after every failed step execution
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# Spinach.on_failed_step do |step_data, location|
|
97
|
+
# # step_data contains a hash with this step's data
|
98
|
+
# # step_location contains a string indication this step definition's
|
99
|
+
# # location
|
100
|
+
# end
|
101
|
+
hook :on_failed_step
|
102
|
+
|
103
|
+
# Runs after every step execution that raises an exception
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# Spinach.on_error_step do |step_data, location|
|
107
|
+
# # step_data contains a hash with this step's data
|
108
|
+
# # step_location contains a string indication this step definition's
|
109
|
+
# # location
|
110
|
+
# end
|
111
|
+
hook :on_error_step
|
112
|
+
|
113
|
+
# Runs every time a step which is not defined is called
|
114
|
+
#
|
115
|
+
# @example
|
116
|
+
# Spinach.on_undefined_step do |step_data, location|
|
117
|
+
# # step_data contains a hash with this step's data
|
118
|
+
# # step_location contains a string indication this step definition's
|
119
|
+
# # location
|
120
|
+
# end
|
121
|
+
hook :on_undefined_step
|
122
|
+
|
123
|
+
# Runs every time a step is skipped because there has been an unsuccessful
|
124
|
+
# one just before.
|
125
|
+
#
|
126
|
+
# @example
|
127
|
+
# Spinach.on_undefined_step do |step_data|
|
128
|
+
# # step_data contains a hash with this step's data
|
129
|
+
# end
|
130
|
+
hook :on_skipped_step
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Spinach
|
2
|
+
class Reporter
|
3
|
+
class Stdout < Reporter
|
4
|
+
# This module handles Stdout's reporter error reporting capabilities.
|
5
|
+
module ErrorReporting
|
6
|
+
|
7
|
+
# Prints the errors for this run.
|
8
|
+
#
|
9
|
+
def error_summary
|
10
|
+
error.puts "\nError summary:\n"
|
11
|
+
report_error_steps
|
12
|
+
report_failed_steps
|
13
|
+
report_undefined_features
|
14
|
+
report_undefined_steps
|
15
|
+
end
|
16
|
+
|
17
|
+
# Prints the steps that raised an error.
|
18
|
+
#
|
19
|
+
def report_error_steps
|
20
|
+
report_errors('Errors', error_steps, :light_red) if error_steps.any?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Prints failing steps.
|
24
|
+
#
|
25
|
+
def report_failed_steps
|
26
|
+
report_errors('Failures', failed_steps, :light_red) if failed_steps.any?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Prints undefined steps.
|
30
|
+
#
|
31
|
+
def report_undefined_steps
|
32
|
+
report_errors('Undefined steps', undefined_steps, :yellow) if undefined_steps.any?
|
33
|
+
end
|
34
|
+
|
35
|
+
def report_undefined_features
|
36
|
+
if undefined_features.any?
|
37
|
+
error.puts " Undefined features (#{undefined_features.length})".light_yellow
|
38
|
+
undefined_features.each do |feature|
|
39
|
+
error.puts " #{feature['name']}".yellow
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Prints the error for a given set of steps
|
45
|
+
#
|
46
|
+
# @param [String] banner
|
47
|
+
# the text to prepend as the title
|
48
|
+
#
|
49
|
+
# @param [Array] steps
|
50
|
+
# the steps to output
|
51
|
+
#
|
52
|
+
# @param [Symbol] color
|
53
|
+
# The color code to use with Colorize to colorize the output.
|
54
|
+
#
|
55
|
+
def report_errors(banner, steps, color)
|
56
|
+
error.puts " #{banner} (#{steps.length})".colorize(color)
|
57
|
+
steps.each do |error|
|
58
|
+
report_error error
|
59
|
+
end
|
60
|
+
error.puts ""
|
61
|
+
end
|
62
|
+
|
63
|
+
# Prints an error in a nice format
|
64
|
+
#
|
65
|
+
# @param [Array] error
|
66
|
+
# An array containing the feature, scenario, step and exception
|
67
|
+
#
|
68
|
+
# @param [Symbol] format
|
69
|
+
# The format to output the error. Currently supproted formats are
|
70
|
+
# :summarized (default) and :full
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
# The error report
|
74
|
+
#
|
75
|
+
def report_error(error, format=:summarized)
|
76
|
+
case format
|
77
|
+
when :summarized
|
78
|
+
self.error.puts summarized_error(error)
|
79
|
+
when :full
|
80
|
+
self.error.puts full_error(error)
|
81
|
+
else
|
82
|
+
raise "Format not defined"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns summarized error report
|
87
|
+
#
|
88
|
+
# @param [Array] error
|
89
|
+
# An array containing the feature, scenario, step and exception
|
90
|
+
#
|
91
|
+
# @return [String]
|
92
|
+
# The summarized error report
|
93
|
+
#
|
94
|
+
def summarized_error(error)
|
95
|
+
feature, scenario, step, exception = error
|
96
|
+
summary = " #{feature['name']} :: #{scenario['name']} :: #{full_step step}"
|
97
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
98
|
+
summary.yellow
|
99
|
+
else
|
100
|
+
summary.red
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns a complete error report
|
105
|
+
#
|
106
|
+
# @param [Array] error
|
107
|
+
# An array containing the feature, scenario, step and exception
|
108
|
+
#
|
109
|
+
# @return [String]
|
110
|
+
# The coplete error report
|
111
|
+
#
|
112
|
+
def full_error(error)
|
113
|
+
feature, scenario, step, exception = error
|
114
|
+
output = "\n"
|
115
|
+
output += report_exception(exception)
|
116
|
+
output +="\n"
|
117
|
+
|
118
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
119
|
+
output << "\n"
|
120
|
+
output << " You can define it with: \n\n".yellow
|
121
|
+
suggestion = Generators::StepGenerator.new(step).generate
|
122
|
+
suggestion.split("\n").each do |line|
|
123
|
+
output << " #{line}\n".yellow
|
124
|
+
end
|
125
|
+
output << "\n"
|
126
|
+
else
|
127
|
+
if options[:backtrace]
|
128
|
+
output += "\n"
|
129
|
+
exception.backtrace.map do |line|
|
130
|
+
output << " #{line}\n"
|
131
|
+
end
|
132
|
+
else
|
133
|
+
output << " #{exception.backtrace[0]}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
output
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# Prints a information when an exception is raised.
|
141
|
+
#
|
142
|
+
# @param [Exception] exception
|
143
|
+
# The exception to report
|
144
|
+
#
|
145
|
+
# @return [String]
|
146
|
+
# The exception report
|
147
|
+
#
|
148
|
+
def report_exception(exception)
|
149
|
+
output = exception.message.split("\n").map{ |line|
|
150
|
+
" #{line}"
|
151
|
+
}.join("\n")
|
152
|
+
|
153
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
154
|
+
output.yellow
|
155
|
+
else
|
156
|
+
output.red
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require_relative 'stdout/error_reporting'
|
2
3
|
|
3
4
|
module Spinach
|
4
5
|
class Reporter
|
@@ -6,6 +7,8 @@ module Spinach
|
|
6
7
|
#
|
7
8
|
class Stdout < Reporter
|
8
9
|
|
10
|
+
include ErrorReporting
|
11
|
+
|
9
12
|
# The output buffers to store the reports.
|
10
13
|
attr_reader :out, :error
|
11
14
|
|
@@ -191,138 +194,6 @@ module Spinach
|
|
191
194
|
out.puts "Steps Summary: #{successful_summary}, #{undefined_summary}, #{failed_summary}, #{error_summary}\n\n"
|
192
195
|
end
|
193
196
|
|
194
|
-
# Prints the errors for this run.
|
195
|
-
#
|
196
|
-
def error_summary
|
197
|
-
error.puts "\nError summary:\n"
|
198
|
-
report_error_steps
|
199
|
-
report_failed_steps
|
200
|
-
report_undefined_features
|
201
|
-
report_undefined_steps
|
202
|
-
end
|
203
|
-
|
204
|
-
# Prints the steps that raised an error.
|
205
|
-
#
|
206
|
-
def report_error_steps
|
207
|
-
report_errors('Errors', error_steps, :light_red) if error_steps.any?
|
208
|
-
end
|
209
|
-
|
210
|
-
# Prints failing steps.
|
211
|
-
#
|
212
|
-
def report_failed_steps
|
213
|
-
report_errors('Failures', failed_steps, :light_red) if failed_steps.any?
|
214
|
-
end
|
215
|
-
|
216
|
-
# Prints undefined steps.
|
217
|
-
#
|
218
|
-
def report_undefined_steps
|
219
|
-
report_errors('Undefined steps', undefined_steps, :yellow) if undefined_steps.any?
|
220
|
-
end
|
221
|
-
|
222
|
-
def report_undefined_features
|
223
|
-
if undefined_features.any?
|
224
|
-
error.puts " Undefined features (#{undefined_features.length})".light_yellow
|
225
|
-
undefined_features.each do |feature|
|
226
|
-
error.puts " #{feature['name']}".yellow
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
# Prints the error for a given set of steps
|
232
|
-
#
|
233
|
-
# @param [String] banner
|
234
|
-
# the text to prepend as the title
|
235
|
-
#
|
236
|
-
# @param [Array] steps
|
237
|
-
# the steps to output
|
238
|
-
#
|
239
|
-
# @param [Symbol] color
|
240
|
-
# The color code to use with Colorize to colorize the output.
|
241
|
-
#
|
242
|
-
def report_errors(banner, steps, color)
|
243
|
-
error.puts " #{banner} (#{steps.length})".colorize(color)
|
244
|
-
steps.each do |error|
|
245
|
-
report_error error
|
246
|
-
end
|
247
|
-
error.puts ""
|
248
|
-
end
|
249
|
-
|
250
|
-
# Prints an error in a nice format
|
251
|
-
#
|
252
|
-
# @param [Array] error
|
253
|
-
# An array containing the feature, scenario, step and exception
|
254
|
-
#
|
255
|
-
# @param [Symbol] format
|
256
|
-
# The format to output the error. Currently supproted formats are
|
257
|
-
# :summarized (default) and :full
|
258
|
-
#
|
259
|
-
# @returns [String]
|
260
|
-
# The error report
|
261
|
-
#
|
262
|
-
def report_error(error, format=:summarized)
|
263
|
-
case format
|
264
|
-
when :summarized
|
265
|
-
self.error.puts summarized_error(error)
|
266
|
-
when :full
|
267
|
-
self.error.puts full_error(error)
|
268
|
-
else
|
269
|
-
raise "Format not defined"
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
# Returns summarized error report
|
274
|
-
#
|
275
|
-
# @param [Array] error
|
276
|
-
# An array containing the feature, scenario, step and exception
|
277
|
-
#
|
278
|
-
# @returns [String]
|
279
|
-
# The summarized error report
|
280
|
-
#
|
281
|
-
def summarized_error(error)
|
282
|
-
feature, scenario, step, exception = error
|
283
|
-
summary = " #{feature['name']} :: #{scenario['name']} :: #{full_step step}"
|
284
|
-
if exception.kind_of?(Spinach::StepNotDefinedException)
|
285
|
-
summary.yellow
|
286
|
-
else
|
287
|
-
summary.red
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
# Returns a complete error report
|
292
|
-
#
|
293
|
-
# @param [Array] error
|
294
|
-
# An array containing the feature, scenario, step and exception
|
295
|
-
#
|
296
|
-
# @returns [String]
|
297
|
-
# The coplete error report
|
298
|
-
#
|
299
|
-
def full_error(error)
|
300
|
-
feature, scenario, step, exception = error
|
301
|
-
output = "\n"
|
302
|
-
output += report_exception(exception)
|
303
|
-
output +="\n"
|
304
|
-
|
305
|
-
if exception.kind_of?(Spinach::StepNotDefinedException)
|
306
|
-
output << "\n"
|
307
|
-
output << " You can define it with: \n\n".yellow
|
308
|
-
suggestion = Generators::StepGenerator.new(step).generate
|
309
|
-
suggestion.split("\n").each do |line|
|
310
|
-
output << " #{line}\n".yellow
|
311
|
-
end
|
312
|
-
output << "\n"
|
313
|
-
else
|
314
|
-
if options[:backtrace]
|
315
|
-
output += "\n"
|
316
|
-
exception.backtrace.map do |line|
|
317
|
-
output << " #{line}\n"
|
318
|
-
end
|
319
|
-
else
|
320
|
-
output << " #{exception.backtrace[0]}"
|
321
|
-
end
|
322
|
-
end
|
323
|
-
output
|
324
|
-
end
|
325
|
-
|
326
197
|
# Constructs the full step definition
|
327
198
|
#
|
328
199
|
# @param [Hash] step
|
@@ -332,25 +203,6 @@ module Spinach
|
|
332
203
|
"#{step['keyword'].strip} #{step['name'].strip}"
|
333
204
|
end
|
334
205
|
|
335
|
-
# Prints a information when an exception is raised.
|
336
|
-
#
|
337
|
-
# @param [Exception] exception
|
338
|
-
# The exception to report
|
339
|
-
#
|
340
|
-
# @returns [String]
|
341
|
-
# The exception report
|
342
|
-
#
|
343
|
-
def report_exception(exception)
|
344
|
-
output = exception.message.split("\n").map{ |line|
|
345
|
-
" #{line}"
|
346
|
-
}.join("\n")
|
347
|
-
|
348
|
-
if exception.kind_of?(Spinach::StepNotDefinedException)
|
349
|
-
output.yellow
|
350
|
-
else
|
351
|
-
output.red
|
352
|
-
end
|
353
|
-
end
|
354
206
|
end
|
355
207
|
end
|
356
208
|
end
|
data/lib/spinach/reporter.rb
CHANGED
@@ -19,35 +19,32 @@ module Spinach
|
|
19
19
|
|
20
20
|
# A Hash with options for the reporter
|
21
21
|
#
|
22
|
-
attr_reader :options
|
23
|
-
|
24
|
-
attr_accessor :current_feature, :current_scenario
|
22
|
+
attr_reader :options, :current_feature, :current_scenario
|
25
23
|
|
26
24
|
attr_reader :undefined_steps, :failed_steps, :error_steps, :undefined_features, :successful_steps
|
27
25
|
|
26
|
+
# Hooks the reporter to the runner endpoints
|
28
27
|
def bind
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
28
|
+
Spinach.hooks.tap do |hooks|
|
29
|
+
hooks.after_run { |*args| after_run(*args) }
|
30
|
+
hooks.before_feature { |*args| before_feature_run(*args) }
|
31
|
+
hooks.after_feature { |*args| after_feature_run(*args) }
|
32
|
+
hooks.on_undefined_feature { |*args| on_feature_not_found(*args) }
|
33
|
+
hooks.before_scenario { |*args| before_scenario_run(*args) }
|
34
|
+
hooks.after_scenario { |*args| after_scenario_run(*args) }
|
35
|
+
hooks.on_successful_step { |*args| on_successful_step(*args) }
|
36
|
+
hooks.on_undefined_step { |*args| on_undefined_step(*args) }
|
37
|
+
hooks.on_failed_step { |*args| on_failed_step(*args) }
|
38
|
+
hooks.on_error_step { |*args| on_error_step(*args) }
|
39
|
+
hooks.on_skipped_step { |*args| on_skipped_step(*args) }
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
hooks.before_feature { |*args| set_current_feature(*args) }
|
42
|
+
hooks.after_feature { |*args| clear_current_feature(*args) }
|
43
|
+
hooks.before_scenario { |*args| set_current_scenario(*args) }
|
44
|
+
hooks.after_scenario { |*args| clear_current_scenario(*args) }
|
45
|
+
end
|
45
46
|
end
|
46
47
|
|
47
|
-
def feature_runner; Runner::Feature; end
|
48
|
-
def scenario_runner; Runner::Scenario; end
|
49
|
-
def runner; Runner; end
|
50
|
-
|
51
48
|
def after_run(*args); end;
|
52
49
|
def before_feature_run(*args); end
|
53
50
|
def after_feature_run(*args); end
|
@@ -60,14 +57,31 @@ module Spinach
|
|
60
57
|
def on_undefined_step(*args); end;
|
61
58
|
def on_skipped_step(*args); end;
|
62
59
|
|
60
|
+
# Stores the current feature
|
61
|
+
#
|
62
|
+
# @param [Hash]
|
63
|
+
# the data for this feature
|
64
|
+
def set_current_feature(data)
|
65
|
+
@current_feature = data
|
66
|
+
end
|
67
|
+
|
68
|
+
# Clears this current feature
|
63
69
|
def clear_current_feature(*args)
|
64
|
-
|
70
|
+
@current_feature = nil
|
65
71
|
end
|
66
72
|
|
67
|
-
|
68
|
-
|
73
|
+
# Stores the current scenario
|
74
|
+
#
|
75
|
+
# @param [Hash]
|
76
|
+
# the data for this scenario
|
77
|
+
def set_current_scenario(data)
|
78
|
+
@current_scenario = data
|
69
79
|
end
|
70
80
|
|
81
|
+
# Clears this current scenario
|
82
|
+
def clear_current_scenario(*args)
|
83
|
+
@current_scenario = nil
|
84
|
+
end
|
71
85
|
end
|
72
86
|
end
|
73
87
|
|
@@ -1,22 +1,12 @@
|
|
1
|
-
require 'hooks'
|
2
|
-
|
3
1
|
module Spinach
|
4
2
|
class Runner
|
5
3
|
# A feature runner handles a particular feature run.
|
6
4
|
#
|
7
|
-
class
|
8
|
-
include Hooks
|
9
|
-
|
10
|
-
# The {Reporter} used in this feature.
|
11
|
-
attr_reader :reporter
|
5
|
+
class FeatureRunner
|
12
6
|
|
13
7
|
# The file that describes the feature.
|
14
8
|
attr_reader :filename
|
15
9
|
|
16
|
-
define_hook :before_run
|
17
|
-
define_hook :after_run
|
18
|
-
define_hook :when_not_found
|
19
|
-
|
20
10
|
# @param [String] filename
|
21
11
|
# path to the feature file. Scenario line could be passed to run just
|
22
12
|
# that scenario.
|
@@ -62,20 +52,20 @@ module Spinach
|
|
62
52
|
#
|
63
53
|
# @api public
|
64
54
|
def run
|
65
|
-
|
55
|
+
Spinach.hooks.run_before_feature data
|
66
56
|
|
67
57
|
scenarios.each do |scenario|
|
68
58
|
if !@scenario_line || scenario['line'].to_s == @scenario_line
|
69
|
-
success =
|
59
|
+
success = ScenarioRunner.new(feature_name, scenario).run
|
70
60
|
@failed = true unless success
|
71
61
|
end
|
72
62
|
end
|
73
63
|
|
74
64
|
rescue Spinach::FeatureStepsNotFoundException => e
|
75
|
-
|
65
|
+
Spinach.hooks.run_on_undefined_feature data, e
|
76
66
|
@failed = true
|
77
67
|
ensure
|
78
|
-
|
68
|
+
Spinach.hooks.run_after_feature data
|
79
69
|
return !@failed
|
80
70
|
end
|
81
71
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Spinach
|
2
|
+
class Runner
|
3
|
+
# A Scenario Runner handles a particular scenario run.
|
4
|
+
#
|
5
|
+
class ScenarioRunner
|
6
|
+
attr_reader :feature_name, :data
|
7
|
+
|
8
|
+
# @param [String] feature_name
|
9
|
+
# The feature name
|
10
|
+
#
|
11
|
+
# @param [Hash] data
|
12
|
+
# The parsed feature data.
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
def initialize(feature_name, data)
|
16
|
+
@feature_name = feature_name
|
17
|
+
@data = data
|
18
|
+
end
|
19
|
+
|
20
|
+
def steps
|
21
|
+
@steps ||= data['steps']
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [FeatureSteps]
|
25
|
+
# The feature object used to run this scenario.
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
def feature_steps
|
29
|
+
@feature_steps ||= Spinach.find_feature_steps(feature_name).new
|
30
|
+
end
|
31
|
+
|
32
|
+
# Runs this scenario
|
33
|
+
# @return [True, False]
|
34
|
+
# true if this scenario succeeded, false if not
|
35
|
+
def run
|
36
|
+
Spinach.hooks.run_before_scenario data
|
37
|
+
steps.each do |step|
|
38
|
+
Spinach.hooks.run_before_step step
|
39
|
+
unless @exception
|
40
|
+
begin
|
41
|
+
step_location = feature_steps.execute_step(step['name'])
|
42
|
+
Spinach.hooks.run_on_successful_step step, step_location
|
43
|
+
rescue Spinach::FeatureStepsNotFoundException => e
|
44
|
+
raise e
|
45
|
+
rescue *Spinach.config[:failure_exceptions] => e
|
46
|
+
@exception = e
|
47
|
+
Spinach.hooks.run_on_failed_step step, @exception, step_location
|
48
|
+
rescue Spinach::StepNotDefinedException => e
|
49
|
+
@exception = e
|
50
|
+
Spinach.hooks.run_on_undefined_step step, @exception
|
51
|
+
rescue Exception => e
|
52
|
+
@exception = e
|
53
|
+
Spinach.hooks.run_on_error_step step, @exception, step_location
|
54
|
+
end
|
55
|
+
else
|
56
|
+
Spinach.hooks.run_on_skipped_step step
|
57
|
+
end
|
58
|
+
Spinach.hooks.run_after_step step
|
59
|
+
end
|
60
|
+
Spinach.hooks.run_after_scenario data
|
61
|
+
!@exception
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|