spinach 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +4 -0
- data/README.markdown +14 -43
- data/features/steps/reporting/use_customized_reporter.rb +2 -2
- data/features/steps/rspec_compatibility.rb +0 -2
- data/lib/spinach.rb +0 -1
- data/lib/spinach/capybara.rb +2 -0
- data/lib/spinach/cli.rb +19 -2
- data/lib/spinach/reporter/progress.rb +2 -46
- data/lib/spinach/reporter/reporting.rb +223 -0
- data/lib/spinach/reporter/stdout.rb +2 -45
- data/lib/spinach/runner.rb +1 -1
- data/lib/spinach/support.rb +11 -0
- data/lib/spinach/version.rb +1 -1
- data/test/spinach/cli_test.rb +7 -7
- data/test/spinach/reporter_test.rb +1 -1
- data/test/spinach/support_test.rb +6 -0
- metadata +24 -57
- data/lib/spinach/helpers.rb +0 -16
- data/lib/spinach/reporter/stdout/error_reporting.rb +0 -183
- data/test/spinach/helpers_test.rb +0 -9
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e27f69c95b6fab263c314db8cb58a6bc3ff3f673
|
4
|
+
data.tar.gz: 75ec627bf23c84e1c13fe6ef364d8af40618cf42
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af2d21ba883aaec463b738b5acd4a0d809981e94d722d65b0794285ea9b30eba4768ba9da98cdd1b2e5a3d0e2dfe53b8f2707e1cb4d95bcfca30b7421c1d99d5
|
7
|
+
data.tar.gz: 3dc41bafa156c3936e656bf60c3dce68f5d6322a8cf6da2fcf8332af32e9817bf527e343f5994b8562136bf34964f7bdceb44a9b66a7f08520af7bfd4bbe5363
|
data/CHANGELOG.md
CHANGED
data/README.markdown
CHANGED
@@ -72,22 +72,22 @@ Spinach will detect your features and generate the following class:
|
|
72
72
|
|
73
73
|
```ruby
|
74
74
|
class Spinach::Features::TestHowSpinachWorks < Spinach::FeatureSteps
|
75
|
-
|
75
|
+
step 'I have an empty array' do
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
step 'I append my first name and my last name to it' do
|
79
79
|
end
|
80
80
|
|
81
|
-
|
81
|
+
step 'I pass it to my super-duper method' do
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
step 'the output should contain a formal greeting' do
|
85
85
|
end
|
86
86
|
|
87
|
-
|
87
|
+
step 'I append only my first name to it' do
|
88
88
|
end
|
89
89
|
|
90
|
-
|
90
|
+
step 'the output should contain a casual greeting' do
|
91
91
|
end
|
92
92
|
end
|
93
93
|
```
|
@@ -97,29 +97,29 @@ use private methods, mix in modules or whatever!
|
|
97
97
|
|
98
98
|
```ruby
|
99
99
|
class Spinach::Features::TestHowSpinachWorks < Spinach::FeatureSteps
|
100
|
-
|
100
|
+
step 'I have an empty array' do
|
101
101
|
@array = Array.new
|
102
102
|
end
|
103
103
|
|
104
|
-
|
104
|
+
step 'I append my first name and my last name to it' do
|
105
105
|
@array += ["John", "Doe"]
|
106
106
|
end
|
107
107
|
|
108
|
-
|
108
|
+
step 'I pass it to my super-duper method' do
|
109
109
|
@output = capture_output do
|
110
110
|
Greeter.greet(@array)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
|
114
|
+
step 'the output should contain a formal greeting' do
|
115
115
|
@output.must_include "Hello, mr. John Doe"
|
116
116
|
end
|
117
117
|
|
118
|
-
|
118
|
+
step 'I append only my first name to it' do
|
119
119
|
@array += ["John"]
|
120
120
|
end
|
121
121
|
|
122
|
-
|
122
|
+
step 'the output should contain a casual greeting' do
|
123
123
|
@output.must_include "Yo, John! Whassup?"
|
124
124
|
end
|
125
125
|
|
@@ -162,25 +162,8 @@ This is one way to make that reusable:
|
|
162
162
|
# ... features/steps/common_steps/login.rb
|
163
163
|
module CommonSteps
|
164
164
|
module Login
|
165
|
-
|
166
|
-
|
167
|
-
def self.included(mod)
|
168
|
-
mod.send(:Given, 'I am logged in') do
|
169
|
-
# log in stuff...
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# within a rails app, you might want to use ActiveSupport::Concern
|
176
|
-
module CommonSteps
|
177
|
-
module Login
|
178
|
-
extend ActiveSupport::Concern
|
179
|
-
|
180
|
-
included do
|
181
|
-
Given 'I am logged in' do
|
182
|
-
# log in stuff...
|
183
|
-
end
|
165
|
+
step 'I am logged in' do
|
166
|
+
# log in stuff...
|
184
167
|
end
|
185
168
|
end
|
186
169
|
end
|
@@ -196,18 +179,6 @@ class Spinach::Features::BuyAWidget < Spinach::FeatureSteps
|
|
196
179
|
end
|
197
180
|
```
|
198
181
|
|
199
|
-
Also, don't forgot to require all of these common steps in your env.rb:
|
200
|
-
|
201
|
-
```ruby
|
202
|
-
# env.rb
|
203
|
-
common_steps = Dir.glob(Rails.root.join("features/steps/common_steps/**/*.rb"))
|
204
|
-
|
205
|
-
common_steps.each do |f|
|
206
|
-
require f
|
207
|
-
end
|
208
|
-
```
|
209
|
-
|
210
|
-
|
211
182
|
## Tags
|
212
183
|
|
213
184
|
Feature and Scenarios can be marked with tags in the form: `@tag`. Tags can be
|
@@ -6,7 +6,7 @@ class UseCustomizedReporter < Spinach::FeatureSteps
|
|
6
6
|
|
7
7
|
before do
|
8
8
|
class_str = <<-EOF
|
9
|
-
class Spinach::TestReporter < Spinach::Reporter
|
9
|
+
class Spinach::Reporter::TestReporter < Spinach::Reporter
|
10
10
|
attr_reader :out, :error
|
11
11
|
attr_accessor :scenario_error
|
12
12
|
attr_accessor :scenario
|
@@ -89,7 +89,7 @@ class ASuccessFeature < Spinach::FeatureSteps
|
|
89
89
|
end
|
90
90
|
|
91
91
|
When 'I run it using the new reporter' do
|
92
|
-
run_feature @feature, append: "-r
|
92
|
+
run_feature @feature, append: "-r test_reporter"
|
93
93
|
end
|
94
94
|
|
95
95
|
Then 'I see the desired output' do
|
data/lib/spinach.rb
CHANGED
data/lib/spinach/capybara.rb
CHANGED
data/lib/spinach/cli.rb
CHANGED
@@ -51,7 +51,7 @@ module Spinach
|
|
51
51
|
files_to_run = []
|
52
52
|
|
53
53
|
@args.each do |arg|
|
54
|
-
if arg.match
|
54
|
+
if arg.match(/\.feature/)
|
55
55
|
if File.exists? arg.gsub(/:\d*/, '')
|
56
56
|
files_to_run << arg
|
57
57
|
else
|
@@ -124,7 +124,7 @@ module Spinach
|
|
124
124
|
|
125
125
|
opts.on('-r', '--reporter CLASS_NAME',
|
126
126
|
'Formatter class name') do |class_name|
|
127
|
-
config[:reporter_class] = class_name
|
127
|
+
config[:reporter_class] = reporter_class(class_name)
|
128
128
|
end
|
129
129
|
end.parse!(@args)
|
130
130
|
|
@@ -145,5 +145,22 @@ module Spinach
|
|
145
145
|
puts message if message
|
146
146
|
exit 1
|
147
147
|
end
|
148
|
+
|
149
|
+
# Builds the class name to use an output reporter.
|
150
|
+
#
|
151
|
+
# @param [String] klass
|
152
|
+
# The class name fo the reporter.
|
153
|
+
#
|
154
|
+
# @return [String]
|
155
|
+
# The full name of the reporter class.
|
156
|
+
#
|
157
|
+
# @example
|
158
|
+
# reporter_class('progress')
|
159
|
+
# # => Spinach::Reporter::Progress
|
160
|
+
#
|
161
|
+
# @api private
|
162
|
+
def reporter_class(klass)
|
163
|
+
"Spinach::Reporter::" + Spinach::Support.camelize(klass)
|
164
|
+
end
|
148
165
|
end
|
149
166
|
end
|
@@ -1,22 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require_relative '
|
2
|
+
require_relative 'reporting'
|
3
3
|
|
4
4
|
module Spinach
|
5
5
|
class Reporter
|
6
6
|
# The Progress reporter outputs the runner results to the standard output
|
7
7
|
#
|
8
8
|
class Progress < Reporter
|
9
|
-
|
10
|
-
include Stdout::ErrorReporting
|
11
|
-
|
12
|
-
# The output buffers to store the reports.
|
13
|
-
attr_reader :out, :error
|
14
|
-
|
15
|
-
# The last scenario error
|
16
|
-
attr_accessor :scenario_error
|
17
|
-
|
18
|
-
# The last scenario
|
19
|
-
attr_accessor :scenario
|
9
|
+
include Reporting
|
20
10
|
|
21
11
|
# Initialitzes the runner
|
22
12
|
#
|
@@ -115,40 +105,6 @@ module Spinach
|
|
115
105
|
def output_step(text, color = :grey)
|
116
106
|
out.print(text.to_s.colorize(color))
|
117
107
|
end
|
118
|
-
|
119
|
-
# It prints the error summary if the run has failed
|
120
|
-
# It always print feature success summary
|
121
|
-
#
|
122
|
-
# @param [True,False] success
|
123
|
-
# whether the run has succeed or not
|
124
|
-
#
|
125
|
-
def after_run(success)
|
126
|
-
error_summary unless success
|
127
|
-
out.puts ""
|
128
|
-
run_summary
|
129
|
-
end
|
130
|
-
|
131
|
-
# Prints the feature success summary for this run.
|
132
|
-
#
|
133
|
-
def run_summary
|
134
|
-
successful_summary = format_summary(:green, successful_steps, 'Successful')
|
135
|
-
undefined_summary = format_summary(:yellow, undefined_steps, 'Undefined')
|
136
|
-
pending_summary = format_summary(:yellow, pending_steps, 'Pending')
|
137
|
-
failed_summary = format_summary(:red, failed_steps, 'Failed')
|
138
|
-
error_summary = format_summary(:red, error_steps, 'Error')
|
139
|
-
|
140
|
-
out.puts "Steps Summary: #{successful_summary}, #{undefined_summary}, #{pending_summary}, #{failed_summary}, #{error_summary}\n\n"
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
def format_summary(color, steps, message)
|
145
|
-
buffer = []
|
146
|
-
buffer << "(".colorize(color)
|
147
|
-
buffer << steps.length.to_s.colorize(:"light_#{color}")
|
148
|
-
buffer << ") ".colorize(color)
|
149
|
-
buffer << message.colorize(color)
|
150
|
-
buffer.join
|
151
|
-
end
|
152
108
|
end
|
153
109
|
end
|
154
110
|
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module Spinach
|
2
|
+
class Reporter
|
3
|
+
# This module handles Stdout's reporter error reporting capabilities.
|
4
|
+
module Reporting
|
5
|
+
|
6
|
+
# The output buffers to store the reports.
|
7
|
+
attr_reader :out, :error
|
8
|
+
|
9
|
+
# The last scenario error
|
10
|
+
attr_accessor :scenario_error
|
11
|
+
|
12
|
+
# The last scenario
|
13
|
+
attr_accessor :scenario
|
14
|
+
|
15
|
+
# Prints the errors for this run.
|
16
|
+
#
|
17
|
+
def error_summary
|
18
|
+
error.puts "\nError summary:\n"
|
19
|
+
report_error_steps
|
20
|
+
report_failed_steps
|
21
|
+
report_undefined_features
|
22
|
+
report_undefined_steps
|
23
|
+
report_pending_steps
|
24
|
+
end
|
25
|
+
|
26
|
+
def report_error_steps
|
27
|
+
report_errors('Errors', error_steps, :light_red) if error_steps.any?
|
28
|
+
end
|
29
|
+
|
30
|
+
def report_failed_steps
|
31
|
+
report_errors('Failures', failed_steps, :light_red) if failed_steps.any?
|
32
|
+
end
|
33
|
+
|
34
|
+
def report_undefined_steps
|
35
|
+
if undefined_steps.any?
|
36
|
+
error.puts "\nUndefined steps summary:\n"
|
37
|
+
report_errors('Undefined steps', undefined_steps, :yellow)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def report_pending_steps
|
42
|
+
if pending_steps.any?
|
43
|
+
error.puts "\nPending steps summary:\n"
|
44
|
+
report_errors('Pending steps', pending_steps, :yellow)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def report_undefined_features
|
49
|
+
if undefined_features.any?
|
50
|
+
error.puts " Undefined features (#{undefined_features.length})".light_yellow
|
51
|
+
undefined_features.each do |feature|
|
52
|
+
error.puts " #{feature.name}".yellow
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Prints the error for a given set of steps
|
58
|
+
#
|
59
|
+
# @param [String] banner
|
60
|
+
# the text to prepend as the title
|
61
|
+
#
|
62
|
+
# @param [Array] steps
|
63
|
+
# the steps to output
|
64
|
+
#
|
65
|
+
# @param [Symbol] color
|
66
|
+
# The color code to use with Colorize to colorize the output.
|
67
|
+
#
|
68
|
+
def report_errors(banner, steps, color)
|
69
|
+
error.puts " #{banner} (#{steps.length})".colorize(color)
|
70
|
+
steps.each do |error|
|
71
|
+
report_error error
|
72
|
+
end
|
73
|
+
error.puts ""
|
74
|
+
end
|
75
|
+
|
76
|
+
# Prints an error in a nice format
|
77
|
+
#
|
78
|
+
# @param [Array] error
|
79
|
+
# An array containing the feature, scenario, step and exception
|
80
|
+
#
|
81
|
+
# @param [Symbol] format
|
82
|
+
# The format to output the error. Currently supproted formats are
|
83
|
+
# :summarized (default) and :full
|
84
|
+
#
|
85
|
+
# @return [String]
|
86
|
+
# The error report
|
87
|
+
#
|
88
|
+
def report_error(error, format=:summarized)
|
89
|
+
case format
|
90
|
+
when :summarized
|
91
|
+
self.error.puts summarized_error(error)
|
92
|
+
when :full
|
93
|
+
self.error.puts full_error(error)
|
94
|
+
else
|
95
|
+
raise "Format not defined"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns summarized error report
|
100
|
+
#
|
101
|
+
# @param [Array] error
|
102
|
+
# An array containing the feature, scenario, step and exception
|
103
|
+
#
|
104
|
+
# @return [String]
|
105
|
+
# The summarized error report
|
106
|
+
#
|
107
|
+
def summarized_error(error)
|
108
|
+
feature, scenario, step, exception = error
|
109
|
+
summary = " #{feature.name} :: #{scenario.name} :: #{full_step step}"
|
110
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
111
|
+
summary.yellow
|
112
|
+
elsif exception.kind_of?(Spinach::StepPendingException)
|
113
|
+
summary += "\n Reason: '#{exception.reason}'\n"
|
114
|
+
summary.yellow
|
115
|
+
else
|
116
|
+
summary.red
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns a complete error report
|
121
|
+
#
|
122
|
+
# @param [Array] error
|
123
|
+
# An array containing the feature, scenario, step and exception
|
124
|
+
#
|
125
|
+
# @return [String]
|
126
|
+
# The coplete error report
|
127
|
+
#
|
128
|
+
def full_error(error)
|
129
|
+
feature, scenario, step, exception = error
|
130
|
+
output = "\n"
|
131
|
+
output += report_exception(exception)
|
132
|
+
output +="\n"
|
133
|
+
|
134
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
135
|
+
output << "\n"
|
136
|
+
output << " You can define it with: \n\n".yellow
|
137
|
+
suggestion = Generators::StepGenerator.new(step).generate
|
138
|
+
suggestion.split("\n").each do |line|
|
139
|
+
output << " #{line}\n".yellow
|
140
|
+
end
|
141
|
+
output << "\n"
|
142
|
+
elsif exception.kind_of?(Spinach::StepPendingException)
|
143
|
+
output << " Reason: '#{exception.reason}'".yellow
|
144
|
+
output << "\n"
|
145
|
+
else
|
146
|
+
if options[:backtrace]
|
147
|
+
output += "\n"
|
148
|
+
exception.backtrace.map do |line|
|
149
|
+
output << " #{line}\n"
|
150
|
+
end
|
151
|
+
else
|
152
|
+
output << " #{exception.backtrace[0]}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
output
|
156
|
+
end
|
157
|
+
|
158
|
+
# Prints a information when an exception is raised.
|
159
|
+
#
|
160
|
+
# @param [Exception] exception
|
161
|
+
# The exception to report
|
162
|
+
#
|
163
|
+
# @return [String]
|
164
|
+
# The exception report
|
165
|
+
#
|
166
|
+
def report_exception(exception)
|
167
|
+
output = exception.message.split("\n").map{ |line|
|
168
|
+
" #{line}"
|
169
|
+
}.join("\n")
|
170
|
+
|
171
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
172
|
+
output.yellow
|
173
|
+
elsif exception.kind_of?(Spinach::StepPendingException)
|
174
|
+
output.yellow
|
175
|
+
else
|
176
|
+
output.red
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Constructs the full step definition
|
181
|
+
#
|
182
|
+
# @param [Hash] step
|
183
|
+
# The step.
|
184
|
+
#
|
185
|
+
def full_step(step)
|
186
|
+
"#{step.keyword} #{step.name}"
|
187
|
+
end
|
188
|
+
|
189
|
+
def format_summary(color, steps, message)
|
190
|
+
buffer = []
|
191
|
+
buffer << "(".colorize(color)
|
192
|
+
buffer << steps.length.to_s.colorize(:"light_#{color}")
|
193
|
+
buffer << ") ".colorize(color)
|
194
|
+
buffer << message.colorize(color)
|
195
|
+
buffer.join
|
196
|
+
end
|
197
|
+
|
198
|
+
# It prints the error summary if the run has failed
|
199
|
+
# It always print feature success summary
|
200
|
+
#
|
201
|
+
# @param [True,False] success
|
202
|
+
# whether the run has succeed or not
|
203
|
+
#
|
204
|
+
def after_run(success)
|
205
|
+
error_summary unless success
|
206
|
+
out.puts ""
|
207
|
+
run_summary
|
208
|
+
end
|
209
|
+
|
210
|
+
# Prints the feature success summary for this run.
|
211
|
+
#
|
212
|
+
def run_summary
|
213
|
+
successful_summary = format_summary(:green, successful_steps, 'Successful')
|
214
|
+
undefined_summary = format_summary(:yellow, undefined_steps, 'Undefined')
|
215
|
+
pending_summary = format_summary(:yellow, pending_steps, 'Pending')
|
216
|
+
failed_summary = format_summary(:red, failed_steps, 'Failed')
|
217
|
+
error_summary = format_summary(:red, error_steps, 'Error')
|
218
|
+
|
219
|
+
out.puts "Steps Summary: #{successful_summary}, #{undefined_summary}, #{pending_summary}, #{failed_summary}, #{error_summary}\n\n"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -1,22 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require_relative '
|
2
|
+
require_relative 'reporting'
|
3
3
|
|
4
4
|
module Spinach
|
5
5
|
class Reporter
|
6
6
|
# The Stdout reporter outputs the runner results to the standard output
|
7
7
|
#
|
8
8
|
class Stdout < Reporter
|
9
|
-
|
10
|
-
include ErrorReporting
|
11
|
-
|
12
|
-
# The output buffers to store the reports.
|
13
|
-
attr_reader :out, :error
|
14
|
-
|
15
|
-
# The last scenario error
|
16
|
-
attr_accessor :scenario_error
|
17
|
-
|
18
|
-
# The last scenario
|
19
|
-
attr_accessor :scenario
|
9
|
+
include Reporting
|
20
10
|
|
21
11
|
# Initialitzes the runner
|
22
12
|
#
|
@@ -192,43 +182,10 @@ module Spinach
|
|
192
182
|
out.puts(joined + step_location.to_s.colorize(:grey))
|
193
183
|
end
|
194
184
|
|
195
|
-
# It prints the error summary if the run has failed
|
196
|
-
# It always print feature success summary
|
197
|
-
#
|
198
|
-
# @param [True,False] success
|
199
|
-
# whether the run has succeed or not
|
200
|
-
#
|
201
|
-
def after_run(success)
|
202
|
-
error_summary unless success
|
203
|
-
out.puts ""
|
204
|
-
run_summary
|
205
|
-
end
|
206
|
-
|
207
|
-
# Prints the feature success summary for this run.
|
208
|
-
#
|
209
|
-
def run_summary
|
210
|
-
successful_summary = format_summary(:green, successful_steps, 'Successful')
|
211
|
-
undefined_summary = format_summary(:yellow, undefined_steps, 'Undefined')
|
212
|
-
pending_summary = format_summary(:yellow, pending_steps, 'Pending')
|
213
|
-
failed_summary = format_summary(:red, failed_steps, 'Failed')
|
214
|
-
error_summary = format_summary(:red, error_steps, 'Error')
|
215
|
-
|
216
|
-
out.puts "Steps Summary: #{successful_summary}, #{undefined_summary}, #{pending_summary}, #{failed_summary}, #{error_summary}\n\n"
|
217
|
-
end
|
218
|
-
|
219
185
|
private
|
220
186
|
def indent(n = 1)
|
221
187
|
" " * n
|
222
188
|
end
|
223
|
-
|
224
|
-
def format_summary(color, steps, message)
|
225
|
-
buffer = []
|
226
|
-
buffer << "(".colorize(color)
|
227
|
-
buffer << steps.length.to_s.colorize(:"light_#{color}")
|
228
|
-
buffer << ") ".colorize(color)
|
229
|
-
buffer << message.colorize(color)
|
230
|
-
buffer.join
|
231
|
-
end
|
232
189
|
end
|
233
190
|
end
|
234
191
|
end
|
data/lib/spinach/runner.rb
CHANGED
@@ -50,7 +50,7 @@ module Spinach
|
|
50
50
|
#
|
51
51
|
# @api public
|
52
52
|
def init_reporter
|
53
|
-
reporter =
|
53
|
+
reporter = Support.constantize(Spinach.config[:reporter_class]).new(Spinach.config.reporter_options)
|
54
54
|
reporter.bind
|
55
55
|
end
|
56
56
|
|
data/lib/spinach/support.rb
CHANGED
@@ -71,5 +71,16 @@ module Spinach
|
|
71
71
|
def self.escape_single_commas(text)
|
72
72
|
text.gsub("'", "\\\\'")
|
73
73
|
end
|
74
|
+
|
75
|
+
def self.constantize(string)
|
76
|
+
names = string.split('::')
|
77
|
+
names.shift if names.empty? || names.first.empty?
|
78
|
+
|
79
|
+
constant = Object
|
80
|
+
names.each do |name|
|
81
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
82
|
+
end
|
83
|
+
constant
|
84
|
+
end
|
74
85
|
end
|
75
86
|
end
|
data/lib/spinach/version.rb
CHANGED
data/test/spinach/cli_test.rb
CHANGED
@@ -17,7 +17,7 @@ describe Spinach::Cli do
|
|
17
17
|
config = Spinach::Config.new
|
18
18
|
Spinach.stubs(:config).returns(config)
|
19
19
|
cli = Spinach::Cli.new([])
|
20
|
-
|
20
|
+
cli.options
|
21
21
|
config[:reporter_options].must_equal({})
|
22
22
|
end
|
23
23
|
|
@@ -55,7 +55,7 @@ tags:
|
|
55
55
|
config = Spinach::Config.new
|
56
56
|
Spinach.stubs(:config).returns(config)
|
57
57
|
cli = Spinach::Cli.new([opt])
|
58
|
-
|
58
|
+
cli.options
|
59
59
|
config[:reporter_options][:backtrace].must_equal true
|
60
60
|
end
|
61
61
|
end
|
@@ -66,9 +66,9 @@ tags:
|
|
66
66
|
it 'sets the reporter class' do
|
67
67
|
config = Spinach::Config.new
|
68
68
|
Spinach.stubs(:config).returns(config)
|
69
|
-
cli = Spinach::Cli.new([opt,
|
70
|
-
|
71
|
-
config.reporter_class.must_equal '
|
69
|
+
cli = Spinach::Cli.new([opt, 'progress'])
|
70
|
+
cli.options
|
71
|
+
config.reporter_class.must_equal 'Spinach::Reporter::Progress'
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -160,7 +160,7 @@ tags:
|
|
160
160
|
cli = Spinach::Cli.new([opt])
|
161
161
|
cli.expects(:exit)
|
162
162
|
cli.expects(:puts).with(Spinach::VERSION)
|
163
|
-
|
163
|
+
capture_stdout do
|
164
164
|
cli.options
|
165
165
|
end
|
166
166
|
end
|
@@ -195,7 +195,7 @@ tags:
|
|
195
195
|
cli = Spinach::Cli.new([opt])
|
196
196
|
cli.expects(:exit)
|
197
197
|
cli.expects(:puts).with("Invalid option: #{opt}")
|
198
|
-
|
198
|
+
cli.options
|
199
199
|
end
|
200
200
|
end
|
201
201
|
end
|
@@ -78,7 +78,7 @@ module Spinach
|
|
78
78
|
|
79
79
|
it "binds a callback before every scenario" do
|
80
80
|
@reporter.expects(:before_scenario_run)
|
81
|
-
Spinach.hooks.run_before_scenario(
|
81
|
+
Spinach.hooks.run_before_scenario(stub_everything)
|
82
82
|
end
|
83
83
|
|
84
84
|
it "binds a callback around every scenario" do
|
@@ -73,4 +73,10 @@ describe Spinach::Support do
|
|
73
73
|
).must_include "I\\'ve been doing things I shouldn\\'t be doing"
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
77
|
+
describe '#constantize' do
|
78
|
+
it "converts a string into a class" do
|
79
|
+
Spinach::Support.constantize("Spinach::FeatureSteps").must_equal Spinach::FeatureSteps
|
80
|
+
end
|
81
|
+
end
|
76
82
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spinach
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
5
|
-
prerelease:
|
4
|
+
version: 0.8.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Josep Jaume Rey
|
@@ -12,12 +11,11 @@ authors:
|
|
12
11
|
autorequire:
|
13
12
|
bindir: bin
|
14
13
|
cert_chain: []
|
15
|
-
date: 2013-03-
|
14
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
16
15
|
dependencies:
|
17
16
|
- !ruby/object:Gem::Dependency
|
18
17
|
name: gherkin-ruby
|
19
18
|
requirement: !ruby/object:Gem::Requirement
|
20
|
-
none: false
|
21
19
|
requirements:
|
22
20
|
- - ~>
|
23
21
|
- !ruby/object:Gem::Version
|
@@ -25,7 +23,6 @@ dependencies:
|
|
25
23
|
type: :runtime
|
26
24
|
prerelease: false
|
27
25
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
26
|
requirements:
|
30
27
|
- - ~>
|
31
28
|
- !ruby/object:Gem::Version
|
@@ -33,7 +30,6 @@ dependencies:
|
|
33
30
|
- !ruby/object:Gem::Dependency
|
34
31
|
name: colorize
|
35
32
|
requirement: !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
33
|
requirements:
|
38
34
|
- - '='
|
39
35
|
- !ruby/object:Gem::Version
|
@@ -41,7 +37,6 @@ dependencies:
|
|
41
37
|
type: :runtime
|
42
38
|
prerelease: false
|
43
39
|
version_requirements: !ruby/object:Gem::Requirement
|
44
|
-
none: false
|
45
40
|
requirements:
|
46
41
|
- - '='
|
47
42
|
- !ruby/object:Gem::Version
|
@@ -49,55 +44,48 @@ dependencies:
|
|
49
44
|
- !ruby/object:Gem::Dependency
|
50
45
|
name: rake
|
51
46
|
requirement: !ruby/object:Gem::Requirement
|
52
|
-
none: false
|
53
47
|
requirements:
|
54
|
-
- -
|
48
|
+
- - '>='
|
55
49
|
- !ruby/object:Gem::Version
|
56
50
|
version: '0'
|
57
51
|
type: :development
|
58
52
|
prerelease: false
|
59
53
|
version_requirements: !ruby/object:Gem::Requirement
|
60
|
-
none: false
|
61
54
|
requirements:
|
62
|
-
- -
|
55
|
+
- - '>='
|
63
56
|
- !ruby/object:Gem::Version
|
64
57
|
version: '0'
|
65
58
|
- !ruby/object:Gem::Dependency
|
66
59
|
name: mocha
|
67
60
|
requirement: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
61
|
requirements:
|
70
|
-
- -
|
62
|
+
- - '>='
|
71
63
|
- !ruby/object:Gem::Version
|
72
64
|
version: '0'
|
73
65
|
type: :development
|
74
66
|
prerelease: false
|
75
67
|
version_requirements: !ruby/object:Gem::Requirement
|
76
|
-
none: false
|
77
68
|
requirements:
|
78
|
-
- -
|
69
|
+
- - '>='
|
79
70
|
- !ruby/object:Gem::Version
|
80
71
|
version: '0'
|
81
72
|
- !ruby/object:Gem::Dependency
|
82
73
|
name: sinatra
|
83
74
|
requirement: !ruby/object:Gem::Requirement
|
84
|
-
none: false
|
85
75
|
requirements:
|
86
|
-
- -
|
76
|
+
- - '>='
|
87
77
|
- !ruby/object:Gem::Version
|
88
78
|
version: '0'
|
89
79
|
type: :development
|
90
80
|
prerelease: false
|
91
81
|
version_requirements: !ruby/object:Gem::Requirement
|
92
|
-
none: false
|
93
82
|
requirements:
|
94
|
-
- -
|
83
|
+
- - '>='
|
95
84
|
- !ruby/object:Gem::Version
|
96
85
|
version: '0'
|
97
86
|
- !ruby/object:Gem::Dependency
|
98
87
|
name: capybara
|
99
88
|
requirement: !ruby/object:Gem::Requirement
|
100
|
-
none: false
|
101
89
|
requirements:
|
102
90
|
- - ~>
|
103
91
|
- !ruby/object:Gem::Version
|
@@ -105,7 +93,6 @@ dependencies:
|
|
105
93
|
type: :development
|
106
94
|
prerelease: false
|
107
95
|
version_requirements: !ruby/object:Gem::Requirement
|
108
|
-
none: false
|
109
96
|
requirements:
|
110
97
|
- - ~>
|
111
98
|
- !ruby/object:Gem::Version
|
@@ -113,81 +100,71 @@ dependencies:
|
|
113
100
|
- !ruby/object:Gem::Dependency
|
114
101
|
name: pry
|
115
102
|
requirement: !ruby/object:Gem::Requirement
|
116
|
-
none: false
|
117
103
|
requirements:
|
118
|
-
- -
|
104
|
+
- - '>='
|
119
105
|
- !ruby/object:Gem::Version
|
120
106
|
version: '0'
|
121
107
|
type: :development
|
122
108
|
prerelease: false
|
123
109
|
version_requirements: !ruby/object:Gem::Requirement
|
124
|
-
none: false
|
125
110
|
requirements:
|
126
|
-
- -
|
111
|
+
- - '>='
|
127
112
|
- !ruby/object:Gem::Version
|
128
113
|
version: '0'
|
129
114
|
- !ruby/object:Gem::Dependency
|
130
115
|
name: simplecov
|
131
116
|
requirement: !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
117
|
requirements:
|
134
|
-
- -
|
118
|
+
- - '>='
|
135
119
|
- !ruby/object:Gem::Version
|
136
120
|
version: '0'
|
137
121
|
type: :development
|
138
122
|
prerelease: false
|
139
123
|
version_requirements: !ruby/object:Gem::Requirement
|
140
|
-
none: false
|
141
124
|
requirements:
|
142
|
-
- -
|
125
|
+
- - '>='
|
143
126
|
- !ruby/object:Gem::Version
|
144
127
|
version: '0'
|
145
128
|
- !ruby/object:Gem::Dependency
|
146
129
|
name: rspec
|
147
130
|
requirement: !ruby/object:Gem::Requirement
|
148
|
-
none: false
|
149
131
|
requirements:
|
150
|
-
- -
|
132
|
+
- - '>='
|
151
133
|
- !ruby/object:Gem::Version
|
152
134
|
version: '0'
|
153
135
|
type: :development
|
154
136
|
prerelease: false
|
155
137
|
version_requirements: !ruby/object:Gem::Requirement
|
156
|
-
none: false
|
157
138
|
requirements:
|
158
|
-
- -
|
139
|
+
- - '>='
|
159
140
|
- !ruby/object:Gem::Version
|
160
141
|
version: '0'
|
161
142
|
- !ruby/object:Gem::Dependency
|
162
143
|
name: minitest
|
163
144
|
requirement: !ruby/object:Gem::Requirement
|
164
|
-
none: false
|
165
145
|
requirements:
|
166
|
-
- -
|
146
|
+
- - '>='
|
167
147
|
- !ruby/object:Gem::Version
|
168
148
|
version: '0'
|
169
149
|
type: :development
|
170
150
|
prerelease: false
|
171
151
|
version_requirements: !ruby/object:Gem::Requirement
|
172
|
-
none: false
|
173
152
|
requirements:
|
174
|
-
- -
|
153
|
+
- - '>='
|
175
154
|
- !ruby/object:Gem::Version
|
176
155
|
version: '0'
|
177
156
|
- !ruby/object:Gem::Dependency
|
178
157
|
name: turn
|
179
158
|
requirement: !ruby/object:Gem::Requirement
|
180
|
-
none: false
|
181
159
|
requirements:
|
182
|
-
- -
|
160
|
+
- - '>='
|
183
161
|
- !ruby/object:Gem::Version
|
184
162
|
version: '0'
|
185
163
|
type: :development
|
186
164
|
prerelease: false
|
187
165
|
version_requirements: !ruby/object:Gem::Requirement
|
188
|
-
none: false
|
189
166
|
requirements:
|
190
|
-
- -
|
167
|
+
- - '>='
|
191
168
|
- !ruby/object:Gem::Version
|
192
169
|
version: '0'
|
193
170
|
description: Spinach is a BDD framework on top of gherkin
|
@@ -258,15 +235,14 @@ files:
|
|
258
235
|
- lib/spinach/generators.rb
|
259
236
|
- lib/spinach/generators/feature_generator.rb
|
260
237
|
- lib/spinach/generators/step_generator.rb
|
261
|
-
- lib/spinach/helpers.rb
|
262
238
|
- lib/spinach/hookable.rb
|
263
239
|
- lib/spinach/hooks.rb
|
264
240
|
- lib/spinach/parser.rb
|
265
241
|
- lib/spinach/parser/visitor.rb
|
266
242
|
- lib/spinach/reporter.rb
|
267
243
|
- lib/spinach/reporter/progress.rb
|
244
|
+
- lib/spinach/reporter/reporting.rb
|
268
245
|
- lib/spinach/reporter/stdout.rb
|
269
|
-
- lib/spinach/reporter/stdout/error_reporting.rb
|
270
246
|
- lib/spinach/runner.rb
|
271
247
|
- lib/spinach/runner/feature_runner.rb
|
272
248
|
- lib/spinach/runner/scenario_runner.rb
|
@@ -287,7 +263,6 @@ files:
|
|
287
263
|
- test/spinach/generators/feature_generator_test.rb
|
288
264
|
- test/spinach/generators/step_generator_test.rb
|
289
265
|
- test/spinach/generators_test.rb
|
290
|
-
- test/spinach/helpers_test.rb
|
291
266
|
- test/spinach/hookable_test.rb
|
292
267
|
- test/spinach/hooks_test.rb
|
293
268
|
- test/spinach/parser/visitor_test.rb
|
@@ -308,33 +283,26 @@ files:
|
|
308
283
|
- test/test_helper.rb
|
309
284
|
homepage: http://github.com/codegram/spinach
|
310
285
|
licenses: []
|
286
|
+
metadata: {}
|
311
287
|
post_install_message:
|
312
288
|
rdoc_options: []
|
313
289
|
require_paths:
|
314
290
|
- lib
|
315
291
|
required_ruby_version: !ruby/object:Gem::Requirement
|
316
|
-
none: false
|
317
292
|
requirements:
|
318
|
-
- -
|
293
|
+
- - '>='
|
319
294
|
- !ruby/object:Gem::Version
|
320
295
|
version: '0'
|
321
|
-
segments:
|
322
|
-
- 0
|
323
|
-
hash: -4461356009493919756
|
324
296
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
325
|
-
none: false
|
326
297
|
requirements:
|
327
|
-
- -
|
298
|
+
- - '>='
|
328
299
|
- !ruby/object:Gem::Version
|
329
300
|
version: '0'
|
330
|
-
segments:
|
331
|
-
- 0
|
332
|
-
hash: -4461356009493919756
|
333
301
|
requirements: []
|
334
302
|
rubyforge_project:
|
335
|
-
rubygems_version:
|
303
|
+
rubygems_version: 2.0.2
|
336
304
|
signing_key:
|
337
|
-
specification_version:
|
305
|
+
specification_version: 4
|
338
306
|
summary: Spinach is a BDD framework on top of gherkin
|
339
307
|
test_files:
|
340
308
|
- features/automatic_feature_generation.feature
|
@@ -378,7 +346,6 @@ test_files:
|
|
378
346
|
- test/spinach/generators/feature_generator_test.rb
|
379
347
|
- test/spinach/generators/step_generator_test.rb
|
380
348
|
- test/spinach/generators_test.rb
|
381
|
-
- test/spinach/helpers_test.rb
|
382
349
|
- test/spinach/hookable_test.rb
|
383
350
|
- test/spinach/hooks_test.rb
|
384
351
|
- test/spinach/parser/visitor_test.rb
|
data/lib/spinach/helpers.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Spinach
|
2
|
-
module Helpers
|
3
|
-
class << self
|
4
|
-
def constantize(string)
|
5
|
-
names = string.split('::')
|
6
|
-
names.shift if names.empty? || names.first.empty?
|
7
|
-
|
8
|
-
constant = Object
|
9
|
-
names.each do |name|
|
10
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
11
|
-
end
|
12
|
-
constant
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,183 +0,0 @@
|
|
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
|
-
report_pending_steps
|
16
|
-
end
|
17
|
-
|
18
|
-
def report_error_steps
|
19
|
-
report_errors('Errors', error_steps, :light_red) if error_steps.any?
|
20
|
-
end
|
21
|
-
|
22
|
-
def report_failed_steps
|
23
|
-
report_errors('Failures', failed_steps, :light_red) if failed_steps.any?
|
24
|
-
end
|
25
|
-
|
26
|
-
def report_undefined_steps
|
27
|
-
if undefined_steps.any?
|
28
|
-
error.puts "\nUndefined steps summary:\n"
|
29
|
-
report_errors('Undefined steps', undefined_steps, :yellow)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def report_pending_steps
|
34
|
-
if pending_steps.any?
|
35
|
-
error.puts "\nPending steps summary:\n"
|
36
|
-
report_errors('Pending steps', pending_steps, :yellow)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def report_undefined_features
|
41
|
-
if undefined_features.any?
|
42
|
-
error.puts " Undefined features (#{undefined_features.length})".light_yellow
|
43
|
-
undefined_features.each do |feature|
|
44
|
-
error.puts " #{feature.name}".yellow
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Prints the error for a given set of steps
|
50
|
-
#
|
51
|
-
# @param [String] banner
|
52
|
-
# the text to prepend as the title
|
53
|
-
#
|
54
|
-
# @param [Array] steps
|
55
|
-
# the steps to output
|
56
|
-
#
|
57
|
-
# @param [Symbol] color
|
58
|
-
# The color code to use with Colorize to colorize the output.
|
59
|
-
#
|
60
|
-
def report_errors(banner, steps, color)
|
61
|
-
error.puts " #{banner} (#{steps.length})".colorize(color)
|
62
|
-
steps.each do |error|
|
63
|
-
report_error error
|
64
|
-
end
|
65
|
-
error.puts ""
|
66
|
-
end
|
67
|
-
|
68
|
-
# Prints an error in a nice format
|
69
|
-
#
|
70
|
-
# @param [Array] error
|
71
|
-
# An array containing the feature, scenario, step and exception
|
72
|
-
#
|
73
|
-
# @param [Symbol] format
|
74
|
-
# The format to output the error. Currently supproted formats are
|
75
|
-
# :summarized (default) and :full
|
76
|
-
#
|
77
|
-
# @return [String]
|
78
|
-
# The error report
|
79
|
-
#
|
80
|
-
def report_error(error, format=:summarized)
|
81
|
-
case format
|
82
|
-
when :summarized
|
83
|
-
self.error.puts summarized_error(error)
|
84
|
-
when :full
|
85
|
-
self.error.puts full_error(error)
|
86
|
-
else
|
87
|
-
raise "Format not defined"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Returns summarized error report
|
92
|
-
#
|
93
|
-
# @param [Array] error
|
94
|
-
# An array containing the feature, scenario, step and exception
|
95
|
-
#
|
96
|
-
# @return [String]
|
97
|
-
# The summarized error report
|
98
|
-
#
|
99
|
-
def summarized_error(error)
|
100
|
-
feature, scenario, step, exception = error
|
101
|
-
summary = " #{feature.name} :: #{scenario.name} :: #{full_step step}"
|
102
|
-
if exception.kind_of?(Spinach::StepNotDefinedException)
|
103
|
-
summary.yellow
|
104
|
-
elsif exception.kind_of?(Spinach::StepPendingException)
|
105
|
-
summary += "\n Reason: '#{exception.reason}'\n"
|
106
|
-
summary.yellow
|
107
|
-
else
|
108
|
-
summary.red
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Returns a complete error report
|
113
|
-
#
|
114
|
-
# @param [Array] error
|
115
|
-
# An array containing the feature, scenario, step and exception
|
116
|
-
#
|
117
|
-
# @return [String]
|
118
|
-
# The coplete error report
|
119
|
-
#
|
120
|
-
def full_error(error)
|
121
|
-
feature, scenario, step, exception = error
|
122
|
-
output = "\n"
|
123
|
-
output += report_exception(exception)
|
124
|
-
output +="\n"
|
125
|
-
|
126
|
-
if exception.kind_of?(Spinach::StepNotDefinedException)
|
127
|
-
output << "\n"
|
128
|
-
output << " You can define it with: \n\n".yellow
|
129
|
-
suggestion = Generators::StepGenerator.new(step).generate
|
130
|
-
suggestion.split("\n").each do |line|
|
131
|
-
output << " #{line}\n".yellow
|
132
|
-
end
|
133
|
-
output << "\n"
|
134
|
-
elsif exception.kind_of?(Spinach::StepPendingException)
|
135
|
-
output << " Reason: '#{exception.reason}'".yellow
|
136
|
-
output << "\n"
|
137
|
-
else
|
138
|
-
if options[:backtrace]
|
139
|
-
output += "\n"
|
140
|
-
exception.backtrace.map do |line|
|
141
|
-
output << " #{line}\n"
|
142
|
-
end
|
143
|
-
else
|
144
|
-
output << " #{exception.backtrace[0]}"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
output
|
148
|
-
end
|
149
|
-
|
150
|
-
# Prints a information when an exception is raised.
|
151
|
-
#
|
152
|
-
# @param [Exception] exception
|
153
|
-
# The exception to report
|
154
|
-
#
|
155
|
-
# @return [String]
|
156
|
-
# The exception report
|
157
|
-
#
|
158
|
-
def report_exception(exception)
|
159
|
-
output = exception.message.split("\n").map{ |line|
|
160
|
-
" #{line}"
|
161
|
-
}.join("\n")
|
162
|
-
|
163
|
-
if exception.kind_of?(Spinach::StepNotDefinedException)
|
164
|
-
output.yellow
|
165
|
-
elsif exception.kind_of?(Spinach::StepPendingException)
|
166
|
-
output.yellow
|
167
|
-
else
|
168
|
-
output.red
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# Constructs the full step definition
|
173
|
-
#
|
174
|
-
# @param [Hash] step
|
175
|
-
# The step.
|
176
|
-
#
|
177
|
-
def full_step(step)
|
178
|
-
"#{step.keyword} #{step.name}"
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|