cucumber 0.3.95 → 0.3.96
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 +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)
|