cucumber 0.3.96 → 0.3.97
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 +22 -3
- data/License.txt +2 -0
- data/Manifest.txt +9 -5
- data/config/hoe.rb +1 -0
- data/examples/i18n/Rakefile +5 -3
- data/examples/i18n/fi/features/yhteenlasku.feature +5 -4
- data/examples/python/features/step_definitions/fib_steps.py +3 -0
- data/examples/python/features/support/env.rb +21 -21
- data/gem_tasks/contributors.rake +8 -0
- data/gem_tasks/features.rake +1 -0
- data/gem_tasks/sdoc.rake +7 -0
- data/lib/README.rdoc +12 -0
- data/lib/cucumber/ast/background.rb +1 -1
- data/lib/cucumber/ast/comment.rb +1 -1
- data/lib/cucumber/ast/examples.rb +9 -4
- data/lib/cucumber/ast/feature.rb +1 -1
- data/lib/cucumber/ast/feature_element.rb +1 -1
- data/lib/cucumber/ast/features.rb +1 -1
- data/lib/cucumber/ast/outline_table.rb +2 -2
- data/lib/cucumber/ast/py_string.rb +1 -1
- data/lib/cucumber/ast/scenario.rb +1 -1
- data/lib/cucumber/ast/scenario_outline.rb +8 -7
- data/lib/cucumber/ast/step.rb +1 -1
- data/lib/cucumber/ast/step_collection.rb +1 -1
- data/lib/cucumber/ast/step_invocation.rb +1 -1
- data/lib/cucumber/ast/table.rb +65 -45
- data/lib/cucumber/ast/tags.rb +2 -2
- data/lib/cucumber/ast/visitor.rb +6 -8
- data/lib/cucumber/broadcaster.rb +1 -1
- data/lib/cucumber/cli/language_help_formatter.rb +1 -1
- data/lib/cucumber/cli/main.rb +15 -52
- data/lib/cucumber/constantize.rb +1 -1
- data/lib/cucumber/core_ext/exception.rb +1 -1
- data/lib/cucumber/core_ext/instance_exec.rb +8 -3
- data/lib/cucumber/core_ext/proc.rb +1 -1
- data/lib/cucumber/core_ext/string.rb +1 -1
- data/lib/cucumber/feature_file.rb +4 -3
- data/lib/cucumber/filter.rb +2 -1
- data/lib/cucumber/formatter/ansicolor.rb +6 -5
- data/lib/cucumber/formatter/color_io.rb +2 -2
- data/lib/cucumber/formatter/console.rb +2 -0
- data/lib/cucumber/formatter/duration.rb +3 -0
- data/lib/cucumber/formatter/html.rb +1 -0
- data/lib/cucumber/formatter/junit.rb +1 -0
- data/lib/cucumber/formatter/ordered_xml_markup.rb +1 -1
- data/lib/cucumber/formatter/pretty.rb +18 -4
- data/lib/cucumber/formatter/profile.rb +1 -0
- data/lib/cucumber/formatter/progress.rb +1 -0
- data/lib/cucumber/formatter/rerun.rb +2 -0
- data/lib/cucumber/formatter/steps.rb +1 -0
- data/lib/cucumber/formatter/tag_cloud.rb +2 -1
- data/lib/cucumber/formatter/unicode.rb +1 -1
- data/lib/cucumber/formatter/usage.rb +1 -0
- data/lib/cucumber/language_support.rb +30 -0
- data/lib/cucumber/language_support/language_methods.rb +34 -12
- data/lib/cucumber/parser/feature.rb +81 -57
- data/lib/cucumber/parser/feature.tt +3 -3
- data/lib/cucumber/parser/natural_language.rb +1 -1
- data/lib/cucumber/parser/table.rb +3 -0
- data/lib/cucumber/parser/treetop_ext.rb +6 -5
- data/lib/cucumber/platform.rb +1 -2
- data/lib/cucumber/py_support/py_dsl.py +8 -0
- data/lib/cucumber/py_support/py_language.py +2 -0
- data/lib/cucumber/py_support/py_language.rb +68 -0
- data/lib/cucumber/rails/world.rb +2 -1
- data/lib/cucumber/rake/task.rb +13 -11
- data/lib/cucumber/rb_support/rb_dsl.rb +27 -15
- data/lib/cucumber/rb_support/rb_hook.rb +1 -2
- data/lib/cucumber/rb_support/rb_language.rb +57 -33
- data/lib/cucumber/rb_support/rb_step_definition.rb +42 -38
- data/lib/cucumber/rb_support/rb_world.rb +93 -0
- data/lib/cucumber/rspec_neuter.rb +3 -3
- data/lib/cucumber/step_match.rb +2 -2
- data/lib/cucumber/step_mother.rb +91 -65
- data/lib/cucumber/version.rb +1 -1
- data/lib/cucumber/webrat/element_locator.rb +3 -3
- data/rails_generators/cucumber/templates/cucumber.rake +2 -0
- data/rails_generators/cucumber/templates/webrat_steps.rb +4 -0
- data/spec/cucumber/ast/background_spec.rb +8 -1
- data/spec/cucumber/ast/scenario_outline_spec.rb +1 -0
- data/spec/cucumber/ast/table_spec.rb +10 -0
- data/spec/cucumber/cli/options_spec.rb +1 -1
- data/spec/cucumber/parser/feature_parser_spec.rb +4 -0
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +114 -0
- data/spec/cucumber/step_mother_spec.rb +29 -10
- data/spec/cucumber/treetop_parser/with_comments.feature +14 -1
- data/spec/cucumber/world/pending_spec.rb +1 -1
- metadata +21 -7
- data/gem_tasks/yard.rake +0 -8
- data/lib/cucumber/language_support/hook_methods.rb +0 -9
- data/lib/cucumber/world.rb +0 -89
- data/spec/cucumber/ast/visitor_spec.rb +0 -27
- data/spec/cucumber/step_definition_spec.rb +0 -102
data/lib/cucumber/platform.rb
CHANGED
@@ -4,7 +4,6 @@ require 'rbconfig'
|
|
4
4
|
require 'yaml'
|
5
5
|
|
6
6
|
module Cucumber
|
7
|
-
# TODO: Move these constants and the file to Language. Update wiki
|
8
7
|
LANGUAGE_FILE = File.expand_path(File.dirname(__FILE__) + '/languages.yml')
|
9
8
|
LANGUAGES = YAML.load_file(LANGUAGE_FILE)
|
10
9
|
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
|
@@ -17,7 +16,7 @@ module Cucumber
|
|
17
16
|
RUBY_BINARY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
18
17
|
RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
|
19
18
|
|
20
|
-
def self.file_mode(m)
|
19
|
+
def self.file_mode(m) #:nodoc:
|
21
20
|
RUBY_1_9 ? "#{m}:UTF-8" : m
|
22
21
|
end
|
23
22
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubypython'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module PySupport
|
5
|
+
class PyLanguage
|
6
|
+
# include LanguageSupport::LanguageMethods
|
7
|
+
|
8
|
+
def initialize(step_mother)
|
9
|
+
@python_path = ENV['PYTHONPATH'] ? ENV['PYTHONPATH'].split(':') : []
|
10
|
+
add_to_python_path(File.dirname(__FILE__))
|
11
|
+
|
12
|
+
RubyPython.start
|
13
|
+
at_exit{RubyPython.stop}
|
14
|
+
|
15
|
+
import(File.dirname(__FILE__) + '/py_language.py')
|
16
|
+
end
|
17
|
+
|
18
|
+
def alias_adverbs(adverbs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def step_definitions_for(py_file)
|
22
|
+
mod = import(py_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
def snippet_text(step_keyword, step_name, multiline_arg_class = nil)
|
26
|
+
"python snippet: #{step_keyword}, #{step_name}"
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def begin_scenario
|
32
|
+
end
|
33
|
+
|
34
|
+
def end_scenario
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def import(path)
|
40
|
+
modname = File.basename(path)[0...-File.extname(path).length]
|
41
|
+
begin
|
42
|
+
mod = RubyPython.import(modname)
|
43
|
+
rescue PythonError => e
|
44
|
+
e.message << "Couldn't load #{path}\nConsider adding #{File.expand_path(File.dirname(path))} to your PYTHONPATH"
|
45
|
+
raise e
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_to_python_path(dir)
|
50
|
+
dir = File.expand_path(dir)
|
51
|
+
@python_path.unshift(dir)
|
52
|
+
@python_path.uniq!
|
53
|
+
ENV['PYTHONPATH'] = @python_path.join(':')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class String #:nodoc:
|
60
|
+
# RubyPython incorrectly to expects String#end_with? to exist.
|
61
|
+
unless defined? end_with? # 1.9
|
62
|
+
def end_with?(str) #:nodoc:
|
63
|
+
str = str.to_str
|
64
|
+
tail = self[-str.length, str.length]
|
65
|
+
tail == str
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/cucumber/rails/world.rb
CHANGED
@@ -23,7 +23,8 @@ $__cucumber_toplevel = self
|
|
23
23
|
|
24
24
|
module Cucumber #:nodoc:
|
25
25
|
module Rails
|
26
|
-
# All scenarios will execute in the context of a new instance of World
|
26
|
+
# All scenarios will execute in the context of a new instance of Cucumber::Rails:World if this file
|
27
|
+
# is loaded. This gives Step Definitions access to all the methods from Rails' ActionController::IntegrationTest
|
27
28
|
class World < ActionController::IntegrationTest
|
28
29
|
if defined?(ActiveRecord::Base)
|
29
30
|
self.use_transactional_fixtures = false
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -8,7 +8,7 @@ module Cucumber
|
|
8
8
|
#
|
9
9
|
# Cucumber::Rake::Task.new
|
10
10
|
#
|
11
|
-
# This will
|
11
|
+
# This will define a task named <tt>cucumber</tt> described as 'Run Cucumber features'.
|
12
12
|
# It will use steps from 'features/**/*.rb' and features in 'features/**/*.feature'.
|
13
13
|
#
|
14
14
|
# To further configure the task, you can pass a block:
|
@@ -82,10 +82,10 @@ module Cucumber
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
LIB = File.expand_path(File.dirname(__FILE__) + '/../..')
|
85
|
+
LIB = File.expand_path(File.dirname(__FILE__) + '/../..') #:nodoc:
|
86
86
|
|
87
87
|
# TODO: remove depreated accessors for 0.4.0
|
88
|
-
def self.deprecate_accessor(attribute)
|
88
|
+
def self.deprecate_accessor(attribute) #:nodoc:
|
89
89
|
attr_reader attribute
|
90
90
|
class_eval <<-EOF, __FILE__, __LINE__ + 1
|
91
91
|
def #{attribute}=(value)
|
@@ -133,7 +133,9 @@ module Cucumber
|
|
133
133
|
@rcov_opts = String === opts ? opts.split(' ') : opts
|
134
134
|
end
|
135
135
|
|
136
|
-
# Whether or not to fork a new ruby interpreter. Defaults to true.
|
136
|
+
# Whether or not to fork a new ruby interpreter. Defaults to true. You may gain
|
137
|
+
# some startup speed if you set it to false, but this may also cause issues with
|
138
|
+
# your load path and gems.
|
137
139
|
attr_accessor :fork
|
138
140
|
|
139
141
|
# Define what profile to be used. When used with cucumber_opts it is simply appended to it. Will be ignored when CUCUMBER_OPTS is used.
|
@@ -165,14 +167,14 @@ module Cucumber
|
|
165
167
|
define_task
|
166
168
|
end
|
167
169
|
|
168
|
-
def define_task
|
170
|
+
def define_task #:nodoc:
|
169
171
|
desc @desc
|
170
172
|
task @task_name do
|
171
173
|
runner.run
|
172
174
|
end
|
173
175
|
end
|
174
176
|
|
175
|
-
def runner(task_args = nil)
|
177
|
+
def runner(task_args = nil) #:nodoc:
|
176
178
|
cucumber_opts = [(ENV['CUCUMBER_OPTS'] ? ENV['CUCUMBER_OPTS'].split(/\s+/) : nil) || cucumber_opts_with_profile]
|
177
179
|
if(@rcov)
|
178
180
|
RCovCucumberRunner.new(libs, binary, cucumber_opts, feature_files(task_args), rcov_opts)
|
@@ -183,11 +185,11 @@ module Cucumber
|
|
183
185
|
end
|
184
186
|
end
|
185
187
|
|
186
|
-
def cucumber_opts_with_profile
|
188
|
+
def cucumber_opts_with_profile #:nodoc:
|
187
189
|
@profile ? [cucumber_opts, '--profile', @profile] : cucumber_opts
|
188
190
|
end
|
189
191
|
|
190
|
-
def feature_files(task_args = nil)
|
192
|
+
def feature_files(task_args = nil) #:nodoc:
|
191
193
|
if ENV['FEATURE']
|
192
194
|
FileList[ ENV['FEATURE'] ]
|
193
195
|
else
|
@@ -199,7 +201,7 @@ module Cucumber
|
|
199
201
|
end
|
200
202
|
end
|
201
203
|
|
202
|
-
def step_files(task_args = nil)
|
204
|
+
def step_files(task_args = nil) #:nodoc:
|
203
205
|
if ENV['STEPS']
|
204
206
|
FileList[ ENV['STEPS'] ]
|
205
207
|
else
|
@@ -222,14 +224,14 @@ module Cucumber
|
|
222
224
|
super(task_name, desc)
|
223
225
|
end
|
224
226
|
|
225
|
-
def define_task
|
227
|
+
def define_task #:nodoc:
|
226
228
|
desc @desc
|
227
229
|
task @task_name, :feature_name do |t, args|
|
228
230
|
runner(args).run
|
229
231
|
end
|
230
232
|
end
|
231
233
|
|
232
|
-
def feature_files(task_arguments)
|
234
|
+
def feature_files(task_arguments) #:nodoc:
|
233
235
|
FileList[File.join("features", "**", "#{task_arguments[:feature_name]}.feature")]
|
234
236
|
end
|
235
237
|
|
@@ -7,11 +7,23 @@ module Cucumber
|
|
7
7
|
# object.
|
8
8
|
module RbDsl
|
9
9
|
class << self
|
10
|
-
|
10
|
+
attr_writer :rb_language
|
11
11
|
|
12
12
|
def alias_adverb(adverb)
|
13
13
|
alias_method adverb, :register_rb_step_definition
|
14
14
|
end
|
15
|
+
|
16
|
+
def build_rb_world_factory(world_modules, proc)
|
17
|
+
@rb_language.build_rb_world_factory(world_modules, proc)
|
18
|
+
end
|
19
|
+
|
20
|
+
def register_rb_hook(phase, tag_names, proc)
|
21
|
+
@rb_language.register_rb_hook(phase, tag_names, proc)
|
22
|
+
end
|
23
|
+
|
24
|
+
def register_rb_step_definition(regexp, proc)
|
25
|
+
@rb_language.register_rb_step_definition(regexp, proc)
|
26
|
+
end
|
15
27
|
end
|
16
28
|
|
17
29
|
# Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
|
@@ -33,38 +45,38 @@ module Cucumber
|
|
33
45
|
# World(MyModule)
|
34
46
|
#
|
35
47
|
def World(*world_modules, &proc)
|
36
|
-
RbDsl.
|
48
|
+
RbDsl.build_rb_world_factory(world_modules, proc)
|
37
49
|
end
|
38
50
|
|
39
|
-
# Registers a
|
40
|
-
# want (typically from ruby scripts under <tt>support</tt>).
|
51
|
+
# Registers a proc that will run before each Scenario. You can register as
|
52
|
+
# as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
|
41
53
|
def Before(*tag_names, &proc)
|
42
|
-
RbDsl.
|
54
|
+
RbDsl.register_rb_hook('before', tag_names, proc)
|
43
55
|
end
|
44
56
|
|
57
|
+
# Registers a proc that will run after each Scenario. You can register as
|
58
|
+
# as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
|
45
59
|
def After(*tag_names, &proc)
|
46
|
-
RbDsl.
|
60
|
+
RbDsl.register_rb_hook('after', tag_names, proc)
|
47
61
|
end
|
48
62
|
|
63
|
+
# Registers a proc that will run after each Step. You can register as
|
64
|
+
# as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
|
49
65
|
def AfterStep(*tag_names, &proc)
|
50
|
-
RbDsl.
|
66
|
+
RbDsl.register_rb_hook('after_step', tag_names, proc)
|
51
67
|
end
|
52
68
|
|
53
|
-
# Registers a new Ruby StepDefinition.
|
54
|
-
# This method is aliased
|
69
|
+
# Registers a new Ruby StepDefinition. This method is aliased
|
55
70
|
# to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>, and
|
56
71
|
# also to the i18n translations whenever a feature of a
|
57
72
|
# new language is loaded.
|
58
73
|
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# The +&proc+ gets executed in the context of a <tt>world</tt>
|
63
|
-
# object, which is defined by #World. A new <tt>world</tt>
|
74
|
+
# The +&proc+ gets executed in the context of a <tt>World</tt>
|
75
|
+
# object, which is defined by #World. A new <tt>World</tt>
|
64
76
|
# object is created for each scenario and is shared across
|
65
77
|
# step definitions within that scenario.
|
66
78
|
def register_rb_step_definition(regexp, &proc)
|
67
|
-
RbDsl.
|
79
|
+
RbDsl.register_rb_step_definition(regexp, proc)
|
68
80
|
end
|
69
81
|
end
|
70
82
|
end
|
@@ -1,63 +1,57 @@
|
|
1
1
|
require 'cucumber/rb_support/rb_dsl'
|
2
|
+
require 'cucumber/rb_support/rb_world'
|
2
3
|
require 'cucumber/rb_support/rb_step_definition'
|
3
4
|
|
4
5
|
module Cucumber
|
5
6
|
module RbSupport
|
7
|
+
# Raised if a World block returns Nil.
|
6
8
|
class NilWorld < StandardError
|
7
9
|
def initialize
|
8
10
|
super("World procs should never return nil")
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
14
|
+
# Raised if there are 2 or more World blocks.
|
12
15
|
class MultipleWorld < StandardError
|
13
16
|
def initialize(first_proc, second_proc)
|
14
17
|
message = "You can only pass a proc to #World once, but it's happening\n"
|
15
18
|
message << "in 2 places:\n\n"
|
16
19
|
message << first_proc.backtrace_line('World') << "\n"
|
17
20
|
message << second_proc.backtrace_line('World') << "\n\n"
|
18
|
-
message << "Use Ruby modules instead to extend your worlds. See the Cucumber::
|
21
|
+
message << "Use Ruby modules instead to extend your worlds. See the Cucumber::RbSupport::RbDsl#World RDoc\n"
|
19
22
|
message << "or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.\n\n"
|
20
23
|
super(message)
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
27
|
+
# The Ruby implementation of the programming language API.
|
24
28
|
class RbLanguage
|
25
29
|
include LanguageSupport::LanguageMethods
|
26
|
-
attr_reader :current_world
|
30
|
+
attr_reader :current_world
|
27
31
|
|
28
32
|
def initialize(step_mother)
|
29
33
|
@step_mother = step_mother
|
30
|
-
RbDsl.step_mother = step_mother
|
31
34
|
RbDsl.rb_language = self
|
32
35
|
end
|
33
|
-
|
34
|
-
def
|
36
|
+
|
37
|
+
def alias_adverbs(adverbs)
|
38
|
+
adverbs.each do |adverb|
|
39
|
+
RbDsl.alias_adverb(adverb)
|
40
|
+
RbWorld.alias_adverb(adverb)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def step_definitions_for(code_file)
|
35
45
|
begin
|
36
|
-
|
46
|
+
load_code_file(code_file)
|
47
|
+
step_definitions
|
37
48
|
rescue LoadError => e
|
38
|
-
e.message << "\nFailed to load #{
|
49
|
+
e.message << "\nFailed to load #{code_filr}"
|
39
50
|
raise e
|
51
|
+
ensure
|
52
|
+
@step_definitions = nil
|
40
53
|
end
|
41
54
|
end
|
42
|
-
|
43
|
-
def build_world_factory(*world_modules, &proc)
|
44
|
-
if(proc)
|
45
|
-
raise MultipleWorld.new(@world_proc, proc) if @world_proc
|
46
|
-
@world_proc = proc
|
47
|
-
end
|
48
|
-
@world_modules ||= []
|
49
|
-
@world_modules += world_modules
|
50
|
-
end
|
51
|
-
|
52
|
-
def begin_scenario
|
53
|
-
create_world
|
54
|
-
extend_world
|
55
|
-
connect_world(@step_mother)
|
56
|
-
end
|
57
|
-
|
58
|
-
def end_scenario
|
59
|
-
@current_world = nil
|
60
|
-
end
|
61
55
|
|
62
56
|
def snippet_text(step_keyword, step_name, multiline_arg_class = nil)
|
63
57
|
escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
|
@@ -78,11 +72,41 @@ module Cucumber
|
|
78
72
|
"#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_comment}pending\nend"
|
79
73
|
end
|
80
74
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
def begin_rb_scenario
|
76
|
+
create_world
|
77
|
+
extend_world
|
78
|
+
connect_world
|
79
|
+
end
|
80
|
+
|
81
|
+
def register_rb_hook(phase, tag_names, proc)
|
82
|
+
add_hook(phase, RbHook.new(self, tag_names, proc))
|
83
|
+
end
|
84
|
+
|
85
|
+
def register_rb_step_definition(regexp, proc)
|
86
|
+
add_step_definition(RbStepDefinition.new(self, regexp, proc))
|
87
|
+
end
|
88
|
+
|
89
|
+
def build_rb_world_factory(world_modules, proc)
|
90
|
+
if(proc)
|
91
|
+
raise MultipleWorld.new(@world_proc, proc) if @world_proc
|
92
|
+
@world_proc = proc
|
85
93
|
end
|
94
|
+
@world_modules ||= []
|
95
|
+
@world_modules += world_modules
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def load_code_file(code_file)
|
101
|
+
require code_file # This will cause self.add_step_definition and self.add_hook to be called from RbDsl
|
102
|
+
end
|
103
|
+
|
104
|
+
def begin_scenario
|
105
|
+
begin_rb_scenario
|
106
|
+
end
|
107
|
+
|
108
|
+
def end_scenario
|
109
|
+
@current_world = nil
|
86
110
|
end
|
87
111
|
|
88
112
|
private
|
@@ -100,15 +124,15 @@ module Cucumber
|
|
100
124
|
end
|
101
125
|
|
102
126
|
def extend_world
|
103
|
-
@current_world.extend(
|
127
|
+
@current_world.extend(RbWorld)
|
104
128
|
@current_world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
|
105
129
|
(@world_modules || []).each do |mod|
|
106
130
|
@current_world.extend(mod)
|
107
131
|
end
|
108
132
|
end
|
109
133
|
|
110
|
-
def connect_world
|
111
|
-
@current_world.__cucumber_step_mother = step_mother
|
134
|
+
def connect_world
|
135
|
+
@current_world.__cucumber_step_mother = @step_mother
|
112
136
|
end
|
113
137
|
|
114
138
|
def check_nil(o, proc)
|
@@ -3,54 +3,58 @@ require 'cucumber/core_ext/string'
|
|
3
3
|
require 'cucumber/core_ext/proc'
|
4
4
|
|
5
5
|
module Cucumber
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
module RbSupport
|
7
|
+
# A Ruby Step Definition holds a Regexp and a Proc, and is created
|
8
|
+
# by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
|
9
|
+
# in the <tt>step_definitions</tt> ruby files. See also RbDsl.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# Given /I have (\d+) cucumbers in my belly/ do
|
14
|
+
# # some code here
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
class RbStepDefinition
|
18
|
+
include LanguageSupport::StepDefinitionMethods
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
class MissingProc < StandardError
|
21
|
+
def message
|
22
|
+
"Step definitions must always have a proc"
|
23
|
+
end
|
20
24
|
end
|
21
|
-
end
|
22
25
|
|
23
|
-
|
26
|
+
attr_reader :proc
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
def initialize(rb_language, pattern, proc)
|
29
|
+
raise MissingProc if proc.nil?
|
30
|
+
if String === pattern
|
31
|
+
p = pattern.gsub(/\$\w+/, '(.*)') # Replace $var with (.*)
|
32
|
+
pattern = Regexp.new("^#{p}$")
|
33
|
+
end
|
34
|
+
@rb_language, @regexp, @proc = rb_language, pattern, proc
|
30
35
|
end
|
31
|
-
@rb_language, @regexp, @proc = rb_language, pattern, proc
|
32
|
-
end
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
def regexp
|
38
|
+
@regexp
|
39
|
+
end
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
def invoke(args)
|
42
|
+
args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg}
|
43
|
+
begin
|
44
|
+
@rb_language.current_world.cucumber_instance_exec(true, regexp.inspect, *args, &@proc)
|
45
|
+
rescue Cucumber::ArityMismatchError => e
|
46
|
+
e.backtrace.unshift(self.backtrace_line)
|
47
|
+
raise e
|
48
|
+
end
|
45
49
|
end
|
46
|
-
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
+
def file_colon_line
|
52
|
+
@proc.file_colon_line
|
53
|
+
end
|
51
54
|
|
52
|
-
|
53
|
-
|
55
|
+
def file
|
56
|
+
@file ||= file_colon_line.split(':')[0]
|
57
|
+
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|