cucumber 2.1.0 → 2.2.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/Gemfile +3 -1
- data/History.md +18 -2
- data/README.md +5 -1
- data/cucumber.gemspec +3 -4
- data/cucumber.yml +2 -2
- data/features/docs/api/run_cli_main_with_existing_runtime.feature +4 -7
- data/features/docs/defining_steps/skip_scenario.feature +6 -2
- data/features/docs/formatters/api_methods.feature +36 -0
- data/features/docs/profiles.feature +2 -2
- data/features/lib/step_definitions/profile_steps.rb +1 -1
- data/lib/cucumber.rb +11 -4
- data/lib/cucumber/cli/configuration.rb +2 -2
- data/lib/cucumber/cli/options.rb +2 -2
- data/lib/cucumber/configuration.rb +25 -3
- data/lib/cucumber/deprecate.rb +29 -0
- data/lib/cucumber/filters/activate_steps.rb +39 -5
- data/lib/cucumber/formatter/console.rb +4 -4
- data/lib/cucumber/formatter/io.rb +1 -1
- data/lib/cucumber/formatter/legacy_api/adapter.rb +30 -30
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +4 -9
- data/lib/cucumber/platform.rb +2 -7
- data/lib/cucumber/rb_support/rb_language.rb +72 -26
- data/lib/cucumber/rb_support/rb_step_definition.rb +2 -2
- data/lib/cucumber/rb_support/rb_world.rb +6 -1
- data/lib/cucumber/rb_support/snippet.rb +21 -0
- data/lib/cucumber/running_test_case.rb +5 -1
- data/lib/cucumber/runtime.rb +11 -15
- data/lib/cucumber/runtime/support_code.rb +20 -128
- data/lib/cucumber/step_argument.rb +25 -0
- data/lib/cucumber/step_match.rb +6 -12
- data/lib/cucumber/step_match_search.rb +67 -0
- data/lib/cucumber/version +1 -0
- data/spec/cucumber/configuration_spec.rb +3 -2
- data/spec/cucumber/filters/activate_steps_spec.rb +95 -3
- data/spec/cucumber/formatter/html_spec.rb +1 -1
- data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +55 -28
- data/spec/cucumber/formatter/pretty_spec.rb +2 -2
- data/spec/cucumber/formatter/spec_helper.rb +22 -12
- data/spec/cucumber/rb_support/rb_language_spec.rb +9 -45
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +2 -2
- data/spec/cucumber/rb_support/rb_world_spec.rb +47 -0
- data/spec/cucumber/runtime/for_programming_languages_spec.rb +1 -1
- data/spec/cucumber/runtime/support_code_spec.rb +4 -111
- data/spec/cucumber/step_argument_spec.rb +18 -0
- data/spec/cucumber/step_match_search_spec.rb +122 -0
- data/spec/cucumber/step_match_spec.rb +8 -2
- data/spec/cucumber/world/pending_spec.rb +2 -1
- data/spec/cucumber_spec.rb +39 -0
- metadata +45 -50
- data/features/docs/wire_protocol/erb_configuration.feature +0 -56
- data/features/docs/wire_protocol/handle_unexpected_response.feature +0 -30
- data/features/docs/wire_protocol/invoke_message.feature +0 -216
- data/features/docs/wire_protocol/readme.md +0 -26
- data/features/docs/wire_protocol/snippets_message.feature +0 -51
- data/features/docs/wire_protocol/step_matches_message.feature +0 -81
- data/features/docs/wire_protocol/table_diffing.feature +0 -126
- data/features/docs/wire_protocol/tags.feature +0 -87
- data/features/docs/wire_protocol/timeouts.feature +0 -64
- data/lib/cucumber/events/bus.rb +0 -86
- data/lib/cucumber/gherkin/formatter/argument.rb +0 -17
- data/lib/cucumber/gherkin/formatter/hashable.rb +0 -27
- data/lib/cucumber/language_support.rb +0 -30
- data/lib/cucumber/language_support/language_methods.rb +0 -72
- data/lib/cucumber/rb_support/regexp_argument_matcher.rb +0 -21
- data/lib/cucumber/wire_support/configuration.rb +0 -38
- data/lib/cucumber/wire_support/connection.rb +0 -61
- data/lib/cucumber/wire_support/request_handler.rb +0 -32
- data/lib/cucumber/wire_support/wire_exception.rb +0 -32
- data/lib/cucumber/wire_support/wire_language.rb +0 -68
- data/lib/cucumber/wire_support/wire_packet.rb +0 -34
- data/lib/cucumber/wire_support/wire_protocol.rb +0 -43
- data/lib/cucumber/wire_support/wire_protocol/requests.rb +0 -133
- data/lib/cucumber/wire_support/wire_step_definition.rb +0 -21
- data/spec/cucumber/events/bus_spec.rb +0 -94
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +0 -22
- data/spec/cucumber/wire_support/configuration_spec.rb +0 -64
- data/spec/cucumber/wire_support/connection_spec.rb +0 -64
- data/spec/cucumber/wire_support/wire_exception_spec.rb +0 -50
- data/spec/cucumber/wire_support/wire_language_spec.rb +0 -46
- data/spec/cucumber/wire_support/wire_packet_spec.rb +0 -44
@@ -1,126 +0,0 @@
|
|
1
|
-
@wire
|
2
|
-
Feature: Wire protocol table diffing
|
3
|
-
|
4
|
-
In order to use the amazing functionality in the Cucumber table object
|
5
|
-
As a wire server
|
6
|
-
I want to be able to ask for a table diff during a step definition invocation
|
7
|
-
|
8
|
-
Background:
|
9
|
-
Given a file named "features/wired.feature" with:
|
10
|
-
"""
|
11
|
-
Feature: Hello
|
12
|
-
Scenario: Wired
|
13
|
-
Given we're all wired
|
14
|
-
|
15
|
-
"""
|
16
|
-
And a file named "features/step_definitions/some_remote_place.wire" with:
|
17
|
-
"""
|
18
|
-
host: localhost
|
19
|
-
port: 54321
|
20
|
-
|
21
|
-
"""
|
22
|
-
|
23
|
-
@spawn
|
24
|
-
Scenario: Invoke a step definition tries to diff the table and fails
|
25
|
-
Given there is a wire server running on port 54321 which understands the following protocol:
|
26
|
-
| request | response |
|
27
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
28
|
-
| ["begin_scenario"] | ["success"] |
|
29
|
-
| ["invoke",{"id":"1","args":[]}] | ["diff",[[["a","b"],["c","d"]],[["x","y"],["z","z"]]]] |
|
30
|
-
| ["diff_failed"] | ["fail",{"message":"Not same", "exception":"DifferentException", "backtrace":["a.cs:12","b.cs:34"]}] |
|
31
|
-
| ["end_scenario"] | ["success"] |
|
32
|
-
When I run `cucumber -f progress --backtrace`
|
33
|
-
Then the stderr should not contain anything
|
34
|
-
And it should fail with:
|
35
|
-
"""
|
36
|
-
F
|
37
|
-
|
38
|
-
(::) failed steps (::)
|
39
|
-
|
40
|
-
Not same (DifferentException from localhost:54321)
|
41
|
-
a.cs:12
|
42
|
-
b.cs:34
|
43
|
-
features/wired.feature:3:in `Given we're all wired'
|
44
|
-
|
45
|
-
Failing Scenarios:
|
46
|
-
cucumber features/wired.feature:2 # Scenario: Wired
|
47
|
-
|
48
|
-
1 scenario (1 failed)
|
49
|
-
1 step (1 failed)
|
50
|
-
|
51
|
-
"""
|
52
|
-
|
53
|
-
Scenario: Invoke a step definition tries to diff the table and passes
|
54
|
-
Given there is a wire server running on port 54321 which understands the following protocol:
|
55
|
-
| request | response |
|
56
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
57
|
-
| ["begin_scenario"] | ["success"] |
|
58
|
-
| ["invoke",{"id":"1","args":[]}] | ["diff",[[["a"],["b"]],[["a"],["b"]]]] |
|
59
|
-
| ["diff_ok"] | ["success"] |
|
60
|
-
| ["end_scenario"] | ["success"] |
|
61
|
-
When I run `cucumber -f progress`
|
62
|
-
Then it should pass with:
|
63
|
-
"""
|
64
|
-
.
|
65
|
-
|
66
|
-
1 scenario (1 passed)
|
67
|
-
1 step (1 passed)
|
68
|
-
|
69
|
-
"""
|
70
|
-
|
71
|
-
@spawn
|
72
|
-
Scenario: Invoke a step definition which successfully diffs a table but then fails
|
73
|
-
Given there is a wire server running on port 54321 which understands the following protocol:
|
74
|
-
| request | response |
|
75
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
76
|
-
| ["begin_scenario"] | ["success"] |
|
77
|
-
| ["invoke",{"id":"1","args":[]}] | ["diff",[[["a"],["b"]],[["a"],["b"]]]] |
|
78
|
-
| ["diff_ok"] | ["fail",{"message":"I wanted things to be different for us"}] |
|
79
|
-
| ["end_scenario"] | ["success"] |
|
80
|
-
When I run `cucumber -f progress`
|
81
|
-
Then it should fail with:
|
82
|
-
"""
|
83
|
-
F
|
84
|
-
|
85
|
-
(::) failed steps (::)
|
86
|
-
|
87
|
-
I wanted things to be different for us (Cucumber::WireSupport::WireException)
|
88
|
-
features/wired.feature:3:in `Given we're all wired'
|
89
|
-
|
90
|
-
Failing Scenarios:
|
91
|
-
cucumber features/wired.feature:2 # Scenario: Wired
|
92
|
-
|
93
|
-
1 scenario (1 failed)
|
94
|
-
1 step (1 failed)
|
95
|
-
|
96
|
-
"""
|
97
|
-
|
98
|
-
@spawn
|
99
|
-
Scenario: Invoke a step definition which asks for an immediate diff that fails
|
100
|
-
Given there is a wire server running on port 54321 which understands the following protocol:
|
101
|
-
| request | response |
|
102
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
103
|
-
| ["begin_scenario"] | ["success"] |
|
104
|
-
| ["invoke",{"id":"1","args":[]}] | ["diff!",[[["a"]],[["b"]]]] |
|
105
|
-
| ["end_scenario"] | ["success"] |
|
106
|
-
When I run `cucumber -f progress`
|
107
|
-
And it should fail with exactly:
|
108
|
-
"""
|
109
|
-
F
|
110
|
-
|
111
|
-
(::) failed steps (::)
|
112
|
-
|
113
|
-
Tables were not identical:
|
114
|
-
|
115
|
-
| (-) a | (+) b |
|
116
|
-
(Cucumber::MultilineArgument::DataTable::Different)
|
117
|
-
features/wired.feature:3:in `Given we're all wired'
|
118
|
-
|
119
|
-
Failing Scenarios:
|
120
|
-
cucumber features/wired.feature:2 # Scenario: Wired
|
121
|
-
|
122
|
-
1 scenario (1 failed)
|
123
|
-
1 step (1 failed)
|
124
|
-
0m0.012s
|
125
|
-
|
126
|
-
"""
|
@@ -1,87 +0,0 @@
|
|
1
|
-
@wire
|
2
|
-
Feature: Wire protocol tags
|
3
|
-
|
4
|
-
In order to use Before and After hooks in a wire server, we send tags with the
|
5
|
-
scenario in the begin_scenario and end_scenario messages
|
6
|
-
|
7
|
-
Background:
|
8
|
-
And a file named "features/step_definitions/some_remote_place.wire" with:
|
9
|
-
"""
|
10
|
-
host: localhost
|
11
|
-
port: 54321
|
12
|
-
|
13
|
-
"""
|
14
|
-
|
15
|
-
Scenario: Run a scenario
|
16
|
-
Given a file named "features/wired.feature" with:
|
17
|
-
"""
|
18
|
-
@foo @bar
|
19
|
-
Feature: Wired
|
20
|
-
|
21
|
-
@baz
|
22
|
-
Scenario: Everybody's Wired
|
23
|
-
Given we're all wired
|
24
|
-
|
25
|
-
"""
|
26
|
-
And there is a wire server running on port 54321 which understands the following protocol:
|
27
|
-
| request | response |
|
28
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
29
|
-
| ["begin_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
30
|
-
| ["invoke",{"id":"1","args":[]}] | ["success"] |
|
31
|
-
| ["end_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
32
|
-
When I run `cucumber -f pretty -q`
|
33
|
-
Then the stderr should not contain anything
|
34
|
-
And it should pass with:
|
35
|
-
"""
|
36
|
-
@foo @bar
|
37
|
-
Feature: Wired
|
38
|
-
|
39
|
-
@baz
|
40
|
-
Scenario: Everybody's Wired
|
41
|
-
Given we're all wired
|
42
|
-
|
43
|
-
1 scenario (1 passed)
|
44
|
-
1 step (1 passed)
|
45
|
-
|
46
|
-
"""
|
47
|
-
|
48
|
-
Scenario: Run a scenario outline example
|
49
|
-
Given a file named "features/wired.feature" with:
|
50
|
-
"""
|
51
|
-
@foo @bar
|
52
|
-
Feature: Wired
|
53
|
-
|
54
|
-
@baz
|
55
|
-
Scenario Outline: Everybody's Wired
|
56
|
-
Given we're all <something>
|
57
|
-
|
58
|
-
Examples:
|
59
|
-
| something |
|
60
|
-
| wired |
|
61
|
-
|
62
|
-
"""
|
63
|
-
And there is a wire server running on port 54321 which understands the following protocol:
|
64
|
-
| request | response |
|
65
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
66
|
-
| ["begin_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
67
|
-
| ["invoke",{"id":"1","args":[]}] | ["success"] |
|
68
|
-
| ["end_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
69
|
-
When I run `cucumber -f pretty -q`
|
70
|
-
Then the stderr should not contain anything
|
71
|
-
And it should pass with:
|
72
|
-
"""
|
73
|
-
@foo @bar
|
74
|
-
Feature: Wired
|
75
|
-
|
76
|
-
@baz
|
77
|
-
Scenario Outline: Everybody's Wired
|
78
|
-
Given we're all <something>
|
79
|
-
|
80
|
-
Examples:
|
81
|
-
| something |
|
82
|
-
| wired |
|
83
|
-
|
84
|
-
1 scenario (1 passed)
|
85
|
-
1 step (1 passed)
|
86
|
-
|
87
|
-
"""
|
@@ -1,64 +0,0 @@
|
|
1
|
-
@wire
|
2
|
-
Feature: Wire protocol timeouts
|
3
|
-
|
4
|
-
We don't want Cucumber to hang forever on a wire server that's not even there,
|
5
|
-
but equally we need to give the user the flexibility to allow step definitions
|
6
|
-
to take a while to execute, if that's what they need.
|
7
|
-
|
8
|
-
Background:
|
9
|
-
And a file named "features/wired.feature" with:
|
10
|
-
"""
|
11
|
-
Feature: Telegraphy
|
12
|
-
Scenario: Wired
|
13
|
-
Given we're all wired
|
14
|
-
|
15
|
-
"""
|
16
|
-
|
17
|
-
Scenario: Try to talk to a server that's not there
|
18
|
-
Given a file named "features/step_definitions/some_remote_place.wire" with:
|
19
|
-
"""
|
20
|
-
host: localhost
|
21
|
-
port: 54321
|
22
|
-
|
23
|
-
"""
|
24
|
-
When I run `cucumber -f progress`
|
25
|
-
Then the stderr should contain:
|
26
|
-
"""
|
27
|
-
Unable to contact the wire server at localhost:54321
|
28
|
-
"""
|
29
|
-
|
30
|
-
@spawn
|
31
|
-
Scenario: Invoke a step definition that takes longer than its timeout
|
32
|
-
Given a file named "features/step_definitions/some_remote_place.wire" with:
|
33
|
-
"""
|
34
|
-
host: localhost
|
35
|
-
port: 54321
|
36
|
-
timeout:
|
37
|
-
invoke: 0.1
|
38
|
-
|
39
|
-
"""
|
40
|
-
And there is a wire server on port 54321 which understands the following protocol:
|
41
|
-
| request | response |
|
42
|
-
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[{"val":"wired", "pos":10}]}]] |
|
43
|
-
| ["begin_scenario"] | ["success"] |
|
44
|
-
| ["invoke",{"id":"1","args":["wired"]}] | ["success"] |
|
45
|
-
| ["end_scenario"] | ["success"] |
|
46
|
-
And the wire server takes 0.2 seconds to respond to the invoke message
|
47
|
-
When I run `cucumber -f pretty`
|
48
|
-
Then the stderr should not contain anything
|
49
|
-
And it should fail with:
|
50
|
-
"""
|
51
|
-
Feature: Telegraphy
|
52
|
-
|
53
|
-
Scenario: Wired # features/wired.feature:2
|
54
|
-
Given we're all wired # Unknown
|
55
|
-
Timed out calling wire server with message 'invoke' (Timeout::Error)
|
56
|
-
features/wired.feature:3:in `Given we're all wired'
|
57
|
-
|
58
|
-
Failing Scenarios:
|
59
|
-
cucumber features/wired.feature:2 # Scenario: Wired
|
60
|
-
|
61
|
-
1 scenario (1 failed)
|
62
|
-
1 step (1 failed)
|
63
|
-
|
64
|
-
"""
|
data/lib/cucumber/events/bus.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
module Cucumber
|
2
|
-
module Events
|
3
|
-
|
4
|
-
# Event bus
|
5
|
-
#
|
6
|
-
# Implements and in-process pub-sub events broadcaster allowing multiple observers
|
7
|
-
# to subscribe to different events that fire as your tests are executed.
|
8
|
-
#
|
9
|
-
# @private
|
10
|
-
class Bus
|
11
|
-
|
12
|
-
def initialize(default_namespace)
|
13
|
-
@default_namespace = default_namespace.to_s
|
14
|
-
@handlers = {}
|
15
|
-
end
|
16
|
-
|
17
|
-
# Register for an event
|
18
|
-
def register(event_id, handler_object = nil, &handler_proc)
|
19
|
-
handler = handler_proc || handler_object
|
20
|
-
raise ArgumentError.new("Please pass either an object or a handler block") unless handler
|
21
|
-
event_class = parse_event_id(event_id)
|
22
|
-
handlers_for(event_class) << handler
|
23
|
-
end
|
24
|
-
|
25
|
-
# Broadcast an event
|
26
|
-
def notify(event)
|
27
|
-
handlers_for(event.class).each { |handler| handler.call(event) }
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def handlers_for(event_class)
|
33
|
-
@handlers[event_class.to_s] ||= []
|
34
|
-
end
|
35
|
-
|
36
|
-
def parse_event_id(event_id)
|
37
|
-
case event_id
|
38
|
-
when Class
|
39
|
-
return event_id
|
40
|
-
when String
|
41
|
-
constantize(event_id)
|
42
|
-
else
|
43
|
-
constantize("#{@default_namespace}::#{camel_case(event_id)}")
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def camel_case(underscored_name)
|
48
|
-
underscored_name.to_s.split("_").map { |word| word.upcase[0] + word[1..-1] }.join
|
49
|
-
end
|
50
|
-
|
51
|
-
# Thanks ActiveSupport
|
52
|
-
# (Only needed to support Ruby 1.9.3 and JRuby)
|
53
|
-
def constantize(camel_cased_word)
|
54
|
-
names = camel_cased_word.split('::')
|
55
|
-
|
56
|
-
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
57
|
-
Object.const_get(camel_cased_word) if names.empty?
|
58
|
-
|
59
|
-
# Remove the first blank element in case of '::ClassName' notation.
|
60
|
-
names.shift if names.size > 1 && names.first.empty?
|
61
|
-
|
62
|
-
names.inject(Object) do |constant, name|
|
63
|
-
if constant == Object
|
64
|
-
constant.const_get(name)
|
65
|
-
else
|
66
|
-
candidate = constant.const_get(name)
|
67
|
-
next candidate if constant.const_defined?(name, false)
|
68
|
-
next candidate unless Object.const_defined?(name)
|
69
|
-
|
70
|
-
# Go down the ancestors to check if it is owned directly. The check
|
71
|
-
# stops when we reach Object or the end of ancestors tree.
|
72
|
-
constant = constant.ancestors.inject do |const, ancestor|
|
73
|
-
break const if ancestor == Object
|
74
|
-
break ancestor if ancestor.const_defined?(name, false)
|
75
|
-
const
|
76
|
-
end
|
77
|
-
|
78
|
-
# owner is in Object, so raise
|
79
|
-
constant.const_get(name, false)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'cucumber/gherkin/formatter/hashable'
|
2
|
-
|
3
|
-
module Cucumber
|
4
|
-
module Gherkin
|
5
|
-
module Formatter
|
6
|
-
class Argument < Hashable
|
7
|
-
#native_impl('gherkin')
|
8
|
-
attr_reader :offset, :val
|
9
|
-
|
10
|
-
# Creates a new Argument that starts at character offset +offset+ with value +val+
|
11
|
-
def initialize(offset, val)
|
12
|
-
@offset, @val = offset, val
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Cucumber
|
2
|
-
module Gherkin
|
3
|
-
module Formatter
|
4
|
-
class Hashable
|
5
|
-
def to_hash
|
6
|
-
ivars = instance_variables
|
7
|
-
# When tests are runn with therubyracer (JavaScript), an extra field might
|
8
|
-
# exist - added by Ref::WeakReference
|
9
|
-
# https://github.com/bdurand/ref/blob/master/lib/ref/weak_reference/pure_ruby.rb
|
10
|
-
# Remove it - we don't want it in the JSON.
|
11
|
-
ivars.delete(:@__weak_backreferences__)
|
12
|
-
ivars.inject({}) do |hash, ivar|
|
13
|
-
value = instance_variable_get(ivar)
|
14
|
-
value = value.to_hash if value.respond_to?(:to_hash)
|
15
|
-
if Array === value
|
16
|
-
value = value.map do |e|
|
17
|
-
e.respond_to?(:to_hash) ? e.to_hash : e
|
18
|
-
end
|
19
|
-
end
|
20
|
-
hash[ivar[1..-1]] = value unless [[], nil].index(value)
|
21
|
-
hash
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Cucumber
|
2
|
-
# This module defines the API for programming language support in Cucumber.
|
3
|
-
# While Cucumber itself is written in Ruby, any programming language can
|
4
|
-
# be supported by implementing this API.
|
5
|
-
#
|
6
|
-
# For the sake of illustration we'll consider an imaginary language called
|
7
|
-
# _why. _why files have the .why extension, so we need to put support for
|
8
|
-
# this language in the <tt>Cucumber::WhySupport::WhyLanguage</tt>. This
|
9
|
-
# class must be defined in a file called <tt>cucumber/why_support/why_language.rb</tt>
|
10
|
-
# and be available on Ruby's <tt>$LOAD_PATH</tt>:
|
11
|
-
#
|
12
|
-
# module Cucumber
|
13
|
-
# module WhySupport
|
14
|
-
# class WhyLanguage
|
15
|
-
#
|
16
|
-
# # Uses whatever available language bridge to load
|
17
|
-
# # +why_file+ and returns an Array of StepDefinition.
|
18
|
-
# def load_code_file(why_file)
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# Each language implementation manages its own hooks, and must execute them
|
25
|
-
# at appropriate times.
|
26
|
-
#
|
27
|
-
#
|
28
|
-
module LanguageSupport
|
29
|
-
end
|
30
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require 'cucumber/step_match'
|
2
|
-
require 'cucumber/step_definition_light'
|
3
|
-
|
4
|
-
module Cucumber
|
5
|
-
module LanguageSupport
|
6
|
-
module LanguageMethods
|
7
|
-
|
8
|
-
def after_configuration(cli_configuration)
|
9
|
-
configuration = Configuration.new(cli_configuration)
|
10
|
-
hooks[:after_configuration].each do |hook|
|
11
|
-
hook.invoke('AfterConfiguration', configuration)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def execute_transforms(args)
|
16
|
-
args.map do |arg|
|
17
|
-
matching_transform = transforms.detect {|transform| transform.match(arg) }
|
18
|
-
matching_transform ? matching_transform.invoke(arg) : arg
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def add_hook(phase, hook)
|
23
|
-
hooks[phase.to_sym] << hook
|
24
|
-
hook
|
25
|
-
end
|
26
|
-
|
27
|
-
def clear_hooks
|
28
|
-
@hooks = nil
|
29
|
-
end
|
30
|
-
|
31
|
-
def add_transform(transform)
|
32
|
-
transforms.unshift transform
|
33
|
-
transform
|
34
|
-
end
|
35
|
-
|
36
|
-
def hooks_for(phase, scenario) #:nodoc:
|
37
|
-
hooks[phase.to_sym].select{|hook| scenario.accept_hook?(hook)}
|
38
|
-
end
|
39
|
-
|
40
|
-
def unmatched_step_definitions
|
41
|
-
available_step_definition_hash.keys - invoked_step_definition_hash.keys
|
42
|
-
end
|
43
|
-
|
44
|
-
def available_step_definition(regexp_source, location)
|
45
|
-
available_step_definition_hash[StepDefinitionLight.new(regexp_source, location)] = nil
|
46
|
-
end
|
47
|
-
|
48
|
-
def invoked_step_definition(regexp_source, location)
|
49
|
-
invoked_step_definition_hash[StepDefinitionLight.new(regexp_source, location)] = nil
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def available_step_definition_hash
|
55
|
-
@available_step_definition_hash ||= {}
|
56
|
-
end
|
57
|
-
|
58
|
-
def invoked_step_definition_hash
|
59
|
-
@invoked_step_definition_hash ||= {}
|
60
|
-
end
|
61
|
-
|
62
|
-
def hooks
|
63
|
-
@hooks ||= Hash.new{|h,k| h[k] = []}
|
64
|
-
end
|
65
|
-
|
66
|
-
def transforms
|
67
|
-
@transforms ||= []
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|