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