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