cucumber 0.3.95 → 0.3.96
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +21 -0
- data/Manifest.txt +9 -3
- data/examples/sinatra/features/support/env.rb +1 -3
- data/features/cucumber_cli.feature +1 -0
- data/features/drb_server_integration.feature +56 -3
- data/features/junit_formatter.feature +23 -12
- data/features/step_definitions/cucumber_steps.rb +13 -2
- data/features/support/env.rb +19 -3
- data/lib/cucumber/ast/feature_element.rb +1 -1
- data/lib/cucumber/ast/step.rb +1 -1
- data/lib/cucumber/ast/step_invocation.rb +3 -2
- data/lib/cucumber/cli/configuration.rb +9 -25
- data/lib/cucumber/cli/drb_client.rb +7 -3
- data/lib/cucumber/cli/language_help_formatter.rb +4 -4
- data/lib/cucumber/cli/main.rb +26 -46
- data/lib/cucumber/cli/options.rb +3 -0
- data/lib/cucumber/constantize.rb +28 -0
- data/lib/cucumber/feature_file.rb +3 -3
- data/lib/cucumber/formatter/junit.rb +13 -9
- data/lib/cucumber/formatter/pretty.rb +2 -2
- data/lib/cucumber/language_support/hook_methods.rb +9 -0
- data/lib/cucumber/language_support/language_methods.rb +47 -0
- data/lib/cucumber/language_support/step_definition_methods.rb +44 -0
- data/lib/cucumber/parser/natural_language.rb +72 -0
- data/lib/cucumber/rb_support/rb_dsl.rb +73 -0
- data/lib/cucumber/rb_support/rb_hook.rb +19 -0
- data/lib/cucumber/rb_support/rb_language.rb +129 -0
- data/lib/cucumber/rb_support/rb_step_definition.rb +56 -0
- data/lib/cucumber/step_match.rb +2 -2
- data/lib/cucumber/step_mother.rb +87 -206
- data/lib/cucumber/version.rb +1 -1
- data/lib/cucumber/webrat/element_locator.rb +7 -7
- data/lib/cucumber/world.rb +28 -8
- data/rails_generators/cucumber/templates/cucumber_environment.rb +2 -2
- data/rails_generators/cucumber/templates/spork_env.rb +0 -2
- data/rails_generators/cucumber/templates/webrat_steps.rb +17 -0
- data/spec/cucumber/ast/background_spec.rb +8 -5
- data/spec/cucumber/ast/feature_factory.rb +4 -5
- data/spec/cucumber/ast/feature_spec.rb +7 -1
- data/spec/cucumber/ast/scenario_outline_spec.rb +10 -6
- data/spec/cucumber/ast/scenario_spec.rb +8 -3
- data/spec/cucumber/ast/step_collection_spec.rb +2 -2
- data/spec/cucumber/cli/configuration_spec.rb +15 -0
- data/spec/cucumber/cli/drb_client_spec.rb +35 -1
- data/spec/cucumber/cli/main_spec.rb +5 -4
- data/spec/cucumber/cli/options_spec.rb +6 -0
- data/spec/cucumber/parser/feature_parser_spec.rb +6 -5
- data/spec/cucumber/parser/table_parser_spec.rb +1 -1
- data/spec/cucumber/step_definition_spec.rb +26 -25
- data/spec/cucumber/step_mother_spec.rb +46 -41
- data/spec/cucumber/world/pending_spec.rb +4 -5
- metadata +11 -5
- data/lib/cucumber/cli/rb_step_def_loader.rb +0 -14
- data/lib/cucumber/parser/i18n/language.rb +0 -87
- data/lib/cucumber/step_definition.rb +0 -122
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'cucumber/rb_support/rb_hook'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module RbSupport
|
5
|
+
# This module defines the methods you can use to define pure Ruby
|
6
|
+
# Step Definitions and Hooks. This module is mixed into the toplevel
|
7
|
+
# object.
|
8
|
+
module RbDsl
|
9
|
+
class << self
|
10
|
+
attr_accessor :step_mother, :rb_language
|
11
|
+
|
12
|
+
def alias_adverb(adverb)
|
13
|
+
alias_method adverb, :register_rb_step_definition
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
|
18
|
+
# The +proc+ will be executed once before each scenario to create an
|
19
|
+
# Object that the scenario's steps will run within. Any +world_modules+
|
20
|
+
# will be mixed into this Object (via Object#extend).
|
21
|
+
#
|
22
|
+
# This method is typically called from one or more Ruby scripts under
|
23
|
+
# <tt>features/support</tt>. You can call this method as many times as you
|
24
|
+
# like (to register more modules), but if you try to register more than
|
25
|
+
# one Proc you will get an error.
|
26
|
+
#
|
27
|
+
# Cucumber will not yield anything to the +proc+. Examples:
|
28
|
+
#
|
29
|
+
# World do
|
30
|
+
# MyClass.new
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# World(MyModule)
|
34
|
+
#
|
35
|
+
def World(*world_modules, &proc)
|
36
|
+
RbDsl.rb_language.build_world_factory(*world_modules, &proc)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Registers a Before proc. You can call this method as many times as you
|
40
|
+
# want (typically from ruby scripts under <tt>support</tt>).
|
41
|
+
def Before(*tag_names, &proc)
|
42
|
+
RbDsl.step_mother.register_hook(:before, RbHook.new(RbDsl.rb_language, tag_names, proc))
|
43
|
+
end
|
44
|
+
|
45
|
+
def After(*tag_names, &proc)
|
46
|
+
RbDsl.step_mother.register_hook(:after, RbHook.new(RbDsl.rb_language, tag_names, proc))
|
47
|
+
end
|
48
|
+
|
49
|
+
def AfterStep(*tag_names, &proc)
|
50
|
+
RbDsl.step_mother.register_hook(:after_step, RbHook.new(RbDsl.rb_language, tag_names, proc))
|
51
|
+
end
|
52
|
+
|
53
|
+
# Registers a new Ruby StepDefinition.
|
54
|
+
# This method is aliased
|
55
|
+
# to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>, and
|
56
|
+
# also to the i18n translations whenever a feature of a
|
57
|
+
# new language is loaded.
|
58
|
+
#
|
59
|
+
# See Cucumber#alias_steps for details on how to
|
60
|
+
# create your own aliases.
|
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>
|
64
|
+
# object is created for each scenario and is shared across
|
65
|
+
# step definitions within that scenario.
|
66
|
+
def register_rb_step_definition(regexp, &proc)
|
67
|
+
RbDsl.step_mother.register_step_definition(RbStepDefinition.new(RbDsl.rb_language, regexp, &proc))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
extend(Cucumber::RbSupport::RbDsl)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module RbSupport
|
3
|
+
class RbHook
|
4
|
+
include LanguageSupport::HookMethods
|
5
|
+
|
6
|
+
attr_reader :tag_names
|
7
|
+
|
8
|
+
def initialize(rb_language, tag_names, proc)
|
9
|
+
@rb_language = rb_language
|
10
|
+
@tag_names = tag_names
|
11
|
+
@proc = proc
|
12
|
+
end
|
13
|
+
|
14
|
+
def invoke(location, scenario)
|
15
|
+
@rb_language.current_world.cucumber_instance_exec(false, location, scenario, &@proc)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'cucumber/rb_support/rb_dsl'
|
2
|
+
require 'cucumber/rb_support/rb_step_definition'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module RbSupport
|
6
|
+
class NilWorld < StandardError
|
7
|
+
def initialize
|
8
|
+
super("World procs should never return nil")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MultipleWorld < StandardError
|
13
|
+
def initialize(first_proc, second_proc)
|
14
|
+
message = "You can only pass a proc to #World once, but it's happening\n"
|
15
|
+
message << "in 2 places:\n\n"
|
16
|
+
message << first_proc.backtrace_line('World') << "\n"
|
17
|
+
message << second_proc.backtrace_line('World') << "\n\n"
|
18
|
+
message << "Use Ruby modules instead to extend your worlds. See the Cucumber::StepMother#World RDoc\n"
|
19
|
+
message << "or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.\n\n"
|
20
|
+
super(message)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RbLanguage
|
25
|
+
include LanguageSupport::LanguageMethods
|
26
|
+
attr_reader :current_world, :step_mother
|
27
|
+
|
28
|
+
def initialize(step_mother)
|
29
|
+
@step_mother = step_mother
|
30
|
+
RbDsl.step_mother = step_mother
|
31
|
+
RbDsl.rb_language = self
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_step_def_file(step_def_file)
|
35
|
+
begin
|
36
|
+
require step_def_file
|
37
|
+
rescue LoadError => e
|
38
|
+
e.message << "\nFailed to load #{step_def_file}"
|
39
|
+
raise e
|
40
|
+
end
|
41
|
+
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
|
+
|
62
|
+
def snippet_text(step_keyword, step_name, multiline_arg_class = nil)
|
63
|
+
escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
|
64
|
+
escaped = escaped.gsub(PARAM_PATTERN, ESCAPED_PARAM_PATTERN)
|
65
|
+
|
66
|
+
n = 0
|
67
|
+
block_args = escaped.scan(ESCAPED_PARAM_PATTERN).map do |a|
|
68
|
+
n += 1
|
69
|
+
"arg#{n}"
|
70
|
+
end
|
71
|
+
block_args << multiline_arg_class.default_arg_name unless multiline_arg_class.nil?
|
72
|
+
block_arg_string = block_args.empty? ? "" : " |#{block_args.join(", ")}|"
|
73
|
+
multiline_class_comment = ""
|
74
|
+
if(multiline_arg_class == Ast::Table)
|
75
|
+
multiline_class_comment = "# #{multiline_arg_class.default_arg_name} is a #{multiline_arg_class.to_s}\n "
|
76
|
+
end
|
77
|
+
|
78
|
+
"#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_comment}pending\nend"
|
79
|
+
end
|
80
|
+
|
81
|
+
def alias_adverbs(adverbs)
|
82
|
+
adverbs.each do |adverb|
|
83
|
+
RbDsl.alias_adverb(adverb)
|
84
|
+
World.alias_adverb(adverb)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
PARAM_PATTERN = /"([^\"]*)"/
|
91
|
+
ESCAPED_PARAM_PATTERN = '"([^\\"]*)"'
|
92
|
+
|
93
|
+
def create_world
|
94
|
+
if(@world_proc)
|
95
|
+
@current_world = @world_proc.call
|
96
|
+
check_nil(@current_world, @world_proc)
|
97
|
+
else
|
98
|
+
@current_world = Object.new
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def extend_world
|
103
|
+
@current_world.extend(World)
|
104
|
+
@current_world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
|
105
|
+
(@world_modules || []).each do |mod|
|
106
|
+
@current_world.extend(mod)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def connect_world(step_mother)
|
111
|
+
@current_world.__cucumber_step_mother = step_mother
|
112
|
+
end
|
113
|
+
|
114
|
+
def check_nil(o, proc)
|
115
|
+
if o.nil?
|
116
|
+
begin
|
117
|
+
raise NilWorld.new
|
118
|
+
rescue NilWorld => e
|
119
|
+
e.backtrace.clear
|
120
|
+
e.backtrace.push(proc.backtrace_line("World"))
|
121
|
+
raise e
|
122
|
+
end
|
123
|
+
else
|
124
|
+
o
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'cucumber/step_match'
|
2
|
+
require 'cucumber/core_ext/string'
|
3
|
+
require 'cucumber/core_ext/proc'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
# A Step Definition holds a Regexp and a Proc, and is created
|
7
|
+
# by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
|
8
|
+
# in the <tt>step_definitions</tt> ruby files - for example:
|
9
|
+
#
|
10
|
+
# Given /I have (\d+) cucumbers in my belly/ do
|
11
|
+
# # some code here
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
class RbStepDefinition
|
15
|
+
include LanguageSupport::StepDefinitionMethods
|
16
|
+
|
17
|
+
class MissingProc < StandardError
|
18
|
+
def message
|
19
|
+
"Step definitions must always have a proc"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :proc
|
24
|
+
|
25
|
+
def initialize(rb_language, pattern, &proc)
|
26
|
+
raise MissingProc if proc.nil?
|
27
|
+
if String === pattern
|
28
|
+
p = pattern.gsub(/\$\w+/, '(.*)') # Replace $var with (.*)
|
29
|
+
pattern = Regexp.new("^#{p}$")
|
30
|
+
end
|
31
|
+
@rb_language, @regexp, @proc = rb_language, pattern, proc
|
32
|
+
end
|
33
|
+
|
34
|
+
def regexp
|
35
|
+
@regexp
|
36
|
+
end
|
37
|
+
|
38
|
+
def invoke(args)
|
39
|
+
args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg}
|
40
|
+
begin
|
41
|
+
@rb_language.current_world.cucumber_instance_exec(true, regexp.inspect, *args, &@proc)
|
42
|
+
rescue Cucumber::ArityMismatchError => e
|
43
|
+
e.backtrace.unshift(self.backtrace_line)
|
44
|
+
raise e
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def file_colon_line
|
49
|
+
@proc.file_colon_line
|
50
|
+
end
|
51
|
+
|
52
|
+
def file
|
53
|
+
@file ||= file_colon_line.split(':')[0]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/cucumber/step_match.rb
CHANGED
@@ -10,10 +10,10 @@ module Cucumber
|
|
10
10
|
@formatted_step_name
|
11
11
|
end
|
12
12
|
|
13
|
-
def invoke(
|
13
|
+
def invoke(multiline_arg)
|
14
14
|
all_args = @args.dup
|
15
15
|
all_args << multiline_arg if multiline_arg
|
16
|
-
@step_definition.invoke(
|
16
|
+
@step_definition.invoke(all_args)
|
17
17
|
end
|
18
18
|
|
19
19
|
def format_args(format = lambda{|a| a})
|
data/lib/cucumber/step_mother.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
require 'cucumber/
|
1
|
+
require 'cucumber/constantize'
|
2
2
|
require 'cucumber/world'
|
3
3
|
require 'cucumber/core_ext/instance_exec'
|
4
|
+
require 'cucumber/parser/natural_language'
|
5
|
+
require 'cucumber/language_support/hook_methods'
|
6
|
+
require 'cucumber/language_support/language_methods'
|
7
|
+
require 'cucumber/language_support/step_definition_methods'
|
4
8
|
|
5
9
|
module Cucumber
|
6
10
|
class Undefined < StandardError
|
@@ -45,61 +49,56 @@ module Cucumber
|
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
48
|
-
class NilWorld < StandardError
|
49
|
-
def initialize
|
50
|
-
super("World procs should never return nil")
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class MultipleWorld < StandardError
|
55
|
-
def initialize(first_proc, second_proc)
|
56
|
-
message = "You can only pass a proc to #World once, but it's happening\n"
|
57
|
-
message << "in 2 places:\n\n"
|
58
|
-
message << first_proc.backtrace_line('World') << "\n"
|
59
|
-
message << second_proc.backtrace_line('World') << "\n\n"
|
60
|
-
message << "Use Ruby modules instead to extend your worlds. See the Cucumber::StepMother#World RDoc\n"
|
61
|
-
message << "or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.\n\n"
|
62
|
-
super(message)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
52
|
# This is the main interface for registering step definitions, which is done
|
67
53
|
# from <tt>*_steps.rb</tt> files. This module is included right at the top-level
|
68
54
|
# so #register_step_definition (and more interestingly - its aliases) are
|
69
55
|
# available from the top-level.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
@proc = proc
|
75
|
-
end
|
56
|
+
class StepMother
|
57
|
+
include Constantize
|
58
|
+
|
59
|
+
attr_writer :options, :visitor
|
76
60
|
|
77
|
-
|
78
|
-
|
79
|
-
|
61
|
+
def initialize
|
62
|
+
@programming_languages = []
|
63
|
+
@language_map = {}
|
64
|
+
load_natural_language('en')
|
65
|
+
end
|
80
66
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
67
|
+
# Loads and registers programming language implementation.
|
68
|
+
# Instances are cached, so calling with the same argument
|
69
|
+
# twice will return the same instance.
|
70
|
+
#
|
71
|
+
# Raises an exception if the language can't be loaded.
|
72
|
+
#
|
73
|
+
def load_programming_language(ext)
|
74
|
+
return @language_map[ext] if @language_map[ext]
|
75
|
+
programming_language_class = constantize("Cucumber::#{ext.capitalize}Support::#{ext.capitalize}Language")
|
76
|
+
programming_language = programming_language_class.new(self)
|
77
|
+
programming_language.alias_adverbs(@adverbs || [])
|
78
|
+
@programming_languages << programming_language
|
79
|
+
@language_map[ext] = programming_language
|
80
|
+
programming_language
|
81
|
+
end
|
82
|
+
|
83
|
+
# Loads a natural language. This has the effect of aliasing
|
84
|
+
# Step Definition keywords for all of the registered programming
|
85
|
+
# languages (if they support aliasing). See #load_programming_language
|
86
|
+
#
|
87
|
+
def load_natural_language(lang)
|
88
|
+
Parser::NaturalLanguage.get(self, lang)
|
92
89
|
end
|
93
90
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
91
|
+
# Registers a StepDefinition. This can be a Ruby StepDefintion,
|
92
|
+
# or any other kind of object that implements the StepDefintion
|
93
|
+
# contract (API).
|
94
|
+
def register_step_definition(step_definition)
|
95
|
+
step_definitions.each do |already|
|
96
|
+
raise Redundant.new(already, step_definition) if already.same_regexp?(step_definition.regexp)
|
98
97
|
end
|
98
|
+
step_definitions << step_definition
|
99
|
+
step_definition
|
99
100
|
end
|
100
101
|
|
101
|
-
attr_writer :snippet_generator, :options, :visitor
|
102
|
-
|
103
102
|
def options
|
104
103
|
@options ||= {}
|
105
104
|
end
|
@@ -117,6 +116,10 @@ module Cucumber
|
|
117
116
|
end
|
118
117
|
end
|
119
118
|
|
119
|
+
def announce(msg)
|
120
|
+
@visitor.announce(msg)
|
121
|
+
end
|
122
|
+
|
120
123
|
def scenarios(status = nil)
|
121
124
|
@scenarios ||= []
|
122
125
|
if(status)
|
@@ -126,44 +129,8 @@ module Cucumber
|
|
126
129
|
end
|
127
130
|
end
|
128
131
|
|
129
|
-
|
130
|
-
|
131
|
-
# also to the i18n translations whenever a feature of a
|
132
|
-
# new language is loaded.
|
133
|
-
#
|
134
|
-
# See Cucumber#alias_steps for details on how to
|
135
|
-
# create your own aliases.
|
136
|
-
#
|
137
|
-
# The +&proc+ gets executed in the context of a <tt>world</tt>
|
138
|
-
# object, which is defined by #World. A new <tt>world</tt>
|
139
|
-
# object is created for each scenario and is shared across
|
140
|
-
# step definitions within that scenario.
|
141
|
-
def register_step_definition(regexp, &proc)
|
142
|
-
step_definition = StepDefinition.new(regexp, &proc)
|
143
|
-
step_definitions.each do |already|
|
144
|
-
raise Redundant.new(already, step_definition) if already.match(regexp)
|
145
|
-
end
|
146
|
-
step_definitions << step_definition
|
147
|
-
step_definition
|
148
|
-
end
|
149
|
-
|
150
|
-
# Registers a Before proc. You can call this method as many times as you
|
151
|
-
# want (typically from ruby scripts under <tt>support</tt>).
|
152
|
-
def Before(*tag_names, &proc)
|
153
|
-
register_hook(:before, tag_names, proc)
|
154
|
-
end
|
155
|
-
|
156
|
-
def After(*tag_names, &proc)
|
157
|
-
register_hook(:after, tag_names, proc)
|
158
|
-
end
|
159
|
-
|
160
|
-
def AfterStep(*tag_names, &proc)
|
161
|
-
register_hook(:after_step, tag_names, proc)
|
162
|
-
end
|
163
|
-
|
164
|
-
def register_hook(phase, tags, proc)
|
165
|
-
hook = Hook.new(tags, proc)
|
166
|
-
hooks[phase] << hook
|
132
|
+
def register_hook(phase, hook)
|
133
|
+
hooks[phase.to_sym] << hook
|
167
134
|
hook
|
168
135
|
end
|
169
136
|
|
@@ -172,53 +139,7 @@ module Cucumber
|
|
172
139
|
end
|
173
140
|
|
174
141
|
def hooks_for(phase, scenario)
|
175
|
-
hooks[phase].select{|hook| scenario.accept_hook?(hook)}
|
176
|
-
end
|
177
|
-
|
178
|
-
# Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
|
179
|
-
# The +proc+ will be executed once before each scenario to create an
|
180
|
-
# Object that the scenario's steps will run within. Any +world_modules+
|
181
|
-
# will be mixed into this Object (via Object#extend).
|
182
|
-
#
|
183
|
-
# This method is typically called from one or more Ruby scripts under
|
184
|
-
# <tt>features/support</tt>. You can call this method as many times as you
|
185
|
-
# like (to register more modules), but if you try to register more than
|
186
|
-
# one Proc you will get an error.
|
187
|
-
#
|
188
|
-
# Cucumber will not yield anything to the +proc+ (like it used to do before v0.3).
|
189
|
-
#
|
190
|
-
# In earlier versions of Cucumber (before 0.3) you could not register
|
191
|
-
# any +world_modules+. Instead you would register several Proc objects (by
|
192
|
-
# calling the method several times). The result of each +proc+ would be yielded
|
193
|
-
# to the next +proc+. Example:
|
194
|
-
#
|
195
|
-
# World do |world| # NOT SUPPORTED FROM 0.3
|
196
|
-
# MyClass.new
|
197
|
-
# end
|
198
|
-
#
|
199
|
-
# World do |world| # NOT SUPPORTED FROM 0.3
|
200
|
-
# world.extend(MyModule)
|
201
|
-
# end
|
202
|
-
#
|
203
|
-
# From Cucumber 0.3 the recommended way to do this is:
|
204
|
-
#
|
205
|
-
# World do
|
206
|
-
# MyClass.new
|
207
|
-
# end
|
208
|
-
#
|
209
|
-
# World(MyModule)
|
210
|
-
#
|
211
|
-
def World(*world_modules, &proc)
|
212
|
-
if(proc)
|
213
|
-
raise MultipleWorld.new(@world_proc, proc) if @world_proc
|
214
|
-
@world_proc = proc
|
215
|
-
end
|
216
|
-
@world_modules ||= []
|
217
|
-
@world_modules += world_modules
|
218
|
-
end
|
219
|
-
|
220
|
-
def current_world
|
221
|
-
@current_world
|
142
|
+
hooks[phase.to_sym].select{|hook| scenario.accept_hook?(hook)}
|
222
143
|
end
|
223
144
|
|
224
145
|
def step_match(step_name, formatted_step_name=nil)
|
@@ -257,108 +178,68 @@ module Cucumber
|
|
257
178
|
end
|
258
179
|
|
259
180
|
def snippet_text(step_keyword, step_name, multiline_arg_class)
|
260
|
-
@
|
181
|
+
@programming_languages.map do |programming_language|
|
182
|
+
programming_language.snippet_text(step_keyword, step_name, multiline_arg_class)
|
183
|
+
end.join("\n")
|
261
184
|
end
|
262
185
|
|
263
186
|
def before_and_after(scenario, skip_hooks=false)
|
264
187
|
before(scenario) unless skip_hooks
|
265
|
-
@current_scenario = scenario
|
266
188
|
yield scenario
|
267
|
-
@current_scenario = nil
|
268
189
|
after(scenario) unless skip_hooks
|
269
190
|
scenario_visited(scenario)
|
270
191
|
end
|
271
|
-
|
272
|
-
def before(scenario)
|
273
|
-
unless current_world
|
274
|
-
new_world!
|
275
|
-
execute_before(scenario)
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def after(scenario)
|
280
|
-
execute_after(scenario)
|
281
|
-
nil_world!
|
282
|
-
end
|
283
|
-
|
284
|
-
def after_step
|
285
|
-
execute_after_step(@current_scenario)
|
286
|
-
end
|
287
|
-
|
288
|
-
private
|
289
192
|
|
290
|
-
def
|
291
|
-
@
|
193
|
+
def register_adverbs(adverbs)
|
194
|
+
@adverbs ||= []
|
195
|
+
@adverbs += adverbs
|
196
|
+
@adverbs.uniq!
|
197
|
+
@programming_languages.each do |programming_language|
|
198
|
+
programming_language.alias_adverbs(@adverbs)
|
199
|
+
end
|
292
200
|
end
|
293
201
|
|
294
|
-
|
295
|
-
def new_world!
|
202
|
+
def begin_scenario
|
296
203
|
return if options[:dry_run]
|
297
|
-
|
298
|
-
|
299
|
-
connect_world
|
300
|
-
@current_world
|
301
|
-
end
|
302
|
-
|
303
|
-
def create_world!
|
304
|
-
if(@world_proc)
|
305
|
-
@current_world = @world_proc.call
|
306
|
-
check_nil(@current_world, @world_proc)
|
307
|
-
else
|
308
|
-
@current_world = Object.new
|
204
|
+
@programming_languages.each do |programming_language|
|
205
|
+
programming_language.begin_scenario
|
309
206
|
end
|
310
207
|
end
|
311
208
|
|
312
|
-
def
|
313
|
-
|
314
|
-
@
|
315
|
-
|
316
|
-
@current_world.extend(mod)
|
209
|
+
def end_scenario
|
210
|
+
return if options[:dry_run]
|
211
|
+
@programming_languages.each do |programming_language|
|
212
|
+
programming_language.end_scenario
|
317
213
|
end
|
318
214
|
end
|
319
|
-
|
320
|
-
def
|
321
|
-
|
322
|
-
@
|
323
|
-
|
324
|
-
|
325
|
-
def check_nil(o, proc)
|
326
|
-
if o.nil?
|
327
|
-
begin
|
328
|
-
raise NilWorld.new
|
329
|
-
rescue NilWorld => e
|
330
|
-
e.backtrace.clear
|
331
|
-
e.backtrace.push(proc.backtrace_line("World"))
|
332
|
-
raise e
|
333
|
-
end
|
334
|
-
else
|
335
|
-
o
|
215
|
+
|
216
|
+
def before(scenario)
|
217
|
+
return if options[:dry_run] || @current_scenario
|
218
|
+
@current_scenario = scenario
|
219
|
+
@programming_languages.each do |programming_language|
|
220
|
+
programming_language.before(scenario)
|
336
221
|
end
|
337
222
|
end
|
338
|
-
|
339
|
-
def
|
340
|
-
@
|
341
|
-
end
|
342
|
-
|
343
|
-
def execute_before(scenario)
|
223
|
+
|
224
|
+
def after(scenario)
|
225
|
+
@current_scenario = nil
|
344
226
|
return if options[:dry_run]
|
345
|
-
|
346
|
-
|
227
|
+
@programming_languages.each do |programming_language|
|
228
|
+
programming_language.after(scenario)
|
347
229
|
end
|
348
230
|
end
|
349
|
-
|
350
|
-
def
|
231
|
+
|
232
|
+
def after_step
|
351
233
|
return if options[:dry_run]
|
352
|
-
|
353
|
-
|
234
|
+
@programming_languages.each do |programming_language|
|
235
|
+
programming_language.execute_after_step(@current_scenario)
|
354
236
|
end
|
355
237
|
end
|
238
|
+
|
239
|
+
private
|
356
240
|
|
357
|
-
def
|
358
|
-
|
359
|
-
hooks_for(:after_step, scenario).each do |hook|
|
360
|
-
hook.execute_in(@current_world, scenario, 'AfterStep', false)
|
361
|
-
end
|
241
|
+
def max_step_definition_length
|
242
|
+
@max_step_definition_length ||= step_definitions.map{|step_definition| step_definition.text_length}.max
|
362
243
|
end
|
363
244
|
|
364
245
|
def scenario_visited(scenario)
|