cucumber 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -1
- data/LICENSE +1 -1
- data/Rakefile +5 -51
- data/bin/cucumber +7 -1
- data/cucumber.gemspec +463 -679
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/he/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +4 -7
- data/examples/i18n/ru/features/division.feature +2 -2
- data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +3 -3
- data/examples/sinatra/features/support/env.rb +2 -5
- data/examples/v8/features/fibonacci.feature +1 -1
- data/examples/watir/features/step_definitions/search_steps.rb +1 -1
- data/features/background.feature +284 -95
- data/features/custom_formatter.feature +3 -73
- data/features/json_formatter.feature +160 -245
- data/features/step_definitions/cucumber_steps.rb +7 -153
- data/features/support/env.rb +18 -140
- data/fixtures/junit/features/pending.feature +3 -1
- data/fixtures/self_test/features/support/env.rb +8 -0
- data/fixtures/tickets/features.html +1 -1
- data/gem_tasks/examples.rake +1 -1
- data/lib/cucumber.rb +12 -0
- data/lib/cucumber/ast.rb +1 -1
- data/lib/cucumber/ast/background.rb +21 -5
- data/lib/cucumber/ast/examples.rb +12 -4
- data/lib/cucumber/ast/feature.rb +13 -5
- data/lib/cucumber/ast/feature_element.rb +9 -4
- data/lib/cucumber/ast/outline_table.rb +4 -4
- data/lib/cucumber/ast/scenario.rb +7 -5
- data/lib/cucumber/ast/scenario_outline.rb +23 -15
- data/lib/cucumber/ast/step.rb +5 -0
- data/lib/cucumber/ast/step_invocation.rb +21 -15
- data/lib/cucumber/ast/table.rb +14 -8
- data/lib/cucumber/ast/tree_walker.rb +10 -48
- data/lib/cucumber/cli/configuration.rb +33 -8
- data/lib/cucumber/cli/main.rb +20 -35
- data/lib/cucumber/cli/options.rb +8 -7
- data/lib/cucumber/cli/profile_loader.rb +2 -0
- data/lib/cucumber/core_ext/proc.rb +2 -1
- data/lib/cucumber/feature_file.rb +47 -15
- data/lib/cucumber/formatter/ansicolor.rb +3 -5
- data/lib/cucumber/formatter/console.rb +27 -23
- data/lib/cucumber/formatter/cucumber.css +34 -17
- data/lib/cucumber/formatter/cucumber.sass +173 -182
- data/lib/cucumber/formatter/html.rb +46 -11
- data/lib/cucumber/formatter/io.rb +2 -4
- data/lib/cucumber/formatter/json.rb +15 -152
- data/lib/cucumber/formatter/json_pretty.rb +5 -6
- data/lib/cucumber/formatter/junit.rb +28 -22
- data/lib/cucumber/formatter/pdf.rb +6 -6
- data/lib/cucumber/formatter/pretty.rb +5 -5
- data/lib/cucumber/formatter/rerun.rb +22 -11
- data/lib/cucumber/formatter/unicode.rb +41 -20
- data/lib/cucumber/js_support/js_dsl.js +4 -4
- data/lib/cucumber/js_support/js_language.rb +9 -5
- data/lib/cucumber/js_support/js_snippets.rb +2 -2
- data/lib/cucumber/language_support.rb +2 -2
- data/lib/cucumber/parser/gherkin_builder.rb +35 -30
- data/lib/cucumber/platform.rb +8 -8
- data/lib/cucumber/py_support/py_language.rb +2 -2
- data/lib/cucumber/rake/task.rb +80 -31
- data/lib/cucumber/rb_support/rb_dsl.rb +1 -0
- data/lib/cucumber/rb_support/rb_language.rb +10 -8
- data/lib/cucumber/rb_support/rb_step_definition.rb +8 -0
- data/lib/cucumber/rb_support/rb_transform.rb +17 -0
- data/lib/cucumber/rb_support/rb_world.rb +26 -18
- data/lib/cucumber/rspec/doubles.rb +3 -3
- data/lib/cucumber/step_match.rb +6 -2
- data/lib/cucumber/step_mother.rb +6 -427
- data/lib/cucumber/wire_support/configuration.rb +4 -1
- data/lib/cucumber/wire_support/wire_language.rb +3 -10
- data/spec/cucumber/ast/background_spec.rb +68 -6
- data/spec/cucumber/ast/feature_factory.rb +5 -4
- data/spec/cucumber/ast/feature_spec.rb +4 -4
- data/spec/cucumber/ast/outline_table_spec.rb +1 -1
- data/spec/cucumber/ast/scenario_outline_spec.rb +15 -11
- data/spec/cucumber/ast/scenario_spec.rb +4 -4
- data/spec/cucumber/ast/step_spec.rb +3 -3
- data/spec/cucumber/ast/table_spec.rb +38 -2
- data/spec/cucumber/ast/tree_walker_spec.rb +2 -2
- data/spec/cucumber/broadcaster_spec.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +32 -6
- data/spec/cucumber/cli/drb_client_spec.rb +2 -3
- data/spec/cucumber/cli/main_spec.rb +43 -43
- data/spec/cucumber/cli/options_spec.rb +28 -1
- data/spec/cucumber/cli/profile_loader_spec.rb +1 -1
- data/spec/cucumber/core_ext/proc_spec.rb +1 -1
- data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
- data/spec/cucumber/formatter/duration_spec.rb +1 -1
- data/spec/cucumber/formatter/html_spec.rb +3 -5
- data/spec/cucumber/formatter/junit_spec.rb +16 -2
- data/spec/cucumber/formatter/progress_spec.rb +1 -1
- data/spec/cucumber/formatter/spec_helper.rb +11 -12
- data/spec/cucumber/rb_support/rb_language_spec.rb +241 -28
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +33 -28
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +1 -1
- data/spec/cucumber/step_match_spec.rb +11 -9
- data/spec/cucumber/wire_support/configuration_spec.rb +1 -1
- data/spec/cucumber/wire_support/connection_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_exception_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_language_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_packet_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_step_definition_spec.rb +1 -1
- data/spec/cucumber/world/pending_spec.rb +2 -2
- data/spec/spec_helper.rb +13 -20
- metadata +11 -222
- data/.gitignore +0 -20
- data/Caliper.yml +0 -4
- data/History.txt +0 -1552
- data/README.rdoc +0 -26
- data/VERSION.yml +0 -5
- data/examples/i18n/ro/features/suma.feature +0 -11
- data/features/announce.feature +0 -164
- data/features/around_hooks.feature +0 -232
- data/features/bug_371.feature +0 -32
- data/features/bug_464.feature +0 -16
- data/features/bug_475.feature +0 -42
- data/features/bug_585_tab_indentation.feature +0 -22
- data/features/bug_600.feature +0 -67
- data/features/call_steps_from_stepdefs.feature +0 -154
- data/features/cucumber_cli.feature +0 -591
- data/features/cucumber_cli_outlines.feature +0 -117
- data/features/default_snippets.feature +0 -42
- data/features/diffing.feature +0 -25
- data/features/drb_server_integration.feature +0 -174
- data/features/exception_in_after_block.feature +0 -127
- data/features/exception_in_after_step_block.feature +0 -104
- data/features/exception_in_before_block.feature +0 -98
- data/features/exclude_files.feature +0 -20
- data/features/expand.feature +0 -60
- data/features/html_formatter.feature +0 -8
- data/features/html_formatter/a.html +0 -582
- data/features/junit_formatter.feature +0 -88
- data/features/language_from_header.feature +0 -30
- data/features/language_help.feature +0 -78
- data/features/listener_debugger_formatter.feature +0 -42
- data/features/multiline_names.feature +0 -44
- data/features/negative_tagged_hooks.feature +0 -60
- data/features/post_configuration_hook.feature +0 -37
- data/features/profiles.feature +0 -126
- data/features/rake_task.feature +0 -152
- data/features/report_called_undefined_steps.feature +0 -34
- data/features/rerun_formatter.feature +0 -45
- data/features/simplest.feature +0 -11
- data/features/snippet.feature +0 -23
- data/features/snippets_when_using_star_keyword.feature +0 -36
- data/features/step_definitions/extra_steps.rb +0 -2
- data/features/step_definitions/simplest_steps.rb +0 -3
- data/features/step_definitions/wire_steps.rb +0 -32
- data/features/support/env.rb.simplest +0 -7
- data/features/support/fake_wire_server.rb +0 -77
- data/features/table_diffing.feature +0 -45
- data/features/table_mapping.feature +0 -34
- data/features/tag_logic.feature +0 -258
- data/features/transform.feature +0 -245
- data/features/unicode_table.feature +0 -35
- data/features/usage_and_stepdefs_formatter.feature +0 -169
- data/features/wire_protocol.feature +0 -332
- data/features/wire_protocol_table_diffing.feature +0 -119
- data/features/wire_protocol_tags.feature +0 -87
- data/features/wire_protocol_timeouts.feature +0 -63
- data/features/work_in_progress.feature +0 -156
- data/fixtures/json/features/pystring.feature +0 -8
- data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +0 -12
- data/fixtures/self_test/features/background/background_with_name.feature +0 -7
- data/fixtures/self_test/features/background/failing_background.feature +0 -12
- data/fixtures/self_test/features/background/failing_background_after_success.feature +0 -11
- data/fixtures/self_test/features/background/multiline_args_background.feature +0 -32
- data/fixtures/self_test/features/background/passing_background.feature +0 -10
- data/fixtures/self_test/features/background/pending_background.feature +0 -10
- data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +0 -16
- data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +0 -16
- data/gem_tasks/features.rake +0 -14
- data/gem_tasks/sdoc.rake +0 -12
- data/lib/cucumber/ast/py_string.rb +0 -80
- data/lib/cucumber/formatter/color_io.rb +0 -23
- data/lib/cucumber/formatter/tag_cloud.rb +0 -35
- data/spec/cucumber/ast/py_string_spec.rb +0 -40
- data/spec/cucumber/formatter/color_io_spec.rb +0 -29
- data/spec/cucumber/step_mother_spec.rb +0 -302
data/lib/cucumber/rake/task.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
require 'cucumber/platform'
|
2
|
+
require 'gherkin/formatter/ansi_escapes'
|
3
|
+
|
4
|
+
begin
|
5
|
+
# Support Rake > 0.8.7
|
6
|
+
require 'rake/dsl_definition'
|
7
|
+
include Rake::DSL
|
8
|
+
rescue LoadError
|
9
|
+
end
|
2
10
|
|
3
11
|
module Cucumber
|
4
12
|
module Rake
|
@@ -8,7 +16,7 @@ module Cucumber
|
|
8
16
|
#
|
9
17
|
# Cucumber::Rake::Task.new
|
10
18
|
#
|
11
|
-
# This will define a task named <tt>cucumber</tt> described as 'Run Cucumber features'.
|
19
|
+
# This will define a task named <tt>cucumber</tt> described as 'Run Cucumber features'.
|
12
20
|
# It will use steps from 'features/**/*.rb' and features in 'features/**/*.feature'.
|
13
21
|
#
|
14
22
|
# To further configure the task, you can pass a block:
|
@@ -22,68 +30,96 @@ module Cucumber
|
|
22
30
|
# Cucumber::Rake::Task.new do |t|
|
23
31
|
# t.rcov = true
|
24
32
|
# end
|
25
|
-
#
|
33
|
+
#
|
26
34
|
# See the attributes for additional configuration possibilities.
|
27
35
|
class Task
|
36
|
+
include Gherkin::Formatter::AnsiEscapes
|
37
|
+
|
28
38
|
class InProcessCucumberRunner #:nodoc:
|
29
39
|
attr_reader :args
|
30
|
-
|
40
|
+
|
31
41
|
def initialize(libs, cucumber_opts, feature_files)
|
32
42
|
raise "libs must be an Array when running in-process" unless Array === libs
|
33
43
|
libs.reverse.each{|lib| $LOAD_PATH.unshift(lib)}
|
34
44
|
@args = (
|
35
|
-
cucumber_opts +
|
45
|
+
cucumber_opts +
|
36
46
|
feature_files
|
37
47
|
).flatten.compact
|
38
48
|
end
|
39
|
-
|
49
|
+
|
40
50
|
def run
|
41
51
|
require 'cucumber/cli/main'
|
42
52
|
failure = Cucumber::Cli::Main.execute(args)
|
43
53
|
raise "Cucumber failed" if failure
|
44
54
|
end
|
45
55
|
end
|
46
|
-
|
56
|
+
|
47
57
|
class ForkedCucumberRunner #:nodoc:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
feature_files
|
56
|
-
).flatten
|
58
|
+
|
59
|
+
def initialize(libs, cucumber_bin, cucumber_opts, bundler, feature_files)
|
60
|
+
@libs = libs
|
61
|
+
@cucumber_bin = cucumber_bin
|
62
|
+
@cucumber_opts = cucumber_opts
|
63
|
+
@bundler = bundler
|
64
|
+
@feature_files = feature_files
|
57
65
|
end
|
58
66
|
|
59
67
|
def load_path(libs)
|
60
|
-
['"%s"' % libs.join(File::PATH_SEPARATOR)]
|
68
|
+
['"%s"' % @libs.join(File::PATH_SEPARATOR)]
|
61
69
|
end
|
62
70
|
|
63
71
|
def quoted_binary(cucumber_bin)
|
64
72
|
['"%s"' % cucumber_bin]
|
65
73
|
end
|
66
74
|
|
67
|
-
def
|
68
|
-
File.exist?("./Gemfile") ?
|
75
|
+
def use_bundler
|
76
|
+
@bundler.nil? ? File.exist?("./Gemfile") && gem_available?("bundler") : @bundler
|
77
|
+
end
|
78
|
+
|
79
|
+
def gem_available?(gemname)
|
80
|
+
gem_available_new_rubygems?(gemname) || gem_available_old_rubygems?(gemname)
|
81
|
+
end
|
82
|
+
|
83
|
+
def gem_available_old_rubygems?(gemname)
|
84
|
+
Gem.available?(gemname)
|
85
|
+
end
|
86
|
+
|
87
|
+
def gem_available_new_rubygems?(gemname)
|
88
|
+
Gem::Specification.respond_to?(:find_all_by_name) && Gem::Specification.find_all_by_name(gemname).any?
|
89
|
+
end
|
90
|
+
|
91
|
+
def cmd
|
92
|
+
if use_bundler
|
93
|
+
[ Cucumber::RUBY_BINARY, '-S', 'bundle', 'exec', 'cucumber', @cucumber_opts,
|
94
|
+
@feature_files ].flatten
|
95
|
+
else
|
96
|
+
[ Cucumber::RUBY_BINARY, '-I', load_path(@libs), quoted_binary(@cucumber_bin),
|
97
|
+
@cucumber_opts, @feature_files ].flatten
|
98
|
+
end
|
69
99
|
end
|
70
100
|
|
71
101
|
def run
|
72
|
-
sh(
|
102
|
+
sh(cmd.join(" "))
|
73
103
|
end
|
74
104
|
end
|
75
105
|
|
76
106
|
class RCovCucumberRunner < ForkedCucumberRunner #:nodoc:
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
107
|
+
|
108
|
+
def initialize(libs, cucumber_bin, cucumber_opts, bundler, feature_files, rcov_opts)
|
109
|
+
super( libs, cucumber_bin, cucumber_opts, bundler, feature_files )
|
110
|
+
@rcov_opts = rcov_opts
|
111
|
+
end
|
112
|
+
|
113
|
+
def cmd
|
114
|
+
if use_bundler
|
115
|
+
[Cucumber::RUBY_BINARY, '-S', 'bundle', 'exec', 'rcov', @rcov_opts,
|
116
|
+
quoted_binary(@cucumber_bin), '--', @cucumber_opts, @feature_files].flatten
|
117
|
+
else
|
118
|
+
[Cucumber::RUBY_BINARY, '-I', load_path(@libs), '-S', 'rcov', @rcov_opts,
|
119
|
+
quoted_binary(@cucumber_bin), '--', @cucumber_opts, @feature_files].flatten
|
120
|
+
end
|
86
121
|
end
|
122
|
+
|
87
123
|
end
|
88
124
|
|
89
125
|
LIB = File.expand_path(File.dirname(__FILE__) + '/../..') #:nodoc:
|
@@ -104,6 +140,12 @@ module Cucumber
|
|
104
140
|
# Run cucumber with RCov? Defaults to false. If you set this to
|
105
141
|
# true, +fork+ is implicit.
|
106
142
|
attr_accessor :rcov
|
143
|
+
def rcov=(flag)
|
144
|
+
if(flag && Cucumber::RUBY_1_9)
|
145
|
+
raise failed + "RCov only works on Ruby 1.8.x. You may want to use SimpleCov: https://github.com/colszowka/simplecov" + reset
|
146
|
+
end
|
147
|
+
@rcov = flag
|
148
|
+
end
|
107
149
|
|
108
150
|
# Extra options to pass to rcov.
|
109
151
|
# It's recommended to pass an Array, but if it's a String it will be #split by ' '.
|
@@ -117,10 +159,17 @@ module Cucumber
|
|
117
159
|
# your load path and gems.
|
118
160
|
attr_accessor :fork
|
119
161
|
|
120
|
-
# Define what profile to be used. When used with cucumber_opts it is simply appended
|
162
|
+
# Define what profile to be used. When used with cucumber_opts it is simply appended
|
121
163
|
# to it. Will be ignored when CUCUMBER_OPTS is used.
|
122
164
|
attr_accessor :profile
|
123
165
|
|
166
|
+
# Whether or not to run with bundler (bundle exec). Setting this to false may speed
|
167
|
+
# up the execution. The default value is true if Bundler is installed and you have
|
168
|
+
# a Gemfile, false otherwise.
|
169
|
+
#
|
170
|
+
# Note that this attribute has no effect if you don't run in forked mode.
|
171
|
+
attr_accessor :bundler
|
172
|
+
|
124
173
|
# Define Cucumber Rake task
|
125
174
|
def initialize(task_name = "cucumber", desc = "Run Cucumber features")
|
126
175
|
@task_name, @desc = task_name, desc
|
@@ -146,9 +195,9 @@ module Cucumber
|
|
146
195
|
def runner(task_args = nil) #:nodoc:
|
147
196
|
cucumber_opts = [(ENV['CUCUMBER_OPTS'] ? ENV['CUCUMBER_OPTS'].split(/\s+/) : nil) || cucumber_opts_with_profile]
|
148
197
|
if(@rcov)
|
149
|
-
RCovCucumberRunner.new(libs, binary, cucumber_opts, feature_files, rcov_opts)
|
198
|
+
RCovCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files, rcov_opts)
|
150
199
|
elsif(@fork)
|
151
|
-
ForkedCucumberRunner.new(libs, binary, cucumber_opts, feature_files)
|
200
|
+
ForkedCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files)
|
152
201
|
else
|
153
202
|
InProcessCucumberRunner.new(libs, cucumber_opts, feature_files)
|
154
203
|
end
|
@@ -88,6 +88,7 @@ module Cucumber
|
|
88
88
|
|
89
89
|
# Registers a proc that will run after Cucumber is configured. You can register as
|
90
90
|
# as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
|
91
|
+
# TODO: Deprecate this
|
91
92
|
def AfterConfiguration(&proc)
|
92
93
|
RbDsl.register_rb_hook('after_configuration', [], proc)
|
93
94
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cucumber/core_ext/instance_exec'
|
1
2
|
require 'cucumber/rb_support/rb_dsl'
|
2
3
|
require 'cucumber/rb_support/rb_world'
|
3
4
|
require 'cucumber/rb_support/rb_step_definition'
|
@@ -21,7 +22,7 @@ module Cucumber
|
|
21
22
|
message << first_proc.backtrace_line('World') << "\n"
|
22
23
|
message << second_proc.backtrace_line('World') << "\n\n"
|
23
24
|
message << "Use Ruby modules instead to extend your worlds. See the Cucumber::RbSupport::RbDsl#World RDoc\n"
|
24
|
-
message << "or http://wiki.github.com/
|
25
|
+
message << "or http://wiki.github.com/cucumber/cucumber/a-whole-new-world.\n\n"
|
25
26
|
super(message)
|
26
27
|
end
|
27
28
|
end
|
@@ -29,7 +30,8 @@ module Cucumber
|
|
29
30
|
# The Ruby implementation of the programming language API.
|
30
31
|
class RbLanguage
|
31
32
|
include LanguageSupport::LanguageMethods
|
32
|
-
attr_reader :current_world
|
33
|
+
attr_reader :current_world,
|
34
|
+
:step_definitions
|
33
35
|
|
34
36
|
Gherkin::I18n.code_keywords.each do |adverb|
|
35
37
|
RbDsl.alias_adverb(adverb)
|
@@ -65,7 +67,7 @@ module Cucumber
|
|
65
67
|
|
66
68
|
# Gets called for each file under features (or whatever is overridden
|
67
69
|
# with --require).
|
68
|
-
def step_definitions_for(rb_file)
|
70
|
+
def step_definitions_for(rb_file) # Looks Unused - Delete?
|
69
71
|
begin
|
70
72
|
require rb_file # This will cause self.add_step_definition and self.add_hook to be called from RbDsl
|
71
73
|
step_definitions
|
@@ -76,7 +78,7 @@ module Cucumber
|
|
76
78
|
@step_definitions = nil
|
77
79
|
end
|
78
80
|
end
|
79
|
-
|
81
|
+
|
80
82
|
def step_matches(name_to_match, name_to_format)
|
81
83
|
@step_definitions.map do |step_definition|
|
82
84
|
if(arguments = step_definition.arguments_from(name_to_match))
|
@@ -89,7 +91,7 @@ module Cucumber
|
|
89
91
|
|
90
92
|
ARGUMENT_PATTERNS = ['"([^"]*)"', '(\d+)']
|
91
93
|
|
92
|
-
def snippet_text(
|
94
|
+
def snippet_text(code_keyword, step_name, multiline_arg_class)
|
93
95
|
snippet_pattern = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
|
94
96
|
arg_count = 0
|
95
97
|
ARGUMENT_PATTERNS.each do |pattern|
|
@@ -105,7 +107,7 @@ module Cucumber
|
|
105
107
|
multiline_class_comment = "# #{multiline_arg_class.default_arg_name} is a #{multiline_arg_class.to_s}\n "
|
106
108
|
end
|
107
109
|
|
108
|
-
"#{
|
110
|
+
"#{code_keyword} /^#{snippet_pattern}$/ do#{block_arg_string}\n #{multiline_class_comment}pending # express the regexp above with the code you wish you had\nend"
|
109
111
|
end
|
110
112
|
|
111
113
|
def begin_rb_scenario(scenario)
|
@@ -138,9 +140,9 @@ module Cucumber
|
|
138
140
|
end
|
139
141
|
|
140
142
|
def load_code_file(code_file)
|
141
|
-
|
143
|
+
load File.expand_path(code_file) # This will cause self.add_step_definition, self.add_hook, and self.add_transform to be called from RbDsl
|
142
144
|
end
|
143
|
-
|
145
|
+
|
144
146
|
protected
|
145
147
|
|
146
148
|
def begin_scenario(scenario)
|
@@ -38,6 +38,14 @@ module Cucumber
|
|
38
38
|
@regexp.inspect
|
39
39
|
end
|
40
40
|
|
41
|
+
def to_hash
|
42
|
+
flags = ''
|
43
|
+
flags += 'm' if (@regexp.options & Regexp::MULTILINE) != 0
|
44
|
+
flags += 'i' if (@regexp.options & Regexp::IGNORECASE) != 0
|
45
|
+
flags += 'x' if (@regexp.options & Regexp::EXTENDED) != 0
|
46
|
+
{'source' => @regexp.source, 'flags' => flags}
|
47
|
+
end
|
48
|
+
|
41
49
|
def ==(step_definition)
|
42
50
|
regexp_source == step_definition.regexp_source
|
43
51
|
end
|
@@ -32,6 +32,23 @@ module Cucumber
|
|
32
32
|
@rb_language.current_world.cucumber_instance_exec(true, @regexp.inspect, *args, &@proc)
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
strip_captures(strip_anchors(@regexp.source))
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def strip_captures(regexp_source)
|
43
|
+
regexp_source.
|
44
|
+
gsub(/(\()/, '').
|
45
|
+
gsub(/(\))/, '')
|
46
|
+
end
|
47
|
+
|
48
|
+
def strip_anchors(regexp_source)
|
49
|
+
regexp_source.
|
50
|
+
gsub(/(^\^|\$$)/, '')
|
51
|
+
end
|
35
52
|
end
|
36
53
|
end
|
37
54
|
end
|
@@ -1,7 +1,11 @@
|
|
1
|
+
require 'gherkin/formatter/ansi_escapes'
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module RbSupport
|
3
5
|
# All steps are run in the context of an object that extends this module.
|
4
6
|
module RbWorld
|
7
|
+
include Gherkin::Formatter::AnsiEscapes
|
8
|
+
|
5
9
|
class << self
|
6
10
|
def alias_adverb(adverb)
|
7
11
|
alias_method adverb, :__cucumber_invoke
|
@@ -32,14 +36,19 @@ module Cucumber
|
|
32
36
|
@__cucumber_step_mother.table(text_or_table, file, line_offset)
|
33
37
|
end
|
34
38
|
|
35
|
-
# See StepMother#
|
36
|
-
def
|
37
|
-
@__cucumber_step_mother.
|
39
|
+
# See StepMother#doc_string
|
40
|
+
def doc_string(string_with_triple_quotes, file=nil, line_offset=0)
|
41
|
+
@__cucumber_step_mother.doc_string(string_with_triple_quotes, file, line_offset)
|
42
|
+
end
|
43
|
+
|
44
|
+
def announce(*messages)
|
45
|
+
STDERR.puts failed + "WARNING: #announce is deprecated. Use #puts instead:" + caller[0] + reset
|
46
|
+
puts(*messages)
|
38
47
|
end
|
39
48
|
|
40
|
-
# See StepMother#
|
41
|
-
def
|
42
|
-
@__cucumber_step_mother.
|
49
|
+
# See StepMother#puts
|
50
|
+
def puts(*messages)
|
51
|
+
@__cucumber_step_mother.puts(*messages)
|
43
52
|
end
|
44
53
|
|
45
54
|
# See StepMother#ask
|
@@ -48,17 +57,8 @@ module Cucumber
|
|
48
57
|
end
|
49
58
|
|
50
59
|
# See StepMother#embed
|
51
|
-
def embed(file, mime_type)
|
52
|
-
@__cucumber_step_mother.embed(file, mime_type)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Prints out the world class, followed by all included modules.
|
56
|
-
def announce_world
|
57
|
-
announce "WORLD:\n #{self.class}"
|
58
|
-
world = self
|
59
|
-
(class << self; self; end).instance_eval do
|
60
|
-
world.announce " #{included_modules.join("\n ")}"
|
61
|
-
end
|
60
|
+
def embed(file, mime_type, label='Screenshot')
|
61
|
+
@__cucumber_step_mother.embed(file, mime_type, label)
|
62
62
|
end
|
63
63
|
|
64
64
|
# Mark the matched step as pending.
|
@@ -88,7 +88,15 @@ module Cucumber
|
|
88
88
|
# such errors in World we define it to just return a simple String.
|
89
89
|
#
|
90
90
|
def inspect #:nodoc:
|
91
|
-
|
91
|
+
modules = [self.class]
|
92
|
+
(class << self; self; end).instance_eval do
|
93
|
+
modules += included_modules
|
94
|
+
end
|
95
|
+
sprintf("#<%s:0x%x>", modules.join('+'), self.object_id)
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
inspect
|
92
100
|
end
|
93
101
|
end
|
94
102
|
end
|
@@ -4,13 +4,13 @@ RSpec.configuration.configure_mock_framework
|
|
4
4
|
World(RSpec::Core::MockFrameworkAdapter)
|
5
5
|
|
6
6
|
Before do
|
7
|
-
|
7
|
+
RSpec::Mocks::setup(self)
|
8
8
|
end
|
9
9
|
|
10
10
|
After do
|
11
11
|
begin
|
12
|
-
|
12
|
+
RSpec::Mocks::verify
|
13
13
|
ensure
|
14
|
-
|
14
|
+
RSpec::Mocks::teardown
|
15
15
|
end
|
16
16
|
end
|
data/lib/cucumber/step_match.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Cucumber
|
2
2
|
class StepMatch #:nodoc:
|
3
|
-
attr_reader :step_definition
|
3
|
+
attr_reader :step_definition, :step_arguments
|
4
4
|
|
5
5
|
# Creates a new StepMatch. The +name_to_report+ argument is what's reported, unless it's is,
|
6
6
|
# in which case +name_to_report+ is used instead.
|
@@ -20,7 +20,7 @@ module Cucumber
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def invoke(multiline_arg)
|
23
|
-
multiline_arg = Ast::
|
23
|
+
multiline_arg = Ast::DocString.new(multiline_arg) if String === multiline_arg
|
24
24
|
all_args = args
|
25
25
|
all_args << multiline_arg.to_step_definition_arg if multiline_arg
|
26
26
|
@step_definition.invoke(all_args)
|
@@ -107,5 +107,9 @@ module Cucumber
|
|
107
107
|
def text_length
|
108
108
|
@step.text_length
|
109
109
|
end
|
110
|
+
|
111
|
+
def step_arguments
|
112
|
+
[]
|
113
|
+
end
|
110
114
|
end
|
111
115
|
end
|
data/lib/cucumber/step_mother.rb
CHANGED
@@ -1,431 +1,10 @@
|
|
1
|
-
require 'cucumber/
|
2
|
-
require 'cucumber/core_ext/instance_exec'
|
3
|
-
require 'cucumber/language_support/language_methods'
|
4
|
-
require 'cucumber/formatter/duration'
|
5
|
-
require 'cucumber/cli/options'
|
6
|
-
require 'timeout'
|
1
|
+
require 'cucumber/runtime'
|
7
2
|
|
8
3
|
module Cucumber
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(step_name)
|
14
|
-
super %{Undefined step: "#{step_name}"}
|
15
|
-
@step_name = step_name
|
16
|
-
end
|
17
|
-
|
18
|
-
def nested!
|
19
|
-
@nested = true
|
20
|
-
end
|
21
|
-
|
22
|
-
def nested?
|
23
|
-
@nested
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Raised when a StepDefinition's block invokes World#pending
|
28
|
-
class Pending < StandardError
|
29
|
-
end
|
30
|
-
|
31
|
-
# Raised when a step matches 2 or more StepDefinitions
|
32
|
-
class Ambiguous < StandardError
|
33
|
-
def initialize(step_name, step_definitions, used_guess)
|
34
|
-
message = "Ambiguous match of \"#{step_name}\":\n\n"
|
35
|
-
message << step_definitions.map{|sd| sd.backtrace_line}.join("\n")
|
36
|
-
message << "\n\n"
|
37
|
-
message << "You can run again with --guess to make Cucumber be more smart about it\n" unless used_guess
|
38
|
-
super(message)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class TagExcess < StandardError
|
43
|
-
def initialize(messages)
|
44
|
-
super(messages.join("\n"))
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# This is the meaty part of Cucumber that ties everything together.
|
49
|
-
class StepMother
|
50
|
-
include Constantize
|
51
|
-
include Formatter::Duration
|
52
|
-
attr_writer :options, :visitor, :log
|
53
|
-
|
54
|
-
def initialize
|
55
|
-
@unsupported_programming_languages = []
|
56
|
-
@programming_languages = []
|
57
|
-
@language_map = {}
|
58
|
-
@current_scenario = nil
|
59
|
-
end
|
60
|
-
|
61
|
-
def load_plain_text_features(feature_files)
|
62
|
-
features = Ast::Features.new
|
63
|
-
|
64
|
-
tag_counts = {}
|
65
|
-
start = Time.new
|
66
|
-
log.debug("Features:\n")
|
67
|
-
feature_files.each do |f|
|
68
|
-
feature_file = FeatureFile.new(f)
|
69
|
-
feature = feature_file.parse(options, tag_counts)
|
70
|
-
if feature
|
71
|
-
features.add_feature(feature)
|
72
|
-
log.debug(" * #{f}\n")
|
73
|
-
end
|
74
|
-
end
|
75
|
-
duration = Time.now - start
|
76
|
-
log.debug("Parsing feature files took #{format_duration(duration)}\n\n")
|
77
|
-
|
78
|
-
check_tag_limits(tag_counts)
|
79
|
-
|
80
|
-
features
|
81
|
-
end
|
82
|
-
|
83
|
-
def check_tag_limits(tag_counts)
|
84
|
-
error_messages = []
|
85
|
-
options[:tag_expression].limits.each do |tag_name, tag_limit|
|
86
|
-
tag_locations = (tag_counts[tag_name] || [])
|
87
|
-
tag_count = tag_locations.length
|
88
|
-
if tag_count > tag_limit
|
89
|
-
error = "#{tag_name} occurred #{tag_count} times, but the limit was set to #{tag_limit}\n " +
|
90
|
-
tag_locations.join("\n ")
|
91
|
-
error_messages << error
|
92
|
-
end
|
93
|
-
end
|
94
|
-
raise TagExcess.new(error_messages) if error_messages.any?
|
95
|
-
end
|
96
|
-
|
97
|
-
def load_code_files(step_def_files)
|
98
|
-
log.debug("Code:\n")
|
99
|
-
step_def_files.each do |step_def_file|
|
100
|
-
load_code_file(step_def_file)
|
101
|
-
end
|
102
|
-
log.debug("\n")
|
103
|
-
end
|
104
|
-
|
105
|
-
def load_code_file(step_def_file)
|
106
|
-
if programming_language = programming_language_for(step_def_file)
|
107
|
-
log.debug(" * #{step_def_file}\n")
|
108
|
-
programming_language.load_code_file(step_def_file)
|
109
|
-
else
|
110
|
-
log.debug(" * #{step_def_file} [NOT SUPPORTED]\n")
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Loads and registers programming language implementation.
|
115
|
-
# Instances are cached, so calling with the same argument
|
116
|
-
# twice will return the same instance.
|
117
|
-
#
|
118
|
-
def load_programming_language(ext)
|
119
|
-
return @language_map[ext] if @language_map[ext]
|
120
|
-
programming_language_class = constantize("Cucumber::#{ext.capitalize}Support::#{ext.capitalize}Language")
|
121
|
-
programming_language = programming_language_class.new(self)
|
122
|
-
@programming_languages << programming_language
|
123
|
-
@language_map[ext] = programming_language
|
124
|
-
programming_language
|
125
|
-
end
|
126
|
-
|
127
|
-
# Returns the options passed on the command line.
|
128
|
-
def options
|
129
|
-
@options ||= Cli::Options.new
|
130
|
-
end
|
131
|
-
|
132
|
-
def step_visited(step) #:nodoc:
|
133
|
-
steps << step unless steps.index(step)
|
134
|
-
end
|
135
|
-
|
136
|
-
def steps(status = nil) #:nodoc:
|
137
|
-
@steps ||= []
|
138
|
-
if(status)
|
139
|
-
@steps.select{|step| step.status == status}
|
140
|
-
else
|
141
|
-
@steps
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
# Output +announcement+ alongside the formatted output.
|
146
|
-
# This is an alternative to using Kernel#puts - it will display
|
147
|
-
# nicer, and in all outputs (in case you use several formatters)
|
148
|
-
#
|
149
|
-
def announce(msg)
|
150
|
-
msg.respond_to?(:join) ? @visitor.announce(msg.join("\n")) : @visitor.announce(msg.to_s)
|
151
|
-
end
|
152
|
-
|
153
|
-
# Suspends execution and prompts +question+ to the console (STDOUT).
|
154
|
-
# An operator (manual tester) can then enter a line of text and hit
|
155
|
-
# <ENTER>. The entered text is returned, and both +question+ and
|
156
|
-
# the result is added to the output using #announce.
|
157
|
-
#
|
158
|
-
# If you want a beep to happen (to grab the manual tester's attention),
|
159
|
-
# just prepend ASCII character 7 to the question:
|
160
|
-
#
|
161
|
-
# ask("#{7.chr}How many cukes are in the external system?")
|
162
|
-
#
|
163
|
-
# If that doesn't issue a beep, you can shell out to something else
|
164
|
-
# that makes a sound before invoking #ask.
|
165
|
-
#
|
166
|
-
def ask(question, timeout_seconds)
|
167
|
-
STDOUT.puts(question)
|
168
|
-
STDOUT.flush
|
169
|
-
announce(question)
|
170
|
-
|
171
|
-
if(Cucumber::JRUBY)
|
172
|
-
answer = jruby_gets(timeout_seconds)
|
173
|
-
else
|
174
|
-
answer = mri_gets(timeout_seconds)
|
175
|
-
end
|
176
|
-
|
177
|
-
if(answer)
|
178
|
-
announce(answer)
|
179
|
-
answer
|
180
|
-
else
|
181
|
-
raise("Waited for input for #{timeout_seconds} seconds, then timed out.")
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
# Embed +file+ of MIME type +mime_type+ into the output. This may or may
|
186
|
-
# not be ignored, depending on what kind of formatter(s) are active.
|
187
|
-
#
|
188
|
-
def embed(file, mime_type)
|
189
|
-
@visitor.embed(file, mime_type)
|
190
|
-
end
|
191
|
-
|
192
|
-
def scenarios(status = nil) #:nodoc:
|
193
|
-
@scenarios ||= []
|
194
|
-
if(status)
|
195
|
-
@scenarios.select{|scenario| scenario.status == status}
|
196
|
-
else
|
197
|
-
@scenarios
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def invoke(step_name, multiline_argument=nil)
|
202
|
-
begin
|
203
|
-
step_match(step_name).invoke(multiline_argument)
|
204
|
-
rescue Exception => e
|
205
|
-
e.nested! if Undefined === e
|
206
|
-
raise e
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
# Invokes a series of steps +steps_text+. Example:
|
211
|
-
#
|
212
|
-
# invoke(%Q{
|
213
|
-
# Given I have 8 cukes in my belly
|
214
|
-
# Then I should not be thirsty
|
215
|
-
# })
|
216
|
-
def invoke_steps(steps_text, i18n, file_colon_line)
|
217
|
-
file, line = file_colon_line.split(':')
|
218
|
-
parser = Gherkin::Parser::Parser.new(StepInvoker.new(self), true, 'steps')
|
219
|
-
parser.parse(steps_text, file, line.to_i)
|
220
|
-
end
|
221
|
-
|
222
|
-
class StepInvoker
|
223
|
-
def initialize(step_mother)
|
224
|
-
@step_mother = step_mother
|
225
|
-
end
|
226
|
-
|
227
|
-
def step(statement, multiline_arg, result)
|
228
|
-
cucumber_multiline_arg = case(multiline_arg)
|
229
|
-
when Gherkin::Formatter::Model::PyString
|
230
|
-
multiline_arg.value
|
231
|
-
when Array
|
232
|
-
Ast::Table.new(multiline_arg.map{|row| row.cells})
|
233
|
-
else
|
234
|
-
nil
|
235
|
-
end
|
236
|
-
@step_mother.invoke(*[statement.name, cucumber_multiline_arg].compact)
|
237
|
-
end
|
238
|
-
|
239
|
-
def eof
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# Returns a Cucumber::Ast::Table for +text_or_table+, which can either
|
244
|
-
# be a String:
|
245
|
-
#
|
246
|
-
# table(%{
|
247
|
-
# | account | description | amount |
|
248
|
-
# | INT-100 | Taxi | 114 |
|
249
|
-
# | CUC-101 | Peeler | 22 |
|
250
|
-
# })
|
251
|
-
#
|
252
|
-
# or a 2D Array:
|
253
|
-
#
|
254
|
-
# table([
|
255
|
-
# %w{ account description amount },
|
256
|
-
# %w{ INT-100 Taxi 114 },
|
257
|
-
# %w{ CUC-101 Peeler 22 }
|
258
|
-
# ])
|
259
|
-
#
|
260
|
-
def table(text_or_table, file=nil, line_offset=0)
|
261
|
-
if Array === text_or_table
|
262
|
-
Ast::Table.new(text_or_table)
|
263
|
-
else
|
264
|
-
Ast::Table.parse(text_or_table, file, line_offset)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
# Returns a regular String for +string_with_triple_quotes+. Example:
|
269
|
-
#
|
270
|
-
# """
|
271
|
-
# hello
|
272
|
-
# world
|
273
|
-
# """
|
274
|
-
#
|
275
|
-
# Is retured as: " hello\nworld"
|
276
|
-
#
|
277
|
-
def py_string(string_with_triple_quotes, file=nil, line_offset=0)
|
278
|
-
Ast::PyString.parse(string_with_triple_quotes)
|
279
|
-
end
|
280
|
-
|
281
|
-
def step_match(step_name, name_to_report=nil) #:nodoc:
|
282
|
-
matches = @programming_languages.map do |programming_language|
|
283
|
-
programming_language.step_matches(step_name, name_to_report).to_a
|
284
|
-
end.flatten
|
285
|
-
raise Undefined.new(step_name) if matches.empty?
|
286
|
-
matches = best_matches(step_name, matches) if matches.size > 1 && options[:guess]
|
287
|
-
raise Ambiguous.new(step_name, matches, options[:guess]) if matches.size > 1
|
288
|
-
matches[0]
|
289
|
-
end
|
290
|
-
|
291
|
-
def best_matches(step_name, step_matches) #:nodoc:
|
292
|
-
no_groups = step_matches.select {|step_match| step_match.args.length == 0}
|
293
|
-
max_arg_length = step_matches.map {|step_match| step_match.args.length }.max
|
294
|
-
top_groups = step_matches.select {|step_match| step_match.args.length == max_arg_length }
|
295
|
-
|
296
|
-
if no_groups.any?
|
297
|
-
longest_regexp_length = no_groups.map {|step_match| step_match.text_length }.max
|
298
|
-
no_groups.select {|step_match| step_match.text_length == longest_regexp_length }
|
299
|
-
elsif top_groups.any?
|
300
|
-
shortest_capture_length = top_groups.map {|step_match| step_match.args.inject(0) {|sum, c| sum + c.to_s.length } }.min
|
301
|
-
top_groups.select {|step_match| step_match.args.inject(0) {|sum, c| sum + c.to_s.length } == shortest_capture_length }
|
302
|
-
else
|
303
|
-
top_groups
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
def unmatched_step_definitions
|
308
|
-
@programming_languages.map do |programming_language|
|
309
|
-
programming_language.unmatched_step_definitions
|
310
|
-
end.flatten
|
311
|
-
end
|
312
|
-
|
313
|
-
def snippet_text(step_keyword, step_name, multiline_arg_class) #:nodoc:
|
314
|
-
load_programming_language('rb') if unknown_programming_language?
|
315
|
-
@programming_languages.map do |programming_language|
|
316
|
-
programming_language.snippet_text(step_keyword, step_name, multiline_arg_class)
|
317
|
-
end.join("\n")
|
318
|
-
end
|
319
|
-
|
320
|
-
def unknown_programming_language?
|
321
|
-
@programming_languages.empty?
|
322
|
-
end
|
323
|
-
|
324
|
-
def with_hooks(scenario, skip_hooks=false)
|
325
|
-
around(scenario, skip_hooks) do
|
326
|
-
before_and_after(scenario, skip_hooks) do
|
327
|
-
yield scenario
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
def around(scenario, skip_hooks=false, &block) #:nodoc:
|
333
|
-
unless skip_hooks
|
334
|
-
@programming_languages.reverse.inject(block) do |blk, programming_language|
|
335
|
-
proc do
|
336
|
-
programming_language.around(scenario) do
|
337
|
-
blk.call(scenario)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end.call
|
341
|
-
else
|
342
|
-
yield
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
def before_and_after(scenario, skip_hooks=false) #:nodoc:
|
347
|
-
before(scenario) unless skip_hooks
|
348
|
-
yield scenario
|
349
|
-
after(scenario) unless skip_hooks
|
350
|
-
scenario_visited(scenario)
|
351
|
-
end
|
352
|
-
|
353
|
-
def before(scenario) #:nodoc:
|
354
|
-
return if options[:dry_run] || @current_scenario
|
355
|
-
@current_scenario = scenario
|
356
|
-
@programming_languages.each do |programming_language|
|
357
|
-
programming_language.before(scenario)
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
def after(scenario) #:nodoc:
|
362
|
-
@current_scenario = nil
|
363
|
-
return if options[:dry_run]
|
364
|
-
@programming_languages.each do |programming_language|
|
365
|
-
programming_language.after(scenario)
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
def after_step #:nodoc:
|
370
|
-
return if options[:dry_run]
|
371
|
-
@programming_languages.each do |programming_language|
|
372
|
-
programming_language.execute_after_step(@current_scenario)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
def after_configuration(configuration) #:nodoc
|
377
|
-
@programming_languages.each do |programming_language|
|
378
|
-
programming_language.after_configuration(configuration)
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
private
|
383
|
-
|
384
|
-
def programming_language_for(step_def_file) #:nodoc:
|
385
|
-
if ext = File.extname(step_def_file)[1..-1]
|
386
|
-
return nil if @unsupported_programming_languages.index(ext)
|
387
|
-
begin
|
388
|
-
load_programming_language(ext)
|
389
|
-
rescue LoadError => e
|
390
|
-
log.debug("Failed to load '#{ext}' programming language for file #{step_def_file}: #{e.message}\n")
|
391
|
-
@unsupported_programming_languages << ext
|
392
|
-
nil
|
393
|
-
end
|
394
|
-
else
|
395
|
-
nil
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
def max_step_definition_length #:nodoc:
|
400
|
-
@max_step_definition_length ||= step_definitions.map{|step_definition| step_definition.text_length}.max
|
401
|
-
end
|
402
|
-
|
403
|
-
def scenario_visited(scenario) #:nodoc:
|
404
|
-
scenarios << scenario unless scenarios.index(scenario)
|
405
|
-
end
|
406
|
-
|
407
|
-
def log
|
408
|
-
@log ||= Logger.new(STDOUT)
|
409
|
-
end
|
410
|
-
|
411
|
-
def mri_gets(timeout_seconds)
|
412
|
-
begin
|
413
|
-
Timeout.timeout(timeout_seconds) do
|
414
|
-
STDIN.gets
|
415
|
-
end
|
416
|
-
rescue Timeout::Error => e
|
417
|
-
nil
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
def jruby_gets(timeout_seconds)
|
422
|
-
answer = nil
|
423
|
-
t = java.lang.Thread.new do
|
424
|
-
answer = STDIN.gets
|
425
|
-
end
|
426
|
-
t.start
|
427
|
-
t.join(timeout_seconds * 1000)
|
428
|
-
answer
|
4
|
+
class StepMother < Runtime
|
5
|
+
def initialize(*args)
|
6
|
+
warn("StepMother has been deprecated and will be gently put to sleep at the next major release. Please use Runtime instead. #{caller[0]}")
|
7
|
+
super
|
429
8
|
end
|
430
9
|
end
|
431
|
-
end
|
10
|
+
end
|