kosmas58-cucumber 0.2.0.1 → 0.2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +32 -1
- data/Manifest.txt +4 -11
- data/examples/dos_line_endings/features/dos_line_endings.feature +9 -9
- data/examples/pure_java/README.textile +5 -0
- data/examples/self_test/features/tons_of_cukes.feature +52 -0
- data/examples/sinatra/features/support/env.rb +6 -2
- data/examples/tickets/features/248.feature +11 -0
- data/examples/tickets/features/step_definitons/248_steps.rb +15 -0
- data/features/cucumber_cli.feature +1 -1
- data/features/custom_formatter.feature +2 -2
- data/features/usage.feature +108 -0
- data/gem_tasks/features.rake +18 -6
- data/lib/autotest/cucumber_mixin.rb +1 -1
- data/lib/cucumber/ast/feature.rb +1 -1
- data/lib/cucumber/ast/features.rb +6 -0
- data/lib/cucumber/ast/step.rb +4 -0
- data/lib/cucumber/ast/step_invocation.rb +10 -2
- data/lib/cucumber/ast/table.rb +4 -0
- data/lib/cucumber/cli/configuration.rb +11 -14
- data/lib/cucumber/cli/main.rb +14 -21
- data/lib/cucumber/core_ext/exception.rb +1 -1
- data/lib/cucumber/formatter.rb +1 -1
- data/lib/cucumber/formatter/html.rb +47 -8
- data/lib/cucumber/formatter/pretty.rb +1 -2
- data/lib/cucumber/formatter/rerun.rb +8 -0
- data/lib/cucumber/formatter/usage.rb +69 -0
- data/lib/cucumber/languages.yml +7 -2
- data/lib/cucumber/rails/world.rb +22 -21
- data/lib/cucumber/step_definition.rb +65 -54
- data/lib/cucumber/step_match.rb +10 -2
- data/lib/cucumber/step_mother.rb +4 -10
- data/lib/cucumber/version.rb +1 -1
- data/rails_generators/cucumber/templates/env.rb +2 -0
- data/rails_generators/feature/templates/steps.erb +1 -1
- data/spec/cucumber/ast/feature_spec.rb +2 -1
- data/spec/cucumber/cli/configuration_spec.rb +18 -6
- data/spec/cucumber/cli/main_spec.rb +1 -14
- data/spec/cucumber/parser/feature_parser_spec.rb +15 -15
- data/spec/cucumber/step_definition_spec.rb +21 -9
- data/spec/cucumber/step_mother_spec.rb +17 -1
- metadata +8 -13
- data/examples/jbehave/README.textile +0 -20
- data/examples/jbehave/features/support/env.rb +0 -7
- data/examples/jbehave/features/trading.feature +0 -28
- data/examples/jbehave/pom.xml +0 -53
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java +0 -32
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java +0 -42
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java +0 -29
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java +0 -22
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +0 -70
- data/gem_tasks/jar.rake +0 -67
- data/lib/cucumber/jbehave.rb +0 -97
data/lib/cucumber/ast/table.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cucumber
|
2
2
|
module Cli
|
3
3
|
class YmlLoadError < StandardError; end
|
4
|
-
|
4
|
+
|
5
5
|
class Configuration
|
6
6
|
FORMATS = %w{pretty profile progress rerun}
|
7
7
|
DEFAULT_FORMAT = 'pretty'
|
@@ -95,6 +95,7 @@ module Cucumber
|
|
95
95
|
Term::ANSIColor.coloring = v
|
96
96
|
end
|
97
97
|
opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.",
|
98
|
+
"This also omits the loading of your support/env.rb file if it exists.",
|
98
99
|
"Implies --quiet.") do
|
99
100
|
@options[:dry_run] = true
|
100
101
|
@quiet = true
|
@@ -137,9 +138,6 @@ module Cucumber
|
|
137
138
|
opts.on("--no-diff", "Disable diff output on failing expectations.") do
|
138
139
|
@options[:diff_enabled] = false
|
139
140
|
end
|
140
|
-
opts.on("-S", "--step-definitions", "Print the regexp and line of all step definitions, then exit.") do
|
141
|
-
@options[:print_step_definitions] = true
|
142
|
-
end
|
143
141
|
opts.on_tail("--version", "Show version.") do
|
144
142
|
@out_stream.puts VERSION::STRING
|
145
143
|
Kernel.exit
|
@@ -175,10 +173,6 @@ module Cucumber
|
|
175
173
|
@options[:diff_enabled]
|
176
174
|
end
|
177
175
|
|
178
|
-
def print_step_definitions?
|
179
|
-
@options[:print_step_definitions]
|
180
|
-
end
|
181
|
-
|
182
176
|
def load_language
|
183
177
|
if Cucumber.language_incomplete?(@options[:lang])
|
184
178
|
list_keywords_and_exit(@options[:lang])
|
@@ -224,11 +218,12 @@ module Cucumber
|
|
224
218
|
|
225
219
|
def formatter_class(format)
|
226
220
|
case format
|
221
|
+
when 'html' then Formatter::Html
|
227
222
|
when 'pretty' then Formatter::Pretty
|
228
|
-
when 'progress' then Formatter::Progress
|
229
223
|
when 'profile' then Formatter::Profile
|
224
|
+
when 'progress' then Formatter::Progress
|
230
225
|
when 'rerun' then Formatter::Rerun
|
231
|
-
when '
|
226
|
+
when 'usage' then Formatter::Usage
|
232
227
|
else
|
233
228
|
constantize(format)
|
234
229
|
end
|
@@ -242,7 +237,9 @@ module Cucumber
|
|
242
237
|
end.flatten.uniq
|
243
238
|
sorted_files = files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }.reject{|f| f =~ /^http/}
|
244
239
|
env_files = sorted_files.select {|f| f =~ %r{/support/env.rb} }
|
245
|
-
env_files + sorted_files.reject {|f| f =~ %r{/support/env.rb} }
|
240
|
+
files = env_files + sorted_files.reject {|f| f =~ %r{/support/env.rb} }
|
241
|
+
files.reject! {|f| f =~ %r{/support/env.rb} } if @options[:dry_run]
|
242
|
+
files
|
246
243
|
end
|
247
244
|
|
248
245
|
def feature_files
|
@@ -305,18 +302,18 @@ Defined profiles in cucumber.yml:
|
|
305
302
|
def cucumber_yml
|
306
303
|
return @cucumber_yml if @cucumber_yml
|
307
304
|
unless File.exist?('cucumber.yml')
|
308
|
-
raise(YmlLoadError,"cucumber.yml was not found. Please refer to cucumber's
|
305
|
+
raise(YmlLoadError,"cucumber.yml was not found. Please refer to cucumber's documentation on defining profiles in cucumber.yml. You must define a 'default' profile to use the cucumber command without any arguments.\nType 'cucumber --help' for usage.\n")
|
309
306
|
end
|
310
307
|
|
311
308
|
require 'yaml'
|
312
309
|
begin
|
313
310
|
@cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
314
311
|
rescue Exception => e
|
315
|
-
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's
|
312
|
+
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
|
316
313
|
end
|
317
314
|
|
318
315
|
if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
|
319
|
-
raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's
|
316
|
+
raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentation on correct profile usage.\n")
|
320
317
|
end
|
321
318
|
|
322
319
|
return @cucumber_yml
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -32,13 +32,6 @@ module Cucumber
|
|
32
32
|
step_mother.options = configuration.options
|
33
33
|
|
34
34
|
require_files
|
35
|
-
|
36
|
-
if(configuration.print_step_definitions?)
|
37
|
-
step_mother.print_step_definitions(@out_stream)
|
38
|
-
Kernel.exit(0)
|
39
|
-
return # In specs, exit is stubbed
|
40
|
-
end
|
41
|
-
|
42
35
|
enable_diffing
|
43
36
|
|
44
37
|
features = load_plain_text_features
|
@@ -53,7 +46,18 @@ module Cucumber
|
|
53
46
|
Kernel.exit(failure ? 1 : 0)
|
54
47
|
end
|
55
48
|
|
56
|
-
|
49
|
+
def load_plain_text_features
|
50
|
+
features = Ast::Features.new
|
51
|
+
parser = Parser::FeatureParser.new
|
52
|
+
|
53
|
+
verbose_log("Features:")
|
54
|
+
configuration.feature_files.each do |f|
|
55
|
+
features.add_feature(parser.parse_file(f))
|
56
|
+
verbose_log(" * #{f}")
|
57
|
+
end
|
58
|
+
verbose_log("\n"*2)
|
59
|
+
features
|
60
|
+
end
|
57
61
|
|
58
62
|
def configuration
|
59
63
|
return @configuration if @configuration
|
@@ -62,6 +66,8 @@ module Cucumber
|
|
62
66
|
@configuration.parse!(@args)
|
63
67
|
@configuration
|
64
68
|
end
|
69
|
+
|
70
|
+
private
|
65
71
|
|
66
72
|
def require_files
|
67
73
|
verbose_log("Ruby files required:")
|
@@ -77,19 +83,6 @@ module Cucumber
|
|
77
83
|
verbose_log("\n")
|
78
84
|
end
|
79
85
|
|
80
|
-
def load_plain_text_features
|
81
|
-
features = Ast::Features.new
|
82
|
-
parser = Parser::FeatureParser.new
|
83
|
-
|
84
|
-
verbose_log("Features:")
|
85
|
-
configuration.feature_files.each do |f|
|
86
|
-
features.add_feature(parser.parse_file(f))
|
87
|
-
verbose_log(" * #{f}")
|
88
|
-
end
|
89
|
-
verbose_log("\n"*2)
|
90
|
-
features
|
91
|
-
end
|
92
|
-
|
93
86
|
def verbose_log(string)
|
94
87
|
@out_stream.puts(string) if configuration.verbose?
|
95
88
|
end
|
data/lib/cucumber/formatter.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
%w{color_io pretty progress profile rerun html}.each{|n| require "cucumber/formatter/#{n}"}
|
1
|
+
%w{color_io pretty progress profile rerun html usage}.each{|n| require "cucumber/formatter/#{n}"}
|
@@ -83,37 +83,73 @@ module Cucumber
|
|
83
83
|
@builder.h4("#{keyword} #{name}")
|
84
84
|
end
|
85
85
|
|
86
|
-
def visit_steps(
|
86
|
+
def visit_steps(steps)
|
87
87
|
@builder.ol do
|
88
88
|
super
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
def visit_step(step)
|
93
|
+
@step_id = step.dom_id
|
94
|
+
@builder.li(:id => @step_id) do
|
95
|
+
super
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
92
99
|
def visit_step_name(keyword, step_match, status, source_indent, background)
|
93
|
-
|
94
|
-
@
|
100
|
+
@step_matches ||= []
|
101
|
+
@skip_step = @step_matches.index(step_match)
|
102
|
+
@step_matches << step_match
|
103
|
+
|
104
|
+
unless @skip_step
|
105
|
+
step_name = step_match.format_args(lambda{|param| "<span>#{param}</span>"})
|
106
|
+
@builder.div(:class => status) do |div|
|
107
|
+
div << "#{keyword} #{step_name}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def visit_exception(exception, status)
|
113
|
+
@builder.pre(format_exception(exception), :class => status)
|
95
114
|
end
|
96
115
|
|
97
116
|
def visit_multiline_arg(multiline_arg)
|
117
|
+
return if @skip_step
|
98
118
|
if Ast::Table === multiline_arg
|
99
119
|
@builder.table do
|
100
120
|
super
|
101
121
|
end
|
102
122
|
else
|
103
|
-
|
104
|
-
|
105
|
-
|
123
|
+
super
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def visit_py_string(string, status)
|
128
|
+
@builder.pre(:class => status) do |pre|
|
129
|
+
pre << string
|
106
130
|
end
|
107
131
|
end
|
108
132
|
|
109
133
|
def visit_table_row(table_row)
|
110
|
-
@
|
134
|
+
@row_id = table_row.dom_id
|
135
|
+
@col_index = 0
|
136
|
+
@builder.tr(:id => @row_id) do
|
111
137
|
super
|
112
138
|
end
|
139
|
+
if table_row.exception
|
140
|
+
@builder.tr do
|
141
|
+
@builder.td(:colspan => @col_index.to_s, :class => 'failed') do
|
142
|
+
@builder.pre do |pre|
|
143
|
+
pre << format_exception(table_row.exception)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
113
148
|
end
|
114
149
|
|
115
150
|
def visit_table_cell_value(value, width, status)
|
116
|
-
@builder.td(value, :class => status)
|
151
|
+
@builder.td(value, :class => status, :id => "#{@row_id}_#{@col_index}")
|
152
|
+
@col_index += 1
|
117
153
|
end
|
118
154
|
|
119
155
|
def announce(announcement)
|
@@ -128,6 +164,9 @@ module Cucumber
|
|
128
164
|
end
|
129
165
|
end
|
130
166
|
|
167
|
+
def format_exception(exception)
|
168
|
+
(["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
|
169
|
+
end
|
131
170
|
end
|
132
171
|
end
|
133
172
|
end
|
@@ -121,16 +121,15 @@ module Cucumber
|
|
121
121
|
|
122
122
|
def visit_step_name(keyword, step_match, status, source_indent, background)
|
123
123
|
@step_matches ||= []
|
124
|
-
|
125
124
|
non_failed_background_step_outside_background = !@in_background && background && (status != :failed)
|
126
125
|
@skip_step = @step_matches.index(step_match) || non_failed_background_step_outside_background
|
126
|
+
@step_matches << step_match
|
127
127
|
|
128
128
|
unless(@skip_step)
|
129
129
|
source_indent = nil unless @options[:source]
|
130
130
|
formatted_step_name = format_step(keyword, step_match, status, source_indent)
|
131
131
|
@io.puts(" " + formatted_step_name)
|
132
132
|
end
|
133
|
-
@step_matches << step_match
|
134
133
|
end
|
135
134
|
|
136
135
|
def visit_multiline_arg(multiline_arg)
|
@@ -1,5 +1,13 @@
|
|
1
1
|
module Cucumber
|
2
2
|
module Formatter
|
3
|
+
# This formatter keeps track of all failing features and print out their location.
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# features/foo.feature:34 features/bar.feature:11:76:81
|
7
|
+
#
|
8
|
+
# This formatter is used by AutoTest - it will use the output to decide what
|
9
|
+
# to run the next time, simply passing the output string on the command line.
|
10
|
+
#
|
3
11
|
class Rerun < Ast::Visitor
|
4
12
|
def initialize(step_mother, io, options)
|
5
13
|
super(step_mother)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'cucumber/formatter/progress'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Formatter
|
5
|
+
class Usage < Ast::Visitor
|
6
|
+
include Console
|
7
|
+
|
8
|
+
def initialize(step_mother, io, options)
|
9
|
+
super(step_mother)
|
10
|
+
@io = io
|
11
|
+
@options = options
|
12
|
+
@step_definitions = Hash.new { |h,step_definition| h[step_definition] = [] }
|
13
|
+
@locations = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def visit_features(features)
|
17
|
+
super
|
18
|
+
print_summary
|
19
|
+
end
|
20
|
+
|
21
|
+
def visit_step(step)
|
22
|
+
@step = step
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def visit_step_name(keyword, step_match, status, source_indent, background)
|
27
|
+
if step_match.step_definition
|
28
|
+
location = @step.file_colon_line
|
29
|
+
return if @locations.index(location)
|
30
|
+
@locations << location
|
31
|
+
|
32
|
+
description = format_step(keyword, step_match, status, nil)
|
33
|
+
length = (keyword + step_match.format_args).jlength
|
34
|
+
@step_definitions[step_match.step_definition] << [step_match, description, length, location]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_summary
|
39
|
+
sorted_defs = @step_definitions.keys.sort_by{|step_definition| step_definition.backtrace_line}
|
40
|
+
|
41
|
+
sorted_defs.each do |step_definition|
|
42
|
+
step_matches_and_descriptions = @step_definitions[step_definition].sort_by do |step_match_and_description|
|
43
|
+
step_match = step_match_and_description[0]
|
44
|
+
step_match.step_definition.regexp.inspect
|
45
|
+
end
|
46
|
+
|
47
|
+
step_matches = step_matches_and_descriptions.map{|step_match_and_description| step_match_and_description[0]}
|
48
|
+
|
49
|
+
lengths = step_matches_and_descriptions.map do |step_match_and_description|
|
50
|
+
step_match_and_description[2]
|
51
|
+
end
|
52
|
+
lengths << step_definition.text_length
|
53
|
+
max_length = lengths.max
|
54
|
+
|
55
|
+
@io.print step_definition.regexp.inspect
|
56
|
+
@io.puts format_string(" # #{step_definition.file_colon_line}".indent(max_length - step_definition.text_length), :comment)
|
57
|
+
step_matches_and_descriptions.each do |step_match_and_description|
|
58
|
+
step_match = step_match_and_description[0]
|
59
|
+
description = step_match_and_description[1]
|
60
|
+
length = step_match_and_description[2]
|
61
|
+
file_colon_line = step_match_and_description[3]
|
62
|
+
@io.print " #{description}"
|
63
|
+
@io.puts format_string(" # #{file_colon_line}".indent(max_length - length), :comment)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/cucumber/languages.yml
CHANGED
@@ -211,8 +211,10 @@
|
|
211
211
|
native: italiano
|
212
212
|
encoding: UTF-8
|
213
213
|
feature: Funzionalità
|
214
|
+
background: Contesto
|
214
215
|
scenario: Scenario
|
215
|
-
|
216
|
+
scenario_outline: Schema dello scenario
|
217
|
+
examples: Esempi
|
216
218
|
given: Dato
|
217
219
|
when: Quando
|
218
220
|
then: Allora
|
@@ -225,7 +227,7 @@
|
|
225
227
|
feature: フィーチャ
|
226
228
|
background: 背景
|
227
229
|
scenario: シナリオ
|
228
|
-
scenario_outline:
|
230
|
+
scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
|
229
231
|
examples: 例|サンプル
|
230
232
|
given: 前提
|
231
233
|
when: もし
|
@@ -249,7 +251,10 @@
|
|
249
251
|
native: Nederlands
|
250
252
|
encoding: UTF-8
|
251
253
|
feature: Functionaliteit
|
254
|
+
background: Achtergrond
|
252
255
|
scenario: Scenario
|
256
|
+
scenario_outline: Abstract Scenario
|
257
|
+
examples: Voorbeelden
|
253
258
|
given: Gegeven
|
254
259
|
when: Als
|
255
260
|
then: Dan
|
data/lib/cucumber/rails/world.rb
CHANGED
@@ -9,22 +9,10 @@ else
|
|
9
9
|
end
|
10
10
|
require 'test/unit/testresult'
|
11
11
|
|
12
|
-
# These allow exceptions to come through as opposed to being caught and having non-helpful responses returned.
|
13
|
-
ActionController::Base.class_eval do
|
14
|
-
def rescue_action(exception)
|
15
|
-
raise exception
|
16
|
-
end
|
17
|
-
end
|
18
|
-
ActionController::Dispatcher.class_eval do
|
19
|
-
def self.failsafe_response(output, status, exception = nil)
|
20
|
-
raise exception
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
12
|
# So that Test::Unit doesn't launch at the end - makes it think it has already been run.
|
25
13
|
Test::Unit.run = true if Test::Unit.respond_to?(:run=)
|
26
14
|
|
27
|
-
$
|
15
|
+
$__cucumber_toplevel = self
|
28
16
|
|
29
17
|
module Cucumber #:nodoc:
|
30
18
|
module Rails
|
@@ -44,20 +32,21 @@ module Cucumber #:nodoc:
|
|
44
32
|
def self.use_transactional_fixtures
|
45
33
|
World.use_transactional_fixtures = true
|
46
34
|
if defined?(ActiveRecord::Base)
|
47
|
-
$
|
48
|
-
|
49
|
-
|
35
|
+
$__cucumber_toplevel.Before do
|
36
|
+
@__cucumber_ar_connection = ActiveRecord::Base.connection
|
37
|
+
if @__cucumber_ar_connection.respond_to?(:increment_open_transactions)
|
38
|
+
@__cucumber_ar_connection.increment_open_transactions
|
50
39
|
else
|
51
40
|
ActiveRecord::Base.__send__(:increment_open_transactions)
|
52
41
|
end
|
53
|
-
|
42
|
+
@__cucumber_ar_connection.begin_db_transaction
|
54
43
|
ActionMailer::Base.deliveries = [] if defined?(ActionMailer::Base)
|
55
44
|
end
|
56
45
|
|
57
|
-
$
|
58
|
-
|
59
|
-
if
|
60
|
-
|
46
|
+
$__cucumber_toplevel.After do
|
47
|
+
@__cucumber_ar_connection.rollback_db_transaction
|
48
|
+
if @__cucumber_ar_connection.respond_to?(:decrement_open_transactions)
|
49
|
+
@__cucumber_ar_connection.decrement_open_transactions
|
61
50
|
else
|
62
51
|
ActiveRecord::Base.__send__(:decrement_open_transactions)
|
63
52
|
end
|
@@ -65,6 +54,18 @@ module Cucumber #:nodoc:
|
|
65
54
|
end
|
66
55
|
end
|
67
56
|
|
57
|
+
def self.bypass_rescue
|
58
|
+
ActionController::Base.class_eval do
|
59
|
+
def rescue_action(exception)
|
60
|
+
raise exception
|
61
|
+
end
|
62
|
+
end
|
63
|
+
ActionController::Dispatcher.class_eval do
|
64
|
+
def self.failsafe_response(output, status, exception = nil)
|
65
|
+
raise exception
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|