cucumber-core 1.0.0.beta.4 → 1.0.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 +1 -0
- data/CONTRIBUTING.md +14 -0
- data/HISTORY.md +14 -1
- data/README.md +34 -33
- data/lib/cucumber/core.rb +3 -5
- data/lib/cucumber/core/ast/background.rb +13 -2
- data/lib/cucumber/core/ast/comment.rb +8 -2
- data/lib/cucumber/core/ast/examples_table.rb +14 -5
- data/lib/cucumber/core/ast/feature.rb +15 -6
- data/lib/cucumber/core/ast/scenario.rb +17 -4
- data/lib/cucumber/core/ast/scenario_outline.rb +20 -8
- data/lib/cucumber/core/ast/tag.rb +5 -3
- data/lib/cucumber/core/compiler.rb +39 -7
- data/lib/cucumber/core/filter.rb +83 -0
- data/lib/cucumber/core/gherkin/ast_builder.rb +7 -2
- data/lib/cucumber/core/gherkin/document.rb +5 -2
- data/lib/cucumber/core/gherkin/parser.rb +6 -1
- data/lib/cucumber/core/test/action.rb +8 -8
- data/lib/cucumber/core/test/around_hook.rb +19 -0
- data/lib/cucumber/core/test/case.rb +6 -4
- data/lib/cucumber/core/test/filters/locations_filter.rb +3 -6
- data/lib/cucumber/core/test/filters/name_filter.rb +3 -7
- data/lib/cucumber/core/test/filters/tag_filter.rb +4 -2
- data/lib/cucumber/core/test/result.rb +5 -7
- data/lib/cucumber/core/test/runner.rb +39 -40
- data/lib/cucumber/core/test/step.rb +7 -10
- data/lib/cucumber/core/version.rb +1 -1
- data/spec/capture_warnings.rb +5 -0
- data/spec/cucumber/core/filter_spec.rb +100 -0
- data/spec/cucumber/core/gherkin/parser_spec.rb +0 -1
- data/spec/cucumber/core/test/action_spec.rb +29 -31
- data/spec/cucumber/core/test/runner_spec.rb +5 -5
- data/spec/cucumber/core/test/step_spec.rb +18 -9
- data/spec/cucumber/core_spec.rb +40 -172
- metadata +11 -16
- data/lib/cucumber/core/test/hooks.rb +0 -93
- data/lib/cucumber/core/test/mapper.rb +0 -150
- data/lib/cucumber/initializer.rb +0 -18
- data/spec/cucumber/core/test/hooks_spec.rb +0 -30
- data/spec/cucumber/core/test/mapper_spec.rb +0 -203
- data/spec/cucumber/initializer_spec.rb +0 -49
@@ -0,0 +1,83 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Core
|
3
|
+
|
4
|
+
# Filters process test cases.
|
5
|
+
#
|
6
|
+
# Each filter must respond to the following protocol:
|
7
|
+
#
|
8
|
+
# * `with_receiver(new_receiver)`
|
9
|
+
# * `test_case(test_case, &describe_test_steps)`
|
10
|
+
# * `done`
|
11
|
+
#
|
12
|
+
# The `with_receiver` method is used to assemble the filters into a chain. It should return a new instance of the
|
13
|
+
# filter with the receiver attribute set to the new receiver. The receiver will also respond to the filter protocol.
|
14
|
+
#
|
15
|
+
# When a `test_case` message is received, the filter can choose to:
|
16
|
+
#
|
17
|
+
# 1. pass the test_case directly to its receiver (no-op)
|
18
|
+
# 2. pass a modified copy of the test_case to its receiver
|
19
|
+
# 3. not pass the test_case to its receiver at all
|
20
|
+
#
|
21
|
+
# Finally, the `done` message is sent. A filter should pass this message directly to its receiver.
|
22
|
+
#
|
23
|
+
module Filter
|
24
|
+
|
25
|
+
# Utility method for quick construction of filter classes.
|
26
|
+
#
|
27
|
+
# @example Example usage:
|
28
|
+
#
|
29
|
+
# class BlankingFilter < Filter.new(:name_to_blank, :receiver)
|
30
|
+
# def test_case(test_case)
|
31
|
+
# if name_to_blank == test_case.name
|
32
|
+
# test_case.with_steps([]).describe_to(receiver)
|
33
|
+
# else
|
34
|
+
# test_case.describe_to(receiver)
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# The attribute names passed to the Filter constructor will become private attributes of
|
40
|
+
# your filter class.
|
41
|
+
#
|
42
|
+
def self.new(*attributes, &block)
|
43
|
+
attributes << :receiver
|
44
|
+
|
45
|
+
result = Class.new do
|
46
|
+
attr_reader(*attributes)
|
47
|
+
private(*attributes)
|
48
|
+
|
49
|
+
define_method(:initialize) do |*args|
|
50
|
+
attributes.zip(args) do |name, value|
|
51
|
+
instance_variable_set("@#{name}".to_sym, value)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_case(test_case)
|
56
|
+
test_case.describe_to receiver
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def done
|
61
|
+
receiver.done
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
define_method(:with_receiver) do |new_receiver|
|
66
|
+
args = attributes.map { |name|
|
67
|
+
instance_variable_get("@#{name}".to_sym)
|
68
|
+
}
|
69
|
+
args[-1] = new_receiver
|
70
|
+
self.class.new(*args)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
if block
|
76
|
+
Class.new(result, &block)
|
77
|
+
else
|
78
|
+
result
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'cucumber/initializer'
|
2
1
|
require 'cucumber/core/ast'
|
3
2
|
require 'cucumber/core/platform'
|
4
3
|
require 'gherkin/rubify'
|
@@ -76,7 +75,13 @@ module Cucumber
|
|
76
75
|
end
|
77
76
|
|
78
77
|
class Builder
|
79
|
-
|
78
|
+
attr_reader :file, :node
|
79
|
+
private :file, :node
|
80
|
+
|
81
|
+
def initialize(file, node)
|
82
|
+
@file = file
|
83
|
+
@node = node
|
84
|
+
end
|
80
85
|
|
81
86
|
private
|
82
87
|
|
@@ -1,12 +1,15 @@
|
|
1
|
-
require 'cucumber/initializer'
|
2
1
|
|
3
2
|
module Cucumber
|
4
3
|
module Core
|
5
4
|
module Gherkin
|
6
5
|
class Document
|
7
|
-
include Cucumber.initializer(:uri, :body)
|
8
6
|
attr_reader :uri, :body
|
9
7
|
|
8
|
+
def initialize(uri, body)
|
9
|
+
@uri = uri
|
10
|
+
@body = body
|
11
|
+
end
|
12
|
+
|
10
13
|
def to_s
|
11
14
|
body
|
12
15
|
end
|
@@ -7,7 +7,12 @@ module Cucumber
|
|
7
7
|
ParseError = Class.new(StandardError)
|
8
8
|
|
9
9
|
class Parser
|
10
|
-
|
10
|
+
attr_reader :receiver
|
11
|
+
private :receiver
|
12
|
+
|
13
|
+
def initialize(receiver)
|
14
|
+
@receiver = receiver
|
15
|
+
end
|
11
16
|
|
12
17
|
def document(document)
|
13
18
|
builder = AstBuilder.new(document.uri)
|
@@ -8,18 +8,18 @@ module Cucumber
|
|
8
8
|
module Test
|
9
9
|
class Action
|
10
10
|
def initialize(&block)
|
11
|
-
raise ArgumentError, "Passing a block to execute the
|
11
|
+
raise ArgumentError, "Passing a block to execute the action is mandatory." unless block
|
12
12
|
@block = block
|
13
13
|
@timer = Timer.new
|
14
14
|
end
|
15
15
|
|
16
|
-
def skip(
|
16
|
+
def skip(*)
|
17
17
|
skipped
|
18
18
|
end
|
19
19
|
|
20
|
-
def execute(
|
20
|
+
def execute(*args)
|
21
21
|
@timer.start
|
22
|
-
@block.call(
|
22
|
+
@block.call(*args)
|
23
23
|
passed
|
24
24
|
rescue Result::Raisable => exception
|
25
25
|
exception.with_duration(@timer.duration)
|
@@ -51,17 +51,17 @@ module Cucumber
|
|
51
51
|
end
|
52
52
|
|
53
53
|
class UnskippableAction < Action
|
54
|
-
def skip(
|
55
|
-
execute(
|
54
|
+
def skip(*args)
|
55
|
+
execute(*args)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
class UndefinedAction
|
60
|
-
def execute(
|
60
|
+
def execute(*)
|
61
61
|
undefined
|
62
62
|
end
|
63
63
|
|
64
|
-
def skip(
|
64
|
+
def skip(*)
|
65
65
|
undefined
|
66
66
|
end
|
67
67
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Core
|
3
|
+
module Test
|
4
|
+
class AroundHook
|
5
|
+
def initialize(&block)
|
6
|
+
@block = block
|
7
|
+
end
|
8
|
+
|
9
|
+
def describe_to(visitor, *args, &continue)
|
10
|
+
visitor.around_hook(self, *args, &continue)
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(continue)
|
14
|
+
@block.call(continue)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
|
-
require 'cucumber/initializer'
|
2
1
|
require 'cucumber/core/test/result'
|
3
2
|
|
4
3
|
module Cucumber
|
5
4
|
module Core
|
6
5
|
module Test
|
7
6
|
class Case
|
8
|
-
|
9
|
-
|
7
|
+
attr_reader :source, :test_steps, :around_hooks
|
8
|
+
private :around_hooks
|
10
9
|
|
11
10
|
def initialize(test_steps, source, around_hooks = [])
|
12
|
-
|
11
|
+
raise ArgumentError.new("test_steps should be an Array but is a #{test_steps.class}") unless test_steps.kind_of?(Array)
|
12
|
+
@test_steps = test_steps
|
13
|
+
@source = source
|
14
|
+
@around_hooks = around_hooks
|
13
15
|
end
|
14
16
|
|
15
17
|
def step_count
|
@@ -1,8 +1,9 @@
|
|
1
|
+
require 'cucumber/core/filter'
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Core
|
3
5
|
module Test
|
4
|
-
class LocationsFilter
|
5
|
-
include Cucumber.initializer(:locations, :receiver)
|
6
|
+
class LocationsFilter < Filter.new(:locations)
|
6
7
|
|
7
8
|
def test_case(test_case)
|
8
9
|
if test_case.match_locations?(@locations)
|
@@ -11,10 +12,6 @@ module Cucumber
|
|
11
12
|
self
|
12
13
|
end
|
13
14
|
|
14
|
-
def done
|
15
|
-
@receiver.done
|
16
|
-
self
|
17
|
-
end
|
18
15
|
end
|
19
16
|
end
|
20
17
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
+
require 'cucumber/core/filter'
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Core
|
3
5
|
module Test
|
4
|
-
class NameFilter
|
5
|
-
include Cucumber.initializer(:name_regexps, :receiver)
|
6
|
+
class NameFilter < Filter.new(:name_regexps)
|
6
7
|
|
7
8
|
def test_case(test_case)
|
8
9
|
if accept?(test_case)
|
@@ -11,11 +12,6 @@ module Cucumber
|
|
11
12
|
self
|
12
13
|
end
|
13
14
|
|
14
|
-
def done
|
15
|
-
@receiver.done
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
15
|
private
|
20
16
|
|
21
17
|
def accept?(test_case)
|
@@ -1,8 +1,9 @@
|
|
1
|
+
require 'cucumber/core/filter'
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module Core
|
3
5
|
module Test
|
4
|
-
class TagFilter
|
5
|
-
include Cucumber.initializer(:filter_expressions, :receiver)
|
6
|
+
class TagFilter < Filter.new(:filter_expressions)
|
6
7
|
|
7
8
|
def test_case(test_case)
|
8
9
|
test_cases << test_case
|
@@ -19,6 +20,7 @@ module Cucumber
|
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
23
|
+
|
22
24
|
def test_cases
|
23
25
|
@test_cases ||= TestCases.new
|
24
26
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'cucumber/initializer'
|
1
|
+
# encoding: UTF-8
|
3
2
|
|
4
3
|
module Cucumber
|
5
4
|
module Core
|
@@ -29,12 +28,11 @@ module Cucumber
|
|
29
28
|
|
30
29
|
class Passed
|
31
30
|
include Result.status_queries(:passed)
|
32
|
-
|
33
|
-
attr_reader :duration
|
31
|
+
attr_accessor :duration
|
34
32
|
|
35
33
|
def initialize(duration)
|
36
34
|
raise ArgumentError unless duration
|
37
|
-
|
35
|
+
@duration = duration
|
38
36
|
end
|
39
37
|
|
40
38
|
def describe_to(visitor, *args)
|
@@ -50,13 +48,13 @@ module Cucumber
|
|
50
48
|
|
51
49
|
class Failed
|
52
50
|
include Result.status_queries(:failed)
|
53
|
-
include Cucumber.initializer(:duration, :exception)
|
54
51
|
attr_reader :duration, :exception
|
55
52
|
|
56
53
|
def initialize(duration, exception)
|
57
54
|
raise ArgumentError unless duration
|
58
55
|
raise ArgumentError unless exception
|
59
|
-
|
56
|
+
@duration = duration
|
57
|
+
@exception = exception
|
60
58
|
end
|
61
59
|
|
62
60
|
def describe_to(visitor, *args)
|
@@ -1,11 +1,42 @@
|
|
1
|
-
require 'cucumber/initializer'
|
2
1
|
require 'cucumber/core/test/timer'
|
3
2
|
|
4
3
|
module Cucumber
|
5
4
|
module Core
|
6
5
|
module Test
|
7
6
|
class Runner
|
8
|
-
|
7
|
+
attr_reader :report, :running_test_case
|
8
|
+
private :report, :running_test_case
|
9
|
+
|
10
|
+
def initialize(report)
|
11
|
+
@report = report
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_case(test_case, &descend)
|
15
|
+
@running_test_case = RunningTestCase.new
|
16
|
+
report.before_test_case(test_case)
|
17
|
+
descend.call(self)
|
18
|
+
report.after_test_case(test_case, running_test_case.result)
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_step(test_step)
|
23
|
+
report.before_test_step test_step
|
24
|
+
step_result = running_test_case.execute(test_step)
|
25
|
+
report.after_test_step test_step, step_result
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def around_hook(hook, &continue)
|
30
|
+
hook.call(continue)
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def done
|
35
|
+
report.done
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
class RunningTestCase
|
9
40
|
def initialize
|
10
41
|
@timer = Timer.new.start
|
11
42
|
@status = Status::Unknown.new(Result::Unknown.new)
|
@@ -57,7 +88,12 @@ module Cucumber
|
|
57
88
|
|
58
89
|
module Status
|
59
90
|
class Base
|
60
|
-
|
91
|
+
attr_reader :step_result
|
92
|
+
private :step_result
|
93
|
+
|
94
|
+
def initialize(step_result)
|
95
|
+
@step_result = step_result
|
96
|
+
end
|
61
97
|
|
62
98
|
def execute(test_step, monitor)
|
63
99
|
result = test_step.execute(monitor.result)
|
@@ -101,43 +137,6 @@ module Cucumber
|
|
101
137
|
end
|
102
138
|
end
|
103
139
|
|
104
|
-
attr_reader :report
|
105
|
-
private :report
|
106
|
-
def initialize(report)
|
107
|
-
@report = report
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_case(test_case, &descend)
|
111
|
-
report.before_test_case(test_case)
|
112
|
-
descend.call(self)
|
113
|
-
report.after_test_case(test_case, current_case_result)
|
114
|
-
@current_step_runner = nil
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_step(test_step)
|
118
|
-
report.before_test_step test_step
|
119
|
-
step_result = current_step_runner.execute(test_step)
|
120
|
-
report.after_test_step test_step, step_result
|
121
|
-
end
|
122
|
-
|
123
|
-
def around_hook(hook, &continue)
|
124
|
-
hook.call(continue)
|
125
|
-
end
|
126
|
-
|
127
|
-
def done
|
128
|
-
report.done
|
129
|
-
self
|
130
|
-
end
|
131
|
-
|
132
|
-
private
|
133
|
-
|
134
|
-
def current_case_result
|
135
|
-
current_step_runner.result
|
136
|
-
end
|
137
|
-
|
138
|
-
def current_step_runner
|
139
|
-
@current_step_runner ||= StepRunner.new
|
140
|
-
end
|
141
140
|
end
|
142
141
|
end
|
143
142
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'cucumber/initializer'
|
2
1
|
require 'cucumber/core/test/result'
|
3
2
|
require 'cucumber/core/test/action'
|
4
3
|
|
@@ -6,13 +5,11 @@ module Cucumber
|
|
6
5
|
module Core
|
7
6
|
module Test
|
8
7
|
class Step
|
9
|
-
include Cucumber.initializer(:source)
|
10
8
|
attr_reader :source
|
11
9
|
|
12
|
-
def initialize(source,
|
10
|
+
def initialize(source, action = Test::UndefinedAction.new)
|
13
11
|
raise ArgumentError if source.any?(&:nil?)
|
14
|
-
@
|
15
|
-
super(source)
|
12
|
+
@source, @action = source, action
|
16
13
|
end
|
17
14
|
|
18
15
|
def describe_to(visitor, *args)
|
@@ -26,15 +23,15 @@ module Cucumber
|
|
26
23
|
self
|
27
24
|
end
|
28
25
|
|
29
|
-
def skip(
|
30
|
-
@
|
26
|
+
def skip(*args)
|
27
|
+
@action.skip(*args)
|
31
28
|
end
|
32
29
|
|
33
|
-
def execute(
|
34
|
-
@
|
30
|
+
def execute(*args)
|
31
|
+
@action.execute(*args)
|
35
32
|
end
|
36
33
|
|
37
|
-
def
|
34
|
+
def with_action(&block)
|
38
35
|
self.class.new(source, Test::Action.new(&block))
|
39
36
|
end
|
40
37
|
|