spinach 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -1
- data/features/{error_reporting.feature → reporting/error_reporting.feature} +0 -0
- data/features/reporting/show_step_source_location.feature +14 -0
- data/features/reporting/undefined_feature_reporting.feature +9 -0
- data/features/steps/{error_reporting.rb → reporting/error_reporting.rb} +0 -0
- data/features/steps/reporting/show_step_source_location.rb +57 -0
- data/features/steps/reporting/undefined_feature_reporting.rb +21 -0
- data/features/support/spinach_runner.rb +4 -1
- data/lib/spinach/dsl.rb +5 -1
- data/lib/spinach/exceptions.rb +3 -8
- data/lib/spinach/reporter/stdout.rb +58 -12
- data/lib/spinach/reporter.rb +5 -1
- data/lib/spinach/runner/feature.rb +4 -0
- data/lib/spinach/runner/scenario.rb +5 -5
- data/lib/spinach/version.rb +2 -2
- data/test/exceptions_test.rb +1 -14
- data/test/spinach/config_test.rb +13 -13
- data/test/spinach/dsl_test.rb +12 -1
- data/test/spinach/reporter/stdout_test.rb +67 -10
- data/test/spinach/reporter_test.rb +19 -2
- data/test/spinach/runner/feature_test.rb +14 -0
- metadata +47 -33
data/Gemfile
CHANGED
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Show step source location
|
2
|
+
As a developer
|
3
|
+
I want spinach to give me every step source location in output
|
4
|
+
So I can easyly know where I defined a step
|
5
|
+
|
6
|
+
Scenario: Show class steps source location in output
|
7
|
+
Given I have a feature that has no error or failure
|
8
|
+
When I run it
|
9
|
+
Then I should see the source location of each step of every scenario
|
10
|
+
|
11
|
+
Scenario: Show in output the source location of external modules steps
|
12
|
+
Given I have a feature that has no error or failure and use external steps
|
13
|
+
When I run it
|
14
|
+
Then I should see the source location of each step, even external ones
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: Undefined feature reporting
|
2
|
+
In order to be aware of what features I've still not defined
|
3
|
+
As a developer
|
4
|
+
I want spinach to tell me which of them I'm missing
|
5
|
+
|
6
|
+
Scenario: Undefined feature
|
7
|
+
Given I've written a feature but not its steps
|
8
|
+
When I run spinach
|
9
|
+
Then I should see a message telling me that there's an undefined feature
|
File without changes
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'aruba/api'
|
2
|
+
|
3
|
+
Feature "Show step source location" do
|
4
|
+
include Integration::SpinachRunner
|
5
|
+
|
6
|
+
Given "I have a feature that has no error or failure" do
|
7
|
+
write_file('features/success_feature.feature',
|
8
|
+
'Feature: A success feature
|
9
|
+
|
10
|
+
Scenario: This is scenario will succeed
|
11
|
+
Then I succeed
|
12
|
+
')
|
13
|
+
write_file('features/steps/success_feature.rb',
|
14
|
+
'Feature "A success feature" do
|
15
|
+
Then "I succeed" do
|
16
|
+
end
|
17
|
+
end')
|
18
|
+
@feature = "features/success_feature.feature"
|
19
|
+
end
|
20
|
+
|
21
|
+
When "I run it" do
|
22
|
+
run_feature @feature
|
23
|
+
end
|
24
|
+
|
25
|
+
Then "I should see the source location of each step of every scenario" do
|
26
|
+
all_stdout.must_match(
|
27
|
+
/I succeed.*features\/steps\/success_feature\.rb.*2/
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
Given "I have a feature that has no error or failure and use external steps" do
|
32
|
+
write_file('features/success_feature.feature',
|
33
|
+
'Feature: A feature that uses external steps
|
34
|
+
|
35
|
+
Scenario: This is scenario will succeed
|
36
|
+
Given this is a external step
|
37
|
+
')
|
38
|
+
write_file('features/steps/success_feature.rb',
|
39
|
+
'Feature "A feature that uses external steps" do
|
40
|
+
include ExternalSteps
|
41
|
+
end')
|
42
|
+
write_file('features/support/external_steps.rb',
|
43
|
+
'module ExternalSteps
|
44
|
+
include Spinach::DSL
|
45
|
+
Given "this is a external step" do
|
46
|
+
end
|
47
|
+
end')
|
48
|
+
@feature = "features/success_feature.feature"
|
49
|
+
end
|
50
|
+
|
51
|
+
Then "I should see the source location of each step, even external ones" do
|
52
|
+
all_stdout.must_match(
|
53
|
+
/this is a external step.*features\/support\/external_steps\.rb.*3/
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature "Undefined feature reporting" do
|
2
|
+
include Integration::SpinachRunner
|
3
|
+
|
4
|
+
Given "I've written a feature but not its steps" do
|
5
|
+
write_file('features/feature_without_steps.feature',
|
6
|
+
'Feature: Feature without steps
|
7
|
+
|
8
|
+
Scenario: A scenario without steps
|
9
|
+
Given I have no steps
|
10
|
+
Then I should do nothing
|
11
|
+
')
|
12
|
+
end
|
13
|
+
|
14
|
+
When "I run spinach" do
|
15
|
+
run_feature 'features/feature_without_steps.feature'
|
16
|
+
end
|
17
|
+
|
18
|
+
Then "I should see a message telling me that there's an undefined feature" do
|
19
|
+
all_stderr.must_match /Undefined features.*1/
|
20
|
+
end
|
21
|
+
end
|
data/lib/spinach/dsl.rb
CHANGED
@@ -47,7 +47,7 @@ module Spinach
|
|
47
47
|
#
|
48
48
|
# @api public
|
49
49
|
def Given(step, &block)
|
50
|
-
define_method(step, &block)
|
50
|
+
define_method(Spinach::Support.underscore(step), &block)
|
51
51
|
end
|
52
52
|
|
53
53
|
alias_method :When, :Given
|
@@ -84,11 +84,15 @@ module Spinach
|
|
84
84
|
#
|
85
85
|
# @api public
|
86
86
|
def execute_step(step)
|
87
|
+
step = Spinach::Support.underscore(step)
|
88
|
+
location = nil
|
87
89
|
if self.respond_to?(step)
|
90
|
+
location = method(step).source_location
|
88
91
|
self.send(step)
|
89
92
|
else
|
90
93
|
raise Spinach::StepNotDefinedException.new(self, step)
|
91
94
|
end
|
95
|
+
location
|
92
96
|
end
|
93
97
|
|
94
98
|
# @return [String]
|
data/lib/spinach/exceptions.rb
CHANGED
@@ -16,15 +16,10 @@ module Spinach
|
|
16
16
|
#
|
17
17
|
# @api public
|
18
18
|
def message
|
19
|
-
|
20
|
-
Please create the file #{Spinach::Support.underscore(@missing_class)}.rb
|
21
|
-
at #{Spinach.config[:step_definitions_path]}, with:}.gsub(/^\s{6,7}/, ''),
|
22
|
-
%Q{class #{@missing_class} << Spinach::FeatureSteps
|
23
|
-
#
|
24
|
-
# define your steps here
|
25
|
-
#
|
26
|
-
end}.gsub(/^\s{6,7}/, '')].join("\n\n").red
|
19
|
+
"Could not find steps for `#{@feature}` feature"
|
27
20
|
end
|
21
|
+
|
22
|
+
attr_reader :missing_class
|
28
23
|
end
|
29
24
|
|
30
25
|
# This class represents the exception raised when Spinach can't find a step
|
@@ -22,6 +22,7 @@ module Spinach
|
|
22
22
|
super(*args)
|
23
23
|
@out = options[:output] || $stdout
|
24
24
|
@error = options[:error] || $stderr
|
25
|
+
@max_step_name_length = 0
|
25
26
|
end
|
26
27
|
|
27
28
|
# Prints the feature name to the standard output
|
@@ -40,9 +41,9 @@ module Spinach
|
|
40
41
|
# The feature in a JSON Gherkin format
|
41
42
|
#
|
42
43
|
def before_scenario_run(data)
|
44
|
+
@max_step_name_length = data['steps'].map{|step| step['name'].length}.max if data['steps']
|
43
45
|
name = data['name']
|
44
46
|
out.puts "\n #{'Scenario:'.green} #{name.light_green}"
|
45
|
-
out.puts
|
46
47
|
end
|
47
48
|
|
48
49
|
# Adds an error report and re
|
@@ -62,8 +63,8 @@ module Spinach
|
|
62
63
|
# @param [Hash] step
|
63
64
|
# The step in a JSON Gherkin format
|
64
65
|
#
|
65
|
-
def on_successful_step(step)
|
66
|
-
output_step('✔', step, :green)
|
66
|
+
def on_successful_step(step, step_location)
|
67
|
+
output_step('✔', step, :green, step_location)
|
67
68
|
end
|
68
69
|
|
69
70
|
# Adds a failing step to the output buffer.
|
@@ -74,8 +75,8 @@ module Spinach
|
|
74
75
|
# @param [Exception] failure
|
75
76
|
# The exception that caused the failure
|
76
77
|
#
|
77
|
-
def on_failed_step(step, failure)
|
78
|
-
output_step('✘', step, :red)
|
78
|
+
def on_failed_step(step, failure, step_location)
|
79
|
+
output_step('✘', step, :red, step_location)
|
79
80
|
self.scenario_error = [current_feature, current_scenario, step, failure]
|
80
81
|
failed_steps << scenario_error
|
81
82
|
end
|
@@ -88,8 +89,8 @@ module Spinach
|
|
88
89
|
# @param [Exception] failure
|
89
90
|
# The exception that caused the failure
|
90
91
|
#
|
91
|
-
def on_error_step(step, failure)
|
92
|
-
output_step('!', step, :red)
|
92
|
+
def on_error_step(step, failure, step_location)
|
93
|
+
output_step('!', step, :red, step_location)
|
93
94
|
self.scenario_error = [current_feature, current_scenario, step, failure]
|
94
95
|
error_steps << scenario_error
|
95
96
|
end
|
@@ -99,12 +100,41 @@ module Spinach
|
|
99
100
|
# @param [Hash] step
|
100
101
|
# The step in a JSON Gherkin format
|
101
102
|
#
|
102
|
-
def on_undefined_step(step)
|
103
|
+
def on_undefined_step(step, failure)
|
103
104
|
output_step('?', step, :yellow)
|
104
105
|
self.scenario_error = [current_feature, current_scenario, step]
|
105
106
|
undefined_steps << scenario_error
|
106
107
|
end
|
107
108
|
|
109
|
+
# Adds a feature not found message to the output buffer.
|
110
|
+
#
|
111
|
+
# @param [Hash] feature
|
112
|
+
# the feature in a json gherkin format
|
113
|
+
#
|
114
|
+
# @param [Spinach::FeatureNotFoundException] exception
|
115
|
+
# the related exception
|
116
|
+
#
|
117
|
+
def on_feature_not_found(feature, exception)
|
118
|
+
lines = "#{exception.message}\n"
|
119
|
+
|
120
|
+
lines << "\nPlease create the file #{Spinach::Support.underscore(exception.missing_class)}.rb at #{Spinach.config[:step_definitions_path]}, with:\n\n"
|
121
|
+
|
122
|
+
lines << "Feature '#{feature['name']}' do\n"
|
123
|
+
|
124
|
+
# TODO: Write the actual steps. We can do this since we have the entire
|
125
|
+
# feature just here. We should iterate over all the scenarios and return
|
126
|
+
# the different steps
|
127
|
+
#
|
128
|
+
lines << " # Write your steps here"
|
129
|
+
lines << "end\n\n"
|
130
|
+
|
131
|
+
lines.split("\n").each do |line|
|
132
|
+
out.puts " #{line}".yellow
|
133
|
+
end
|
134
|
+
|
135
|
+
undefined_features << feature
|
136
|
+
end
|
137
|
+
|
108
138
|
# Adds a step that has been skipped to the output buffer.
|
109
139
|
#
|
110
140
|
# @param [Hash] step
|
@@ -126,8 +156,14 @@ module Spinach
|
|
126
156
|
# @param [Symbol] color
|
127
157
|
# The color code to use with Colorize to colorize the output.
|
128
158
|
#
|
129
|
-
|
130
|
-
|
159
|
+
# @param [Array] step_location
|
160
|
+
# step source location and file line
|
161
|
+
#
|
162
|
+
def output_step(symbol, step, color, step_location = nil)
|
163
|
+
step_location = step_location.first.gsub("#{File.expand_path('.')}/", '# ')+":#{step_location.last.to_s}" if step_location
|
164
|
+
max_length = @max_step_name_length + 60 # Colorize and output format correction
|
165
|
+
# REMEMBER TO CORRECT PREVIOUS MAX LENGTH IF OUTPUT FORMAT IS MODIFIED
|
166
|
+
out.puts " #{symbol.colorize(:"light_#{color}")} #{step['keyword'].strip.colorize(:"light_#{color}")} #{step['name'].strip.colorize(color)} ".ljust(max_length) + step_location.to_s.colorize(:grey)
|
131
167
|
end
|
132
168
|
|
133
169
|
# It prints the error summary if the run has failed
|
@@ -145,6 +181,7 @@ module Spinach
|
|
145
181
|
error.puts "\nError summary:\n"
|
146
182
|
report_error_steps
|
147
183
|
report_failed_steps
|
184
|
+
report_undefined_features
|
148
185
|
report_undefined_steps
|
149
186
|
end
|
150
187
|
|
@@ -166,6 +203,15 @@ module Spinach
|
|
166
203
|
report_errors('Undefined steps', undefined_steps, :yellow) if undefined_steps.any?
|
167
204
|
end
|
168
205
|
|
206
|
+
def report_undefined_features
|
207
|
+
if undefined_features.any?
|
208
|
+
error.puts " Undefined features (#{undefined_features.length})".light_yellow
|
209
|
+
undefined_features.each do |feature|
|
210
|
+
error.puts " #{feature['name']}".yellow
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
169
215
|
# Prints the error for a given set of steps
|
170
216
|
#
|
171
217
|
# @param [String] banner
|
@@ -178,7 +224,7 @@ module Spinach
|
|
178
224
|
# The color code to use with Colorize to colorize the output.
|
179
225
|
#
|
180
226
|
def report_errors(banner, steps, color)
|
181
|
-
error.puts "#{banner} (#{steps.length})".colorize(color)
|
227
|
+
error.puts " #{banner} (#{steps.length})".colorize(color)
|
182
228
|
steps.each do |error|
|
183
229
|
report_error error
|
184
230
|
end
|
@@ -218,7 +264,7 @@ module Spinach
|
|
218
264
|
#
|
219
265
|
def summarized_error(error)
|
220
266
|
feature, scenario, step, exception = error
|
221
|
-
summary = "
|
267
|
+
summary = " #{feature['name']} :: #{scenario['name']} :: #{full_step step}"
|
222
268
|
if exception.kind_of?(Spinach::StepNotDefinedException)
|
223
269
|
summary.yellow
|
224
270
|
else
|
data/lib/spinach/reporter.rb
CHANGED
@@ -10,6 +10,7 @@ module Spinach
|
|
10
10
|
def initialize(options = {})
|
11
11
|
@errors = []
|
12
12
|
@options = options
|
13
|
+
@undefined_features = []
|
13
14
|
@undefined_steps = []
|
14
15
|
@failed_steps = []
|
15
16
|
@error_steps = []
|
@@ -21,15 +22,17 @@ module Spinach
|
|
21
22
|
|
22
23
|
attr_accessor :current_feature, :current_scenario
|
23
24
|
|
24
|
-
attr_reader :undefined_steps, :failed_steps, :error_steps
|
25
|
+
attr_reader :undefined_steps, :failed_steps, :error_steps, :undefined_features
|
25
26
|
|
26
27
|
def bind
|
27
28
|
runner.after_run method(:after_run)
|
28
29
|
feature_runner.before_run method(:before_feature_run)
|
29
30
|
feature_runner.after_run method(:after_feature_run)
|
31
|
+
feature_runner.when_not_found method(:on_feature_not_found)
|
30
32
|
scenario_runner.before_run method(:before_scenario_run)
|
31
33
|
scenario_runner.after_run method(:after_scenario_run)
|
32
34
|
scenario_runner.on_successful_step method(:on_successful_step)
|
35
|
+
scenario_runner.on_undefined_step method(:on_undefined_step)
|
33
36
|
scenario_runner.on_failed_step method(:on_failed_step)
|
34
37
|
scenario_runner.on_error_step method(:on_error_step)
|
35
38
|
scenario_runner.on_skipped_step method(:on_skipped_step)
|
@@ -47,6 +50,7 @@ module Spinach
|
|
47
50
|
def after_run(*args); end;
|
48
51
|
def before_feature_run(*args); end
|
49
52
|
def after_feature_run(*args); end
|
53
|
+
def on_feature_not_found(*args); end
|
50
54
|
def before_scenario_run(*args); end
|
51
55
|
def after_scenario_run(*args); end
|
52
56
|
def on_successful_step(*args); end;
|
@@ -15,6 +15,7 @@ module Spinach
|
|
15
15
|
|
16
16
|
define_hook :before_run
|
17
17
|
define_hook :after_run
|
18
|
+
define_hook :when_not_found
|
18
19
|
|
19
20
|
# @param [String] filename
|
20
21
|
# path to the feature file. Scenario line could be passed to run just
|
@@ -81,6 +82,9 @@ module Spinach
|
|
81
82
|
feature.run_hook :after, data
|
82
83
|
run_hook :after_run, data
|
83
84
|
|
85
|
+
rescue Spinach::FeatureStepsNotFoundException => e
|
86
|
+
run_hook :when_not_found, data, e
|
87
|
+
ensure
|
84
88
|
return !!@success
|
85
89
|
end
|
86
90
|
end
|
@@ -44,17 +44,17 @@ module Spinach
|
|
44
44
|
feature.run_hook :before_step, step
|
45
45
|
unless @exception
|
46
46
|
begin
|
47
|
-
feature.execute_step(step['name'])
|
48
|
-
run_hook :on_successful_step, step
|
47
|
+
step_location = feature.execute_step(step['name'])
|
48
|
+
run_hook :on_successful_step, step, step_location
|
49
49
|
rescue *Spinach.config[:failure_exceptions] => e
|
50
50
|
@exception = e
|
51
|
-
run_hook :on_failed_step, step, @exception
|
51
|
+
run_hook :on_failed_step, step, @exception, step_location
|
52
52
|
rescue Spinach::StepNotDefinedException => e
|
53
53
|
@exception = e
|
54
54
|
run_hook :on_undefined_step, step, @exception
|
55
|
-
rescue
|
55
|
+
rescue Exception => e
|
56
56
|
@exception = e
|
57
|
-
run_hook :on_error_step, step, @exception
|
57
|
+
run_hook :on_error_step, step, @exception, step_location
|
58
58
|
end
|
59
59
|
else
|
60
60
|
run_hook :on_skipped_step, step
|
data/lib/spinach/version.rb
CHANGED
data/test/exceptions_test.rb
CHANGED
@@ -7,20 +7,7 @@ describe Spinach::FeatureStepsNotFoundException do
|
|
7
7
|
|
8
8
|
describe 'message' do
|
9
9
|
it 'tells the user that the steps could not be found' do
|
10
|
-
subject.message.must_include 'Could not find steps for `This feature does not exist` feature
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'tells the user to create the file' do
|
14
|
-
subject.message.must_include 'Please create the file this_feature_does_not_exist.rb'
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'tells the user where to create the file respecting the step definitions path' do
|
18
|
-
Spinach.config.stubs(:step_definitions_path).returns('my/path')
|
19
|
-
subject.message.must_include 'at my/path, with:'
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'tells the user what to write in the file' do
|
23
|
-
subject.message.must_include 'class ThisFeatureDoesNotExist << Spinach::FeatureSteps'
|
10
|
+
subject.message.must_include 'Could not find steps for `This feature does not exist` feature'
|
24
11
|
end
|
25
12
|
end
|
26
13
|
end
|
data/test/spinach/config_test.rb
CHANGED
@@ -1,45 +1,45 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
2
|
|
3
3
|
describe Spinach::Config do
|
4
|
-
|
5
|
-
|
4
|
+
subject do
|
5
|
+
Spinach::Config.new
|
6
6
|
end
|
7
7
|
|
8
8
|
describe '#step_definitions_path' do
|
9
9
|
it 'returns a default' do
|
10
|
-
|
10
|
+
subject[:step_definitions_path].must_be_kind_of String
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'can be overwritten' do
|
14
|
-
|
15
|
-
|
14
|
+
subject[:step_definitions_path] = 'steps'
|
15
|
+
subject[:step_definitions_path].must_equal 'steps'
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
describe '#support_path' do
|
20
20
|
it 'returns a default' do
|
21
|
-
|
21
|
+
subject[:support_path].must_be_kind_of String
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'can be overwritten' do
|
25
|
-
|
26
|
-
|
25
|
+
subject[:support_path] = 'support'
|
26
|
+
subject[:support_path].must_equal 'support'
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
describe '#failure_exceptions' do
|
31
31
|
it 'returns a default' do
|
32
|
-
|
32
|
+
subject[:failure_exceptions].must_be_kind_of Array
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'can be overwritten' do
|
36
|
-
|
37
|
-
|
36
|
+
subject[:failure_exceptions] = [1, 2, 3]
|
37
|
+
subject[:failure_exceptions].must_equal [1,2,3]
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'allows adding elements' do
|
41
|
-
|
42
|
-
|
41
|
+
subject[:failure_exceptions] << RuntimeError
|
42
|
+
subject[:failure_exceptions].must_include RuntimeError
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
data/test/spinach/dsl_test.rb
CHANGED
@@ -10,11 +10,22 @@ describe Spinach::DSL do
|
|
10
10
|
describe 'class methods' do
|
11
11
|
describe '#When' do
|
12
12
|
it 'defines a method with the step name' do
|
13
|
+
step_executed = false
|
14
|
+
@feature.When('I say goodbye') do
|
15
|
+
step_executed = true
|
16
|
+
end
|
17
|
+
|
18
|
+
@feature.new.execute_step('I say goodbye')
|
19
|
+
step_executed.must_equal true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns step source location' do
|
13
23
|
@feature.When('I say goodbye') do
|
14
24
|
'You say hello'
|
15
25
|
end
|
16
26
|
|
17
|
-
@feature.new.
|
27
|
+
@feature.new.execute_step('I say goodbye').first.must_include '/dsl_test.rb'
|
28
|
+
@feature.new.execute_step('I say goodbye').last.must_be_kind_of Fixnum
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
@@ -68,8 +68,9 @@ describe Spinach::Reporter::Stdout do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
describe '#on_successful_step' do
|
71
|
+
let(:step_location){['error_step_location', 1]}
|
71
72
|
it 'adds the step to the output buffer' do
|
72
|
-
@reporter.on_successful_step({'keyword' => 'Given', 'name' => 'I am too cool'})
|
73
|
+
@reporter.on_successful_step({'keyword' => 'Given', 'name' => 'I am too cool'}, step_location)
|
73
74
|
|
74
75
|
@out.string.must_include '✔'
|
75
76
|
@out.string.must_include 'Given'
|
@@ -79,9 +80,10 @@ describe Spinach::Reporter::Stdout do
|
|
79
80
|
|
80
81
|
describe '#on_failed_step' do
|
81
82
|
let(:step) { {'keyword' => 'Then', 'name' => 'I write failing steps'} }
|
83
|
+
let(:step_location){['error_step_location', 1]}
|
82
84
|
|
83
85
|
it 'adds the step to the output buffer' do
|
84
|
-
@reporter.on_failed_step(step, anything)
|
86
|
+
@reporter.on_failed_step(step, anything, step_location)
|
85
87
|
|
86
88
|
@out.string.must_include '✘'
|
87
89
|
@out.string.must_include 'Then'
|
@@ -89,13 +91,13 @@ describe Spinach::Reporter::Stdout do
|
|
89
91
|
end
|
90
92
|
|
91
93
|
it 'sets the current scenario error' do
|
92
|
-
@reporter.on_failed_step(step, anything)
|
94
|
+
@reporter.on_failed_step(step, anything, step_location)
|
93
95
|
|
94
96
|
@reporter.scenario_error.must_include step
|
95
97
|
end
|
96
98
|
|
97
99
|
it 'adds the step to the failing steps' do
|
98
|
-
@reporter.on_failed_step(step, anything)
|
100
|
+
@reporter.on_failed_step(step, anything, step_location)
|
99
101
|
|
100
102
|
@reporter.failed_steps.last.must_include step
|
101
103
|
end
|
@@ -103,9 +105,10 @@ describe Spinach::Reporter::Stdout do
|
|
103
105
|
|
104
106
|
describe '#on_error_step' do
|
105
107
|
let(:step) { {'keyword' => 'And', 'name' => 'I even make syntax errors'} }
|
108
|
+
let(:step_location){['error_step_location', 1]}
|
106
109
|
|
107
110
|
it 'adds the step to the output buffer' do
|
108
|
-
@reporter.on_error_step(step, anything)
|
111
|
+
@reporter.on_error_step(step, anything, step_location)
|
109
112
|
|
110
113
|
@out.string.must_include '!'
|
111
114
|
@out.string.must_include 'And'
|
@@ -113,13 +116,13 @@ describe Spinach::Reporter::Stdout do
|
|
113
116
|
end
|
114
117
|
|
115
118
|
it 'sets the current scenario error' do
|
116
|
-
@reporter.on_error_step(step, anything)
|
119
|
+
@reporter.on_error_step(step, anything, step_location)
|
117
120
|
|
118
121
|
@reporter.scenario_error.must_include step
|
119
122
|
end
|
120
123
|
|
121
124
|
it 'adds the step to the error steps' do
|
122
|
-
@reporter.on_error_step(step, anything)
|
125
|
+
@reporter.on_error_step(step, anything, step_location)
|
123
126
|
|
124
127
|
@reporter.error_steps.last.must_include step
|
125
128
|
end
|
@@ -129,7 +132,7 @@ describe Spinach::Reporter::Stdout do
|
|
129
132
|
let(:step) { {'keyword' => 'When', 'name' => 'I forgot to write steps'} }
|
130
133
|
|
131
134
|
it 'adds the step to the output buffer' do
|
132
|
-
@reporter.on_undefined_step(step)
|
135
|
+
@reporter.on_undefined_step(step, anything)
|
133
136
|
|
134
137
|
@out.string.must_include '?'
|
135
138
|
@out.string.must_include 'When'
|
@@ -137,18 +140,50 @@ describe Spinach::Reporter::Stdout do
|
|
137
140
|
end
|
138
141
|
|
139
142
|
it 'sets the current scenario error' do
|
140
|
-
@reporter.on_undefined_step(step)
|
143
|
+
@reporter.on_undefined_step(step, anything)
|
141
144
|
|
142
145
|
@reporter.scenario_error.must_include step
|
143
146
|
end
|
144
147
|
|
145
148
|
it 'adds the step to the undefined steps' do
|
146
|
-
@reporter.on_undefined_step(step)
|
149
|
+
@reporter.on_undefined_step(step, anything)
|
147
150
|
|
148
151
|
@reporter.undefined_steps.last.must_include step
|
149
152
|
end
|
150
153
|
end
|
151
154
|
|
155
|
+
describe "#on_feature_not_found" do
|
156
|
+
before do
|
157
|
+
@feature = {
|
158
|
+
'name' => 'This feature does not exist'
|
159
|
+
}
|
160
|
+
Spinach.config.stubs(:step_definitions_path).returns('my/path')
|
161
|
+
exception = stub(
|
162
|
+
message: "This is a \nmultiple line error message",
|
163
|
+
missing_class: "ThisFeatureDoesNotExist"
|
164
|
+
)
|
165
|
+
@reporter.on_feature_not_found(@feature, exception)
|
166
|
+
end
|
167
|
+
it "outputs a message" do
|
168
|
+
@out.string.must_include "this_feature_does_not_exist.rb"
|
169
|
+
@out.string.must_include "This is a"
|
170
|
+
@out.string.must_include "multiple line error message"
|
171
|
+
@reporter.undefined_features.must_include @feature
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'tells the user to create the file' do
|
175
|
+
@out.string.must_include 'Please create the file this_feature_does_not_exist.rb'
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'tells the user where to create the file respecting the step definitions path' do
|
179
|
+
@out.string.must_include 'at my/path, with:'
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'tells the user what to write in the file' do
|
183
|
+
@out.string.must_include 'Feature \'This feature does not exist\' do'
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
152
187
|
describe '#on_skipped_step' do
|
153
188
|
it 'adds the step to the output buffer' do
|
154
189
|
@reporter.on_skipped_step({'keyword' => 'Then', 'name' => 'some steps are not even called'})
|
@@ -191,6 +226,7 @@ describe Spinach::Reporter::Stdout do
|
|
191
226
|
@reporter.expects(:report_error_steps).once
|
192
227
|
@reporter.expects(:report_failed_steps).once
|
193
228
|
@reporter.expects(:report_undefined_steps).once
|
229
|
+
@reporter.expects(:report_undefined_features).once
|
194
230
|
|
195
231
|
@reporter.error_summary
|
196
232
|
|
@@ -258,6 +294,27 @@ describe Spinach::Reporter::Stdout do
|
|
258
294
|
end
|
259
295
|
end
|
260
296
|
|
297
|
+
describe '#report_undefined_features' do
|
298
|
+
describe 'when some features are undefined' do
|
299
|
+
it 'outputs the undefined features' do
|
300
|
+
@reporter.undefined_features << {'name' => 'Undefined feature name'}
|
301
|
+
@reporter.report_undefined_features
|
302
|
+
|
303
|
+
@error.string.must_include "Undefined features (1)"
|
304
|
+
@error.string.must_include "Undefined feature name"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe 'when there are no undefined features' do
|
309
|
+
it 'does nothing' do
|
310
|
+
error = @error.string.dup
|
311
|
+
@reporter.report_undefined_steps
|
312
|
+
|
313
|
+
error.must_equal @error.string
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
261
318
|
describe '#report_errors' do
|
262
319
|
describe 'when some steps have raised an error' do
|
263
320
|
it 'outputs a the banner with the number of steps given' do
|
@@ -51,33 +51,45 @@ module Spinach
|
|
51
51
|
@callback = mock
|
52
52
|
@reporter.stubs(:method)
|
53
53
|
end
|
54
|
+
|
54
55
|
it "binds a callback after running all the suite" do
|
55
56
|
@reporter.expects(:method).with(:after_run).returns(@callback)
|
56
57
|
@reporter.runner.expects(:after_run).with(@callback)
|
57
58
|
@reporter.bind
|
58
59
|
end
|
60
|
+
|
59
61
|
it "binds a callback before running every feature" do
|
60
62
|
@reporter.expects(:method).with(:before_feature_run).returns(@callback)
|
61
63
|
@reporter.feature_runner.expects(:before_run).with(@callback)
|
62
64
|
@reporter.bind
|
63
65
|
end
|
66
|
+
|
64
67
|
it "binds a callback after running every feature" do
|
65
68
|
@reporter.expects(:method).with(:after_feature_run).returns(@callback)
|
66
69
|
@reporter.feature_runner.expects(:after_run).with(@callback)
|
67
70
|
@reporter.bind
|
68
71
|
end
|
72
|
+
|
73
|
+
it "binds a callback for not defined features" do
|
74
|
+
@reporter.expects(:method).with(:on_feature_not_found).returns(@callback)
|
75
|
+
@reporter.feature_runner.expects(:when_not_found).with(@callback)
|
76
|
+
@reporter.bind
|
77
|
+
end
|
78
|
+
|
69
79
|
it "binds a callback before running every scenario" do
|
70
80
|
@reporter.expects(:method).with(:before_scenario_run).returns(@callback)
|
71
81
|
@reporter.scenario_runner.expects(:before_run).with(@callback)
|
72
82
|
@reporter.bind
|
73
83
|
end
|
84
|
+
|
74
85
|
it "binds a callback after running every feature" do
|
75
86
|
@reporter.expects(:method).with(:after_scenario_run).returns(@callback)
|
76
87
|
@reporter.scenario_runner.expects(:after_run).with(@callback)
|
77
88
|
@reporter.bind
|
78
89
|
end
|
90
|
+
|
79
91
|
describe "when running steps" do
|
80
|
-
%w{successful failed error skipped}.each do |type|
|
92
|
+
%w{successful failed error undefined skipped}.each do |type|
|
81
93
|
it "binds a callback after running a #{type} step" do
|
82
94
|
@reporter.expects(:method).with(:"on_#{type}_step").returns(@callback)
|
83
95
|
@reporter.scenario_runner.expects(:"on_#{type}_step").with(@callback)
|
@@ -85,22 +97,26 @@ module Spinach
|
|
85
97
|
end
|
86
98
|
end
|
87
99
|
end
|
100
|
+
|
88
101
|
describe "binds the context methods" do
|
89
102
|
it "binds the current feature setter" do
|
90
103
|
@reporter.expects(:method).with(:current_feature=).returns(@callback)
|
91
104
|
@reporter.feature_runner.expects(:before_run).with(@callback)
|
92
105
|
@reporter.bind
|
93
106
|
end
|
107
|
+
|
94
108
|
it "binds the current feature clearer" do
|
95
109
|
@reporter.expects(:method).with(:clear_current_feature).returns(@callback)
|
96
110
|
@reporter.feature_runner.expects(:after_run).with(@callback)
|
97
111
|
@reporter.bind
|
98
112
|
end
|
113
|
+
|
99
114
|
it "binds the current scenario setter" do
|
100
115
|
@reporter.expects(:method).with(:current_scenario=).returns(@callback)
|
101
116
|
@reporter.scenario_runner.expects(:before_run).with(@callback)
|
102
117
|
@reporter.bind
|
103
118
|
end
|
119
|
+
|
104
120
|
it "binds the current feature clearer" do
|
105
121
|
@reporter.expects(:method).with(:clear_current_scenario).returns(@callback)
|
106
122
|
@reporter.scenario_runner.expects(:after_run).with(@callback)
|
@@ -131,11 +147,13 @@ module Spinach
|
|
131
147
|
@reporter.feature_runner.must_be_kind_of Class
|
132
148
|
end
|
133
149
|
end
|
150
|
+
|
134
151
|
describe "#scenario_runner" do
|
135
152
|
it "returns a runner class" do
|
136
153
|
@reporter.scenario_runner.must_be_kind_of Class
|
137
154
|
end
|
138
155
|
end
|
156
|
+
|
139
157
|
describe "#runner" do
|
140
158
|
it "returns a runner class" do
|
141
159
|
@reporter.runner.must_be_kind_of Class
|
@@ -156,6 +174,5 @@ module Spinach
|
|
156
174
|
end
|
157
175
|
end
|
158
176
|
end
|
159
|
-
|
160
177
|
end
|
161
178
|
end
|
@@ -93,5 +93,19 @@ describe Spinach::Runner::Feature do
|
|
93
93
|
Spinach::Runner::Scenario.expects(:new).with(anything, anything, @feature.scenarios[1], anything).once.returns(stub_everything)
|
94
94
|
@feature.run
|
95
95
|
end
|
96
|
+
|
97
|
+
it "fires a hook if the feature is not defined" do
|
98
|
+
feature = Spinach::Runner::Feature.new(filename)
|
99
|
+
data = mock
|
100
|
+
exception = Spinach::FeatureStepsNotFoundException.new([anything, anything])
|
101
|
+
feature.stubs(:feature).raises(exception)
|
102
|
+
feature.stubs(:data).returns(data)
|
103
|
+
not_found_called = false
|
104
|
+
feature.class.when_not_found do |data, exception|
|
105
|
+
not_found_called = [data, exception]
|
106
|
+
end
|
107
|
+
feature.run
|
108
|
+
not_found_called.must_equal [data, exception]
|
109
|
+
end
|
96
110
|
end
|
97
111
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spinach
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,11 +12,11 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2011-10-
|
15
|
+
date: 2011-10-10 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: gherkin
|
19
|
-
requirement: &
|
19
|
+
requirement: &2164332760 !ruby/object:Gem::Requirement
|
20
20
|
none: false
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
@@ -24,10 +24,10 @@ dependencies:
|
|
24
24
|
version: '0'
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2164332760
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: minitest
|
30
|
-
requirement: &
|
30
|
+
requirement: &2164330700 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ! '>='
|
@@ -35,10 +35,10 @@ dependencies:
|
|
35
35
|
version: '0'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2164330700
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: colorize
|
41
|
-
requirement: &
|
41
|
+
requirement: &2164330180 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
44
|
- - ! '>='
|
@@ -46,10 +46,10 @@ dependencies:
|
|
46
46
|
version: '0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
|
-
version_requirements: *
|
49
|
+
version_requirements: *2164330180
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: hooks
|
52
|
-
requirement: &
|
52
|
+
requirement: &2164329420 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
54
54
|
requirements:
|
55
55
|
- - ! '>='
|
@@ -57,10 +57,10 @@ dependencies:
|
|
57
57
|
version: '0'
|
58
58
|
type: :runtime
|
59
59
|
prerelease: false
|
60
|
-
version_requirements: *
|
60
|
+
version_requirements: *2164329420
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: purdytest
|
63
|
-
requirement: &
|
63
|
+
requirement: &2164328540 !ruby/object:Gem::Requirement
|
64
64
|
none: false
|
65
65
|
requirements:
|
66
66
|
- - ! '>='
|
@@ -68,10 +68,10 @@ dependencies:
|
|
68
68
|
version: '0'
|
69
69
|
type: :development
|
70
70
|
prerelease: false
|
71
|
-
version_requirements: *
|
71
|
+
version_requirements: *2164328540
|
72
72
|
- !ruby/object:Gem::Dependency
|
73
73
|
name: rake
|
74
|
-
requirement: &
|
74
|
+
requirement: &2164328020 !ruby/object:Gem::Requirement
|
75
75
|
none: false
|
76
76
|
requirements:
|
77
77
|
- - ! '>='
|
@@ -79,10 +79,10 @@ dependencies:
|
|
79
79
|
version: '0'
|
80
80
|
type: :development
|
81
81
|
prerelease: false
|
82
|
-
version_requirements: *
|
82
|
+
version_requirements: *2164328020
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: mocha
|
85
|
-
requirement: &
|
85
|
+
requirement: &2164373480 !ruby/object:Gem::Requirement
|
86
86
|
none: false
|
87
87
|
requirements:
|
88
88
|
- - ! '>='
|
@@ -90,10 +90,10 @@ dependencies:
|
|
90
90
|
version: '0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
|
-
version_requirements: *
|
93
|
+
version_requirements: *2164373480
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: sinatra
|
96
|
-
requirement: &
|
96
|
+
requirement: &2164372820 !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
99
|
- - ! '>='
|
@@ -101,10 +101,10 @@ dependencies:
|
|
101
101
|
version: '0'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
|
-
version_requirements: *
|
104
|
+
version_requirements: *2164372820
|
105
105
|
- !ruby/object:Gem::Dependency
|
106
106
|
name: capybara
|
107
|
-
requirement: &
|
107
|
+
requirement: &2164372260 !ruby/object:Gem::Requirement
|
108
108
|
none: false
|
109
109
|
requirements:
|
110
110
|
- - ! '>='
|
@@ -112,10 +112,10 @@ dependencies:
|
|
112
112
|
version: '0'
|
113
113
|
type: :development
|
114
114
|
prerelease: false
|
115
|
-
version_requirements: *
|
115
|
+
version_requirements: *2164372260
|
116
116
|
- !ruby/object:Gem::Dependency
|
117
117
|
name: aruba
|
118
|
-
requirement: &
|
118
|
+
requirement: &2164371820 !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|
121
121
|
- - ! '>='
|
@@ -123,10 +123,10 @@ dependencies:
|
|
123
123
|
version: '0'
|
124
124
|
type: :development
|
125
125
|
prerelease: false
|
126
|
-
version_requirements: *
|
126
|
+
version_requirements: *2164371820
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: pry
|
129
|
-
requirement: &
|
129
|
+
requirement: &2164371000 !ruby/object:Gem::Requirement
|
130
130
|
none: false
|
131
131
|
requirements:
|
132
132
|
- - ! '>='
|
@@ -134,10 +134,10 @@ dependencies:
|
|
134
134
|
version: '0'
|
135
135
|
type: :development
|
136
136
|
prerelease: false
|
137
|
-
version_requirements: *
|
137
|
+
version_requirements: *2164371000
|
138
138
|
- !ruby/object:Gem::Dependency
|
139
139
|
name: simplecov
|
140
|
-
requirement: &
|
140
|
+
requirement: &2164370500 !ruby/object:Gem::Requirement
|
141
141
|
none: false
|
142
142
|
requirements:
|
143
143
|
- - ! '>='
|
@@ -145,10 +145,10 @@ dependencies:
|
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
|
-
version_requirements: *
|
148
|
+
version_requirements: *2164370500
|
149
149
|
- !ruby/object:Gem::Dependency
|
150
150
|
name: rspec
|
151
|
-
requirement: &
|
151
|
+
requirement: &2164369940 !ruby/object:Gem::Requirement
|
152
152
|
none: false
|
153
153
|
requirements:
|
154
154
|
- - ! '>='
|
@@ -156,7 +156,7 @@ dependencies:
|
|
156
156
|
version: '0'
|
157
157
|
type: :development
|
158
158
|
prerelease: false
|
159
|
-
version_requirements: *
|
159
|
+
version_requirements: *2164369940
|
160
160
|
description: Spinach is a BDD framework on top of gherkin
|
161
161
|
email:
|
162
162
|
- info@codegram.com
|
@@ -177,13 +177,17 @@ files:
|
|
177
177
|
- Rakefile
|
178
178
|
- Readme.md
|
179
179
|
- bin/spinach
|
180
|
-
- features/error_reporting.feature
|
181
180
|
- features/exit_status.feature
|
182
181
|
- features/feature_name_guessing.feature
|
182
|
+
- features/reporting/error_reporting.feature
|
183
|
+
- features/reporting/show_step_source_location.feature
|
184
|
+
- features/reporting/undefined_feature_reporting.feature
|
183
185
|
- features/rspec_compatibility.feature
|
184
|
-
- features/steps/error_reporting.rb
|
185
186
|
- features/steps/exit_status.rb
|
186
187
|
- features/steps/feature_name_guessing.rb
|
188
|
+
- features/steps/reporting/error_reporting.rb
|
189
|
+
- features/steps/reporting/show_step_source_location.rb
|
190
|
+
- features/steps/reporting/undefined_feature_reporting.rb
|
187
191
|
- features/steps/rspec_compatibility.rb
|
188
192
|
- features/support/env.rb
|
189
193
|
- features/support/error_reporting.rb
|
@@ -235,26 +239,36 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
235
239
|
- - ! '>='
|
236
240
|
- !ruby/object:Gem::Version
|
237
241
|
version: '0'
|
242
|
+
segments:
|
243
|
+
- 0
|
244
|
+
hash: 1257566033182471881
|
238
245
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
246
|
none: false
|
240
247
|
requirements:
|
241
248
|
- - ! '>='
|
242
249
|
- !ruby/object:Gem::Version
|
243
250
|
version: '0'
|
251
|
+
segments:
|
252
|
+
- 0
|
253
|
+
hash: 1257566033182471881
|
244
254
|
requirements: []
|
245
255
|
rubyforge_project:
|
246
|
-
rubygems_version: 1.8.
|
256
|
+
rubygems_version: 1.8.5
|
247
257
|
signing_key:
|
248
258
|
specification_version: 3
|
249
259
|
summary: Spinach is a BDD framework on top of gherkin
|
250
260
|
test_files:
|
251
|
-
- features/error_reporting.feature
|
252
261
|
- features/exit_status.feature
|
253
262
|
- features/feature_name_guessing.feature
|
263
|
+
- features/reporting/error_reporting.feature
|
264
|
+
- features/reporting/show_step_source_location.feature
|
265
|
+
- features/reporting/undefined_feature_reporting.feature
|
254
266
|
- features/rspec_compatibility.feature
|
255
|
-
- features/steps/error_reporting.rb
|
256
267
|
- features/steps/exit_status.rb
|
257
268
|
- features/steps/feature_name_guessing.rb
|
269
|
+
- features/steps/reporting/error_reporting.rb
|
270
|
+
- features/steps/reporting/show_step_source_location.rb
|
271
|
+
- features/steps/reporting/undefined_feature_reporting.rb
|
258
272
|
- features/steps/rspec_compatibility.rb
|
259
273
|
- features/support/env.rb
|
260
274
|
- features/support/error_reporting.rb
|