spinach 0.1.1 → 0.1.2
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/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
|