spinach 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|