cucumber 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +38 -3
- data/Manifest.txt +17 -1
- data/README.txt +2 -39
- data/bin/cucumber +1 -1
- data/examples/calculator_ruby_features/features/addition.rb +16 -0
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +1 -0
- data/examples/i18n/de/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/i18n/en/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/i18n/es/features/step_definitons/calculador_steps.rb +1 -0
- data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -0
- data/examples/i18n/fr/features/addition.feature +13 -11
- data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +6 -2
- data/examples/i18n/id/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -0
- data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +2 -0
- data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +1 -0
- data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +1 -0
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -0
- data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +1 -0
- data/examples/selenium/features/search.feature +1 -1
- data/examples/selenium/features/step_definitons/stories_steps.rb +2 -3
- data/examples/tickets/features/lib/eatting_machine.rb +18 -0
- data/examples/tickets/features/lib/pantry.rb +20 -0
- data/examples/tickets/features/scenario_outline.feature +64 -0
- data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +34 -0
- data/examples/tickets/features/step_definitons/tickets_steps.rb +4 -0
- data/gem_tasks/fix_cr_lf.rake +1 -1
- data/gem_tasks/yard.rake +8 -0
- data/lib/autotest/cucumber_mixin.rb +3 -3
- data/lib/cucumber.rb +2 -0
- data/lib/cucumber/broadcaster.rb +1 -1
- data/lib/cucumber/cli.rb +87 -42
- data/lib/cucumber/core_ext/exception.rb +20 -0
- data/lib/cucumber/core_ext/string.rb +1 -1
- data/lib/cucumber/executor.rb +35 -18
- data/lib/cucumber/formatters/ansicolor.rb +65 -74
- data/lib/cucumber/formatters/html_formatter.rb +33 -10
- data/lib/cucumber/formatters/pretty_formatter.rb +58 -16
- data/lib/cucumber/formatters/progress_formatter.rb +3 -0
- data/lib/cucumber/formatters/unicode.rb +27 -0
- data/lib/cucumber/languages.yml +6 -4
- data/lib/cucumber/platform.rb +1 -0
- data/lib/cucumber/rails/world.rb +6 -6
- data/lib/cucumber/step_mother.rb +3 -0
- data/lib/cucumber/tree/feature.rb +28 -2
- data/lib/cucumber/tree/scenario.rb +62 -1
- data/lib/cucumber/tree/step.rb +32 -1
- data/lib/cucumber/treetop_parser/feature.treetop.erb +54 -7
- data/lib/cucumber/treetop_parser/feature_ar.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_cy.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_da.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_de.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_en-lol.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_en-tx.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_en.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_es.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_et.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_fr.rb +389 -30
- data/lib/cucumber/treetop_parser/feature_id.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_it.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_ja.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_lt.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_nl.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_no.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_pl.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_pt.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_ro.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_ro2.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_ru.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_se.rb +377 -18
- data/lib/cucumber/treetop_parser/feature_zh-CN.rb +377 -18
- data/lib/cucumber/version.rb +1 -1
- data/lib/cucumber/world.rb +1 -0
- data/lib/cucumber/world/pending.rb +22 -0
- data/rails_generators/cucumber/templates/env.rb +1 -0
- data/rails_generators/feature/feature_generator.rb +22 -2
- data/rails_generators/feature/templates/feature.erb +15 -12
- data/rails_generators/feature/templates/steps.erb +16 -14
- data/spec/cucumber/cli_spec.rb +87 -6
- data/spec/cucumber/executor_spec.rb +102 -30
- data/spec/cucumber/formatters/ansicolor_spec.rb +10 -10
- data/spec/cucumber/formatters/html_formatter_spec.rb +30 -0
- data/spec/cucumber/formatters/pretty_formatter_spec.rb +139 -4
- data/spec/cucumber/formatters/progress_formatter_spec.rb +16 -0
- data/spec/cucumber/tree/feature_spec.rb +84 -5
- data/spec/cucumber/tree/row_scenario_outline_spec.rb +73 -0
- data/spec/cucumber/tree/row_step_outline_spec.rb +38 -0
- data/spec/cucumber/tree/scenario_outline_spec.rb +50 -0
- data/spec/cucumber/tree/step_outline_spec.rb +17 -0
- data/spec/cucumber/tree/step_spec.rb +9 -0
- data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
- data/spec/cucumber/treetop_parser/feature_parser_spec.rb +22 -0
- data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
- data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
- data/spec/cucumber/world/pending_spec.rb +46 -0
- data/spec/spec_helper.rb +2 -1
- metadata +19 -4
- data/TODO.txt +0 -26
@@ -0,0 +1,34 @@
|
|
1
|
+
Given /^there are (\d+) (\w+)$/ do |count, fruit|
|
2
|
+
@eattingMachine = EattingMachine.new(fruit, count)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given "the belly space is < 12 and > 6" do
|
6
|
+
end
|
7
|
+
|
8
|
+
Given "I have the following fruits in my pantry" do |pantry_table|
|
9
|
+
@pantry = Pantry.new
|
10
|
+
pantry_table.hashes.each do |item|
|
11
|
+
@pantry.add(item['name'].downcase, item['quantity'])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I eat (\d+) (\w+)$/ do |count, fruit|
|
16
|
+
@eattingMachine.eat(count)
|
17
|
+
@eattingMachine.belly_count = count.to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
When /^I eat (\d+) (\w+) from the pantry$/ do |count, fruit|
|
21
|
+
@pantry.remove(fruit, count.to_i)
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /^I should have (\d+) (\w+)$/ do |count, fruit|
|
25
|
+
@eattingMachine.fruit_total.should == count.to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
Then /^I should have (\d+) (\w+) in my belly$/ do |count, fruit|
|
29
|
+
@eattingMachine.belly_count.should == count.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
Then /^I should have (\d+) (\w+) in the pantry$/ do |count, fruit|
|
33
|
+
@pantry.count(fruit).should == count.to_i
|
34
|
+
end
|
data/gem_tasks/fix_cr_lf.rake
CHANGED
@@ -2,7 +2,7 @@ desc 'Make all files use UNIX (\n) line endings'
|
|
2
2
|
task :fix_cr_lf do
|
3
3
|
files = FileList['**/*']
|
4
4
|
files.each do |f|
|
5
|
-
next if File.directory?(f)
|
5
|
+
next if File.directory?(f) || f =~ /dos/
|
6
6
|
s = IO.read(f)
|
7
7
|
s.gsub!(/\r?\n/, "\n")
|
8
8
|
File.open(f, "w") { |io| io.write(s) }
|
data/gem_tasks/yard.rake
ADDED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'autotest'
|
2
2
|
require 'tempfile'
|
3
|
+
require File.dirname(__FILE__) + '/../cucumber/platform'
|
3
4
|
|
4
5
|
module Autotest::CucumberMixin
|
5
6
|
def self.included(receiver)
|
@@ -121,11 +122,10 @@ module Autotest::CucumberMixin
|
|
121
122
|
else
|
122
123
|
scenario_args = scenarios_to_run.map { |s| "-s '#{s}'" }.join(' ')
|
123
124
|
end
|
124
|
-
|
125
|
-
return "#{cucumber} #{args} #{scenario_args}"
|
125
|
+
return "#{$CUCUMBER_RUBY} #{cucumber} #{args} #{scenario_args}"
|
126
126
|
end
|
127
127
|
|
128
128
|
def cucumber
|
129
|
-
File.
|
129
|
+
File.file?("script/cucumber") ? "script/cucumber" : "cucumber"
|
130
130
|
end
|
131
131
|
end
|
data/lib/cucumber.rb
CHANGED
@@ -15,6 +15,8 @@ require 'cucumber/formatters'
|
|
15
15
|
require 'cucumber/treetop_parser/feature_parser'
|
16
16
|
require 'cucumber/cli'
|
17
17
|
require 'cucumber/broadcaster'
|
18
|
+
require 'cucumber/world'
|
19
|
+
require 'cucumber/core_ext/exception'
|
18
20
|
|
19
21
|
module Cucumber
|
20
22
|
LANGUAGE_FILE = File.expand_path(File.dirname(__FILE__) + '/cucumber/languages.yml')
|
data/lib/cucumber/broadcaster.rb
CHANGED
@@ -11,7 +11,7 @@ module Cucumber
|
|
11
11
|
|
12
12
|
def method_missing(method_name, *args)
|
13
13
|
@receivers.each do |receiver|
|
14
|
-
r = (receiver == STDOUT) ? Kernel: receiver # Needed to make colors work on Windows
|
14
|
+
r = (receiver == STDOUT) ? Kernel : receiver # Needed to make colors work on Windows
|
15
15
|
r.__send__(method_name, *args) if receiver.respond_to?(method_name)
|
16
16
|
end
|
17
17
|
end
|
data/lib/cucumber/cli.rb
CHANGED
@@ -2,13 +2,15 @@ require 'optparse'
|
|
2
2
|
require 'cucumber'
|
3
3
|
|
4
4
|
module Cucumber
|
5
|
+
class YmlLoadError < StandardError; end
|
6
|
+
|
5
7
|
class CLI
|
6
8
|
class << self
|
7
9
|
attr_writer :step_mother, :executor, :features
|
8
10
|
|
9
|
-
def execute
|
11
|
+
def execute(args)
|
10
12
|
@execute_called = true
|
11
|
-
parse(
|
13
|
+
parse(args).execute!(@step_mother, @executor, @features)
|
12
14
|
end
|
13
15
|
|
14
16
|
def execute_called?
|
@@ -44,11 +46,16 @@ module Cucumber
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def parse_options!(args)
|
49
|
+
@args = args
|
47
50
|
return parse_args_from_profile('default') if args.empty?
|
48
51
|
args.extend(OptionParser::Arguable)
|
49
52
|
|
50
53
|
args.options do |opts|
|
51
|
-
opts.banner = "Usage: cucumber [options] FILES|DIRS"
|
54
|
+
opts.banner = ["Usage: cucumber [options] [[FILE[:LINE[:LINE]*]] | [FILES|DIRS]]", "",
|
55
|
+
"Examples:",
|
56
|
+
"cucumber examples/i18n/en/features",
|
57
|
+
"cucumber --language it examples/i18n/it/features/somma.feature:6:98:113", "", ""
|
58
|
+
].join("\n")
|
52
59
|
opts.on("-r LIBRARY|DIR", "--require LIBRARY|DIR", "Require files before executing the features.",
|
53
60
|
"If this option is not specified, all *.rb files that",
|
54
61
|
"are siblings or below the features will be autorequired",
|
@@ -62,7 +69,7 @@ module Cucumber
|
|
62
69
|
@options[:scenario_names] ||= []
|
63
70
|
@options[:scenario_names] << v
|
64
71
|
end
|
65
|
-
opts.on("-
|
72
|
+
opts.on("-l LANG", "--language LANG", "Specify language for features (Default: #{@options[:lang]})",
|
66
73
|
"Available languages: #{Cucumber.languages.join(", ")}",
|
67
74
|
"Look at #{Cucumber::LANGUAGE_FILE} for keywords") do |v|
|
68
75
|
@options[:lang] = v
|
@@ -113,6 +120,9 @@ module Cucumber
|
|
113
120
|
@options[:snippets] = false
|
114
121
|
@options[:source] = false
|
115
122
|
end
|
123
|
+
opts.on("-b", "--backtrace", "Show full backtrace for all errors") do
|
124
|
+
Exception.cucumber_full_backtrace = true
|
125
|
+
end
|
116
126
|
opts.on("-v", "--verbose", "Show the files and features loaded") do
|
117
127
|
@options[:verbose] = true
|
118
128
|
end
|
@@ -135,33 +145,12 @@ module Cucumber
|
|
135
145
|
@paths += args
|
136
146
|
end
|
137
147
|
|
138
|
-
def parse_args_from_profile(profile)
|
139
|
-
unless File.exist?('cucumber.yml')
|
140
|
-
return exit_with_error("cucumber.yml was not found. Please define your '#{profile}' and other profiles in cucumber.yml.\n"+
|
141
|
-
"Type 'cucumber --help' for usage.\n")
|
142
|
-
end
|
143
|
-
|
144
|
-
require 'yaml'
|
145
|
-
cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
146
|
-
args_from_yml = cucumber_yml[profile]
|
147
|
-
if args_from_yml.nil?
|
148
|
-
exit_with_error <<-END_OF_ERROR
|
149
|
-
Could not find profile: '#{profile}'
|
150
|
-
|
151
|
-
Defined profiles in cucumber.yml:
|
152
|
-
* #{cucumber_yml.keys.join("\n * ")}
|
153
|
-
END_OF_ERROR
|
154
|
-
elsif !args_from_yml.is_a?(String)
|
155
|
-
exit_with_error "Profiles must be defined as a String. The '#{profile}' profile was #{args_from_yml.inspect} (#{args_from_yml.class}).\n"
|
156
|
-
else
|
157
|
-
parse_options!(args_from_yml.split(' '))
|
158
|
-
end
|
159
|
-
end
|
160
148
|
|
161
149
|
def execute!(step_mother, executor, features)
|
162
150
|
Term::ANSIColor.coloring = @options[:color] unless @options[:color].nil?
|
163
151
|
Cucumber.load_language(@options[:lang])
|
164
152
|
require_files
|
153
|
+
enable_diffing
|
165
154
|
executor.formatters = build_formatter_broadcaster(step_mother)
|
166
155
|
load_plain_text_features(features)
|
167
156
|
executor.lines_for_features = @options[:lines_for_features]
|
@@ -183,20 +172,60 @@ Defined profiles in cucumber.yml:
|
|
183
172
|
arg
|
184
173
|
end
|
185
174
|
end
|
186
|
-
|
175
|
+
|
176
|
+
def cucumber_yml
|
177
|
+
return @cucumber_yml if @cucumber_yml
|
178
|
+
unless File.exist?('cucumber.yml')
|
179
|
+
raise(YmlLoadError,"cucumber.yml was not found. Please refer to cucumber's documentaion 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")
|
180
|
+
end
|
181
|
+
|
182
|
+
require 'yaml'
|
183
|
+
begin
|
184
|
+
@cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
185
|
+
rescue Exception => e
|
186
|
+
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentaion on correct profile usage.\n")
|
187
|
+
end
|
188
|
+
|
189
|
+
if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
|
190
|
+
raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentaion on correct profile usage.\n")
|
191
|
+
end
|
192
|
+
|
193
|
+
return @cucumber_yml
|
194
|
+
end
|
195
|
+
|
196
|
+
def parse_args_from_profile(profile)
|
197
|
+
unless cucumber_yml.has_key?(profile)
|
198
|
+
return(exit_with_error <<-END_OF_ERROR)
|
199
|
+
Could not find profile: '#{profile}'
|
200
|
+
|
201
|
+
Defined profiles in cucumber.yml:
|
202
|
+
* #{cucumber_yml.keys.join("\n * ")}
|
203
|
+
END_OF_ERROR
|
204
|
+
end
|
205
|
+
|
206
|
+
args_from_yml = cucumber_yml[profile] || ''
|
207
|
+
|
208
|
+
if !args_from_yml.is_a?(String)
|
209
|
+
exit_with_error "Profiles must be defined as a String. The '#{profile}' profile was #{args_from_yml.inspect} (#{args_from_yml.class}).\n"
|
210
|
+
elsif args_from_yml =~ /^\s*$/
|
211
|
+
exit_with_error "The 'foo' profile in cucumber.yml was blank. Please define the command line arguments for the 'foo' profile in cucumber.yml.\n"
|
212
|
+
else
|
213
|
+
parse_options!(args_from_yml.split(' '))
|
214
|
+
end
|
215
|
+
|
216
|
+
rescue YmlLoadError => e
|
217
|
+
exit_with_error(e.message)
|
218
|
+
end
|
219
|
+
|
220
|
+
|
187
221
|
# Requires files - typically step files and ruby feature files.
|
188
222
|
def require_files
|
189
|
-
|
223
|
+
@args.clear # Shut up RSpec
|
190
224
|
require "cucumber/treetop_parser/feature_#{@options[:lang]}"
|
191
225
|
require "cucumber/treetop_parser/feature_parser"
|
192
226
|
|
193
227
|
verbose_log("Ruby files required:")
|
194
|
-
|
195
|
-
libs = requires.map do |path|
|
196
|
-
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
197
|
-
File.directory?(path) ? Dir["#{path}/**/*.rb"] : path
|
198
|
-
end.flatten.uniq
|
199
|
-
libs.each do |lib|
|
228
|
+
files_to_require.each do |lib|
|
200
229
|
begin
|
201
230
|
require lib
|
202
231
|
verbose_log(" * #{lib}")
|
@@ -207,6 +236,15 @@ Defined profiles in cucumber.yml:
|
|
207
236
|
end
|
208
237
|
verbose_log("\n")
|
209
238
|
end
|
239
|
+
|
240
|
+
def files_to_require
|
241
|
+
requires = @options[:require] || feature_dirs
|
242
|
+
files = requires.map do |path|
|
243
|
+
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
244
|
+
File.directory?(path) ? Dir["#{path}/**/*.rb"] : path
|
245
|
+
end.flatten.uniq
|
246
|
+
files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }
|
247
|
+
end
|
210
248
|
|
211
249
|
def feature_files
|
212
250
|
potential_feature_files = @paths.map do |path|
|
@@ -280,14 +318,14 @@ Defined profiles in cucumber.yml:
|
|
280
318
|
private
|
281
319
|
|
282
320
|
def constantize(camel_cased_word)
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
321
|
+
names = camel_cased_word.split('::')
|
322
|
+
names.shift if names.empty? || names.first.empty?
|
323
|
+
|
324
|
+
constant = Object
|
325
|
+
names.each do |name|
|
326
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
327
|
+
end
|
328
|
+
constant
|
291
329
|
end
|
292
330
|
|
293
331
|
def verbose_log(string)
|
@@ -303,6 +341,13 @@ Defined profiles in cucumber.yml:
|
|
303
341
|
Kernel.exit 1
|
304
342
|
end
|
305
343
|
|
344
|
+
def enable_diffing
|
345
|
+
if defined?(::Spec)
|
346
|
+
require 'spec/expectations/differs/default'
|
347
|
+
options = ::Spec::Runner::Options.new(nil, nil)
|
348
|
+
::Spec::Expectations.differ = ::Spec::Expectations::Differs::Default.new(options)
|
349
|
+
end
|
350
|
+
end
|
306
351
|
end
|
307
352
|
end
|
308
353
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Exception
|
2
|
+
CUCUMBER_FILTER_PATTERNS = [
|
3
|
+
/vendor\/rails/,
|
4
|
+
/vendor\/plugins\/cucumber/,
|
5
|
+
/spec\/expectations/,
|
6
|
+
/spec\/matchers/
|
7
|
+
]
|
8
|
+
|
9
|
+
def self.cucumber_full_backtrace=(v)
|
10
|
+
@@cucumber_full_backtrace = v
|
11
|
+
end
|
12
|
+
self.cucumber_full_backtrace = false
|
13
|
+
|
14
|
+
def cucumber_backtrace
|
15
|
+
return (backtrace || []) if @@cucumber_full_backtrace
|
16
|
+
(backtrace || []).map {|b| b.split("\n") }.flatten.reject do |line|
|
17
|
+
CUCUMBER_FILTER_PATTERNS.detect{|p| line =~ p}
|
18
|
+
end.map { |line| line.strip }
|
19
|
+
end
|
20
|
+
end
|
data/lib/cucumber/executor.rb
CHANGED
@@ -65,6 +65,10 @@ module Cucumber
|
|
65
65
|
visit_scenario(scenario)
|
66
66
|
end
|
67
67
|
|
68
|
+
def visit_scenario_outline(scenario)
|
69
|
+
visit_regular_scenario(scenario)
|
70
|
+
end
|
71
|
+
|
68
72
|
def visit_scenario(scenario)
|
69
73
|
if accept_scenario?(scenario)
|
70
74
|
@executed_scenarios[scenario.name] = true
|
@@ -77,8 +81,6 @@ module Cucumber
|
|
77
81
|
@pending = nil
|
78
82
|
|
79
83
|
@world = create_world
|
80
|
-
@world.extend(Spec::Matchers) if defined?(Spec::Matchers)
|
81
|
-
define_step_call_methods(@world)
|
82
84
|
|
83
85
|
formatters.scenario_executing(scenario)
|
84
86
|
@before_scenario_procs.each{|p| p.call_in(@world, *[])}
|
@@ -104,6 +106,11 @@ module Cucumber
|
|
104
106
|
visit_step(step)
|
105
107
|
end
|
106
108
|
|
109
|
+
def visit_step_outline(step)
|
110
|
+
regexp, args, proc = step.regexp_args_proc(@step_mother)
|
111
|
+
formatters.step_traced(step, regexp, args)
|
112
|
+
end
|
113
|
+
|
107
114
|
def visit_step(step)
|
108
115
|
unless @pending || @error
|
109
116
|
begin
|
@@ -112,6 +119,9 @@ module Cucumber
|
|
112
119
|
step.execute_in(@world, regexp, args, proc)
|
113
120
|
@after_step_procs.each{|p| p.call_in(@world, *[])}
|
114
121
|
formatters.step_passed(step, regexp, args)
|
122
|
+
rescue ForcedPending => e
|
123
|
+
step.error = e
|
124
|
+
record_pending_step(step, regexp, args)
|
115
125
|
rescue Pending
|
116
126
|
record_pending_step(step, regexp, args)
|
117
127
|
rescue => e
|
@@ -124,6 +134,9 @@ module Cucumber
|
|
124
134
|
regexp, args, proc = step.regexp_args_proc(@step_mother)
|
125
135
|
step.execute_in(@world, regexp, args, proc)
|
126
136
|
formatters.step_skipped(step, regexp, args)
|
137
|
+
rescue ForcedPending => e
|
138
|
+
step.error = e
|
139
|
+
record_pending_step(step, regexp, args)
|
127
140
|
rescue Pending
|
128
141
|
record_pending_step(step, regexp, args)
|
129
142
|
rescue Exception
|
@@ -137,22 +150,6 @@ module Cucumber
|
|
137
150
|
formatters.step_pending(step, regexp, args)
|
138
151
|
end
|
139
152
|
|
140
|
-
def define_step_call_methods(world)
|
141
|
-
world.instance_variable_set('@__executor', self)
|
142
|
-
world.instance_eval do
|
143
|
-
class << self
|
144
|
-
def run_step(name)
|
145
|
-
_, args, proc = @__executor.instance_variable_get(:@step_mother).regexp_args_proc(name)
|
146
|
-
proc.call_in(self, *args)
|
147
|
-
end
|
148
|
-
|
149
|
-
%w{given when then and but}.each do |keyword|
|
150
|
-
alias_method Cucumber.language[keyword], :run_step
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
153
|
def executing_unprepared_row_scenario?(scenario)
|
157
154
|
accept_scenario?(scenario) && !@executed_scenarios[scenario.name]
|
158
155
|
end
|
@@ -182,7 +179,27 @@ module Cucumber
|
|
182
179
|
@world_procs.each do |world_proc|
|
183
180
|
world = world_proc.call(world)
|
184
181
|
end
|
182
|
+
|
183
|
+
world.extend(World::Pending)
|
184
|
+
world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
|
185
|
+
define_step_call_methods(world)
|
185
186
|
world
|
186
187
|
end
|
188
|
+
|
189
|
+
def define_step_call_methods(world)
|
190
|
+
world.instance_variable_set('@__executor', self)
|
191
|
+
world.instance_eval do
|
192
|
+
class << self
|
193
|
+
def run_step(name)
|
194
|
+
_, args, proc = @__executor.instance_variable_get(:@step_mother).regexp_args_proc(name)
|
195
|
+
proc.call_in(self, *args)
|
196
|
+
end
|
197
|
+
|
198
|
+
%w{given when then and but}.each do |keyword|
|
199
|
+
alias_method Cucumber.language[keyword], :run_step
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
187
204
|
end
|
188
205
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Hack to work around Win32/Console, which bundles a licence-violating, outdated
|
2
|
-
# copy of term/ansicolor that doesn't implement Term::ANSIColor#coloring=.
|
2
|
+
# copy of term/ansicolor that doesn't implement Term::ANSIColor#coloring=.
|
3
3
|
# We want the official one!
|
4
4
|
gem 'term-ansicolor'
|
5
5
|
$LOAD_PATH.each{|path| $LOAD_PATH.unshift($LOAD_PATH.delete(path)) if path =~ /term-ansicolor/}
|
@@ -7,7 +7,7 @@ require 'term/ansicolor'
|
|
7
7
|
|
8
8
|
if $CUCUMBER_WINDOWS_MRI
|
9
9
|
begin
|
10
|
-
require 'Win32/Console/ANSI'
|
10
|
+
require 'Win32/Console/ANSI'
|
11
11
|
rescue LoadError
|
12
12
|
STDERR.puts "You must gem install win32console to get coloured output on MRI/Windows"
|
13
13
|
Term::ANSIColor.coloring = false
|
@@ -18,92 +18,83 @@ Term::ANSIColor.coloring = false if !STDOUT.tty? || ($CUCUMBER_WINDOWS && !$CUCU
|
|
18
18
|
|
19
19
|
module Cucumber
|
20
20
|
module Formatters
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# Defines aliases for coloured output. You can tweak the colours by defining
|
22
|
+
# a <tt>$CUCUMBER_COLORS</tt> variable in your shell, very much like you can
|
23
|
+
# tweak the familiar POSIX command <tt>ls</tt> with
|
24
|
+
# <a href="http://mipsisrisc.com/rambling/2008/06/27/lscolorsls_colors-now-with-linux-support/">$LSCOLORS/$LS_COLORS</a>
|
23
25
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# The string must be a series of key=value pairs where:
|
26
|
+
# The colours that you can change are:
|
27
27
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# ** bold
|
39
|
-
# ** dark
|
40
|
-
# ** italic
|
41
|
-
# ** underline
|
42
|
-
# ** underscore
|
43
|
-
# ** blink
|
44
|
-
# ** rapid_blink
|
45
|
-
# ** negative
|
46
|
-
# ** concealed
|
47
|
-
# ** strikethrough
|
48
|
-
# ** black
|
49
|
-
# ** red
|
50
|
-
# ** green
|
51
|
-
# ** yellow
|
52
|
-
# ** blue
|
53
|
-
# ** magenta
|
54
|
-
# ** cyan
|
55
|
-
# ** white
|
56
|
-
# ** grey
|
57
|
-
# ** on_black
|
58
|
-
# ** on_red
|
59
|
-
# ** on_green
|
60
|
-
# ** on_yellow
|
61
|
-
# ** on_blue
|
62
|
-
# ** on_magenta
|
63
|
-
# ** on_cyan
|
64
|
-
# ** on_white
|
28
|
+
# * <tt>pending</tt> - defaults to <tt>yellow</tt>
|
29
|
+
# * <tt>pending_param</tt> - defaults to <tt>yellow,bold</tt>
|
30
|
+
# * <tt>failed</tt> - defaults to <tt>red</tt>
|
31
|
+
# * <tt>failed_param</tt> - defaults to <tt>red,bold</tt>
|
32
|
+
# * <tt>passed</tt> - defaults to <tt>green</tt>
|
33
|
+
# * <tt>passed_param</tt> - defaults to <tt>green,bold</tt>
|
34
|
+
# * <tt>skipped</tt> - defaults to <tt>cyan</tt>
|
35
|
+
# * <tt>skipped_param</tt> - defaults to <tt>cyan,bold</tt>
|
36
|
+
# * <tt>comment</tt> - defaults to <tt>grey</tt>
|
37
|
+
# * <tt>tag</tt> - defaults to <tt>blue</tt>
|
65
38
|
#
|
39
|
+
# For instance, if your shell has a black background and a green font (like the
|
40
|
+
# "Homebrew" settings for OS X' Terminal.app), you may want to override passed
|
41
|
+
# steps to be white instead of green. Examples:
|
42
|
+
#
|
43
|
+
# export CUCUMBER_COLORS="passed=white"
|
44
|
+
# export CUCUMBER_COLORS="passed=white,bold:passed_param=white,bold,underline"
|
45
|
+
#
|
46
|
+
# (If you're on Windows, use SET instead of export).
|
47
|
+
# To see what colours and effects are available, just run this in your shell:
|
48
|
+
#
|
49
|
+
# ruby -e "require 'rubygems'; require 'term/ansicolor'; puts Term::ANSIColor.attributes"
|
50
|
+
#
|
51
|
+
# Although not listed, you can also use <tt>grey</tt>
|
66
52
|
module ANSIColor
|
67
|
-
include
|
68
|
-
|
69
|
-
# Params are underlined bold, except in windows, which doesn't support underline. Use non-bold colour.
|
70
|
-
param = PLATFORM =~ /mswin|mingw/ ? '' : 'underline,bold,'
|
53
|
+
include Term::ANSIColor
|
71
54
|
|
72
|
-
# Default aliases
|
73
|
-
ALIASES = {
|
74
|
-
:passed => 'bold,green',
|
75
|
-
:passed_param => "#{param}green",
|
76
|
-
:failed => 'bold,red',
|
77
|
-
:failed_param => "#{param}red",
|
78
|
-
:skipped => 'bold,cyan',
|
79
|
-
:skipped_param => "#{param}cyan",
|
80
|
-
:pending => 'bold,yellow', # No pending_param
|
81
|
-
:comment => 'grey'
|
82
|
-
}
|
83
|
-
if ENV['CUCUMBER_COLORS']
|
84
|
-
ENV['CUCUMBER_COLORS'].split(':').each do |pair|
|
85
|
-
a = pair.split('=')
|
86
|
-
ALIASES[a[0].to_sym] = a[1]
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
55
|
# Not supported in Term::ANSIColor
|
91
56
|
def grey(m)
|
92
57
|
if ::Term::ANSIColor.coloring?
|
93
|
-
"\e[90m#{m}\e[0m"
|
58
|
+
"\e[90m#{m}\e[0m"
|
94
59
|
else
|
95
60
|
m
|
96
61
|
end
|
97
62
|
end
|
98
|
-
|
99
|
-
ALIASES.
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
63
|
+
|
64
|
+
ALIASES = Hash.new do |h,k|
|
65
|
+
if k.to_s =~ /(.*)_param/
|
66
|
+
h[$1] + ',bold'
|
67
|
+
end
|
68
|
+
end.merge({
|
69
|
+
'pending' => 'yellow',
|
70
|
+
'failed' => 'red',
|
71
|
+
'passed' => 'green',
|
72
|
+
'skipped' => 'cyan',
|
73
|
+
'comment' => 'grey',
|
74
|
+
'tag' => 'blue'
|
75
|
+
})
|
76
|
+
|
77
|
+
if ENV['CUCUMBER_COLORS'] # Example: export CUCUMBER_COLORS="passed=red:failed=yellow"
|
78
|
+
ENV['CUCUMBER_COLORS'].split(':').each do |pair|
|
79
|
+
a = pair.split('=')
|
80
|
+
ALIASES[a[0]] = a[1]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
ALIASES.each do |method, color|
|
85
|
+
unless method =~ /.*_param/
|
86
|
+
code = <<-EOF
|
87
|
+
def #{method}(string=nil, &proc)
|
88
|
+
#{ALIASES[method].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method].split(",").length}
|
104
89
|
end
|
90
|
+
# This resets the colour to the non-param colour
|
91
|
+
def #{method}_param(string=nil, &proc)
|
92
|
+
#{ALIASES[method+'_param'].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method+'_param'].split(",").length} + #{ALIASES[method].split(",").join(' + ')}
|
93
|
+
end
|
94
|
+
EOF
|
95
|
+
eval(code)
|
105
96
|
end
|
106
97
|
end
|
107
98
|
end
|
108
99
|
end
|
109
|
-
end
|
100
|
+
end
|