cucumber-core 1.0.0.beta.4 → 1.0.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 +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
|
|