cucumber-core 5.0.0 → 7.1.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 +5 -5
- data/CHANGELOG.md +37 -9
- data/README.md +1 -0
- data/lib/cucumber/core.rb +8 -6
- data/lib/cucumber/core/compiler.rb +34 -13
- data/lib/cucumber/core/event.rb +0 -2
- data/lib/cucumber/core/events.rb +25 -0
- data/lib/cucumber/core/gherkin/parser.rb +21 -10
- data/lib/cucumber/core/gherkin/writer.rb +30 -2
- data/lib/cucumber/core/test/case.rb +5 -4
- data/lib/cucumber/core/test/data_table.rb +5 -9
- data/lib/cucumber/core/test/doc_string.rb +3 -6
- data/lib/cucumber/core/test/result.rb +64 -3
- data/lib/cucumber/core/test/step.rb +6 -5
- data/lib/cucumber/core/version.rb +1 -1
- data/spec/capture_warnings.rb +1 -1
- data/spec/cucumber/core/compiler_spec.rb +66 -3
- data/spec/cucumber/core/gherkin/parser_spec.rb +68 -1
- data/spec/cucumber/core/test/case_spec.rb +3 -2
- data/spec/cucumber/core/test/data_table_spec.rb +10 -12
- data/spec/cucumber/core/test/doc_string_spec.rb +8 -11
- data/spec/cucumber/core/test/location_spec.rb +5 -2
- data/spec/cucumber/core/test/result_spec.rb +31 -1
- data/spec/cucumber/core/test/runner_spec.rb +23 -21
- data/spec/cucumber/core/test/step_spec.rb +10 -9
- data/spec/cucumber/core_spec.rb +1 -1
- metadata +67 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c03c5c2ccda9326120bc377c75a0a3c56e386070c108c677f6bffea29bc21eb6
|
4
|
+
data.tar.gz: 965d2ec74b9fbfba44d2355d2d8ba083a24c82be5cd72d371a4ab504049a2f77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 063f801da4e9df7f0a0a592b3823ac173255dd218f52b97dccdddc0a735ecbd33317ffbb93f223688c563f43e0f567751ae98d47b4db5314200205c96bd2be58
|
7
|
+
data.tar.gz: 62f5793d529b180b0ace6012db447f763ba6029438a0140d9f665893dafa75bcef653d74ec641658d3075014a74b7661a0264ea776564c415d8fc3e6a020c387
|
data/CHANGELOG.md
CHANGED
@@ -1,26 +1,54 @@
|
|
1
1
|
Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) on how to contribute to Cucumber.
|
2
2
|
|
3
|
-
## [
|
3
|
+
## [7.1.0](https://github.com/cucumber/cucumber-ruby-core/compare/v7.0.0...v7.0.1)
|
4
4
|
|
5
5
|
### Changed
|
6
6
|
|
7
|
-
*
|
7
|
+
* Updated gems:
|
8
|
+
* `cucumber-gherkin` ~> 14.0.1
|
9
|
+
* `cucumber-messages` ~> 12.2.0
|
8
10
|
|
9
|
-
|
11
|
+
## [7.0.0](https://github.com/cucumber/cucumber-ruby-core/compare/v6.0.0...v7.0.0)
|
10
12
|
|
11
|
-
|
13
|
+
### Changed
|
12
14
|
|
13
|
-
|
15
|
+
* Updated monorepo libraries:
|
16
|
+
- cucumber-gherkin ~> 13
|
17
|
+
- cucumber-messages ~> 12
|
14
18
|
|
15
|
-
|
19
|
+
## [6.0.0](https://github.com/cucumber/cucumber-ruby-core/compare/v5.0.2...v6.0.0)
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
* Update to Gherkin 10
|
24
|
+
|
25
|
+
### Added
|
26
|
+
|
27
|
+
* Add `envelope` event, which are used when emitting `Cucumber::Messages`
|
28
|
+
* Add `TestCaseCreated` and `TestStepCreated` events, emitted when compiling a `Pickle`
|
29
|
+
* Add `Id` field to `TestCase` and `TestStep`
|
30
|
+
* Added rubocop (with todo file), and removed backports gems
|
31
|
+
([#186](https://github.com/cucumber/cucumber-ruby-core/pull/186),
|
32
|
+
[#182](https://github.com/cucumber/cucumber-ruby-core/issues/182)
|
33
|
+
[tas50](https://github.com/tas50),
|
34
|
+
[luke-hill](https://github.com/luke-hill))
|
16
35
|
|
17
36
|
### Removed
|
18
37
|
|
19
|
-
*
|
38
|
+
* Remove location for MultiLine arguments
|
20
39
|
|
21
|
-
### Improved
|
22
40
|
|
23
|
-
|
41
|
+
## [5.0.2](https://github.com/cucumber/cucumber-ruby-core/compare/v5.0.1...v5.0.2)
|
42
|
+
|
43
|
+
### Changed
|
44
|
+
|
45
|
+
* Update to use Gherkin v8
|
46
|
+
|
47
|
+
## [5.0.1](https://github.com/cucumber/cucumber-ruby-core/compare/v5.0.0...v5.0.1)
|
48
|
+
|
49
|
+
### Removed
|
50
|
+
|
51
|
+
* Remove support for ruby 2.2 and below. 2.3 or higher is required now.
|
24
52
|
|
25
53
|
## [5.0.0](https://github.com/cucumber/cucumber-ruby-core/compare/v4.0.0...v5.0.0)
|
26
54
|
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# cucumber-core
|
2
2
|
|
3
3
|
[](https://gitter.im/cucumber/cucumber-ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
|
+
[](https://circleci.com/gh/cucumber/cucumber-ruby-core)
|
4
5
|
[](https://travis-ci.org/cucumber/cucumber-ruby-core)
|
5
6
|
[](https://codeclimate.com/github/cucumber/cucumber-ruby-core)
|
6
7
|
[](https://coveralls.io/r/cucumber/cucumber-ruby-core?branch=master)
|
data/lib/cucumber/core.rb
CHANGED
@@ -4,6 +4,8 @@ require 'cucumber/core/gherkin/parser'
|
|
4
4
|
require 'cucumber/core/gherkin/document'
|
5
5
|
require 'cucumber/core/compiler'
|
6
6
|
require 'cucumber/core/test/runner'
|
7
|
+
require 'cucumber/messages'
|
8
|
+
require 'gherkin/query'
|
7
9
|
|
8
10
|
module Cucumber
|
9
11
|
module Core
|
@@ -11,21 +13,22 @@ module Cucumber
|
|
11
13
|
def execute(gherkin_documents, filters = [], event_bus = EventBus.new)
|
12
14
|
yield event_bus if block_given?
|
13
15
|
receiver = Test::Runner.new(event_bus)
|
14
|
-
compile gherkin_documents, receiver, filters
|
16
|
+
compile gherkin_documents, receiver, filters, event_bus
|
15
17
|
self
|
16
18
|
end
|
17
19
|
|
18
20
|
def compile(gherkin_documents, last_receiver, filters = [], event_bus = EventBus.new)
|
19
21
|
first_receiver = compose(filters, last_receiver)
|
20
|
-
|
21
|
-
|
22
|
+
gherkin_query = ::Gherkin::Query.new
|
23
|
+
compiler = Compiler.new(first_receiver, gherkin_query, event_bus)
|
24
|
+
parse gherkin_documents, compiler, event_bus, gherkin_query
|
22
25
|
self
|
23
26
|
end
|
24
27
|
|
25
28
|
private
|
26
29
|
|
27
|
-
def parse(gherkin_documents, compiler, event_bus)
|
28
|
-
parser = Core::Gherkin::Parser.new(compiler, event_bus)
|
30
|
+
def parse(gherkin_documents, compiler, event_bus, gherkin_query)
|
31
|
+
parser = Core::Gherkin::Parser.new(compiler, event_bus, gherkin_query)
|
29
32
|
gherkin_documents.each do |document|
|
30
33
|
parser.document document
|
31
34
|
end
|
@@ -38,6 +41,5 @@ module Cucumber
|
|
38
41
|
filter.with_receiver(receiver)
|
39
42
|
end
|
40
43
|
end
|
41
|
-
|
42
44
|
end
|
43
45
|
end
|
@@ -6,16 +6,20 @@ require 'cucumber/core/test/tag'
|
|
6
6
|
require 'cucumber/core/test/doc_string'
|
7
7
|
require 'cucumber/core/test/data_table'
|
8
8
|
require 'cucumber/core/test/empty_multiline_argument'
|
9
|
+
require 'cucumber/messages'
|
9
10
|
|
10
11
|
module Cucumber
|
11
12
|
module Core
|
12
13
|
# Compiles the Pickles into test cases
|
13
14
|
class Compiler
|
14
|
-
attr_reader :receiver
|
15
|
-
private :receiver
|
15
|
+
attr_reader :receiver, :gherkin_query, :id_generator
|
16
|
+
private :receiver, :gherkin_query, :id_generator
|
16
17
|
|
17
|
-
def initialize(receiver)
|
18
|
+
def initialize(receiver, gherkin_query, event_bus = nil)
|
18
19
|
@receiver = receiver
|
20
|
+
@id_generator = Cucumber::Messages::IdGenerator::UUID.new
|
21
|
+
@gherkin_query = gherkin_query
|
22
|
+
@event_bus = event_bus
|
19
23
|
end
|
20
24
|
|
21
25
|
def pickle(pickle)
|
@@ -33,15 +37,19 @@ module Cucumber
|
|
33
37
|
def create_test_case(pickle)
|
34
38
|
uri = pickle.uri
|
35
39
|
test_steps = pickle.steps.map { |step| create_test_step(step, uri) }
|
36
|
-
lines = pickle.
|
37
|
-
tags = pickle.tags.map { |tag| Test::Tag.new(Test::Location.new(uri, tag
|
38
|
-
Test::Case.new(pickle.name, test_steps, Test::Location.new(uri, lines), tags, pickle.language)
|
40
|
+
lines = source_lines_for_pickle(pickle).sort.reverse
|
41
|
+
tags = pickle.tags.map { |tag| Test::Tag.new(Test::Location.new(uri, source_line_for_pickle_tag(tag)), tag.name) }
|
42
|
+
test_case = Test::Case.new(id_generator.new_id, pickle.name, test_steps, Test::Location.new(uri, lines), tags, pickle.language)
|
43
|
+
@event_bus.test_case_created(test_case, pickle) unless @event_bus.nil?
|
44
|
+
test_case
|
39
45
|
end
|
40
46
|
|
41
47
|
def create_test_step(pickle_step, uri)
|
42
|
-
lines = pickle_step.
|
48
|
+
lines = source_lines_for_pickle_step(pickle_step).sort.reverse
|
43
49
|
multiline_arg = create_multiline_arg(pickle_step, uri)
|
44
|
-
Test::Step.new(pickle_step.text, Test::Location.new(uri, lines), multiline_arg)
|
50
|
+
step = Test::Step.new(id_generator.new_id, pickle_step.text, Test::Location.new(uri, lines), multiline_arg)
|
51
|
+
@event_bus.test_step_created(step, pickle_step) unless @event_bus.nil?
|
52
|
+
step
|
45
53
|
end
|
46
54
|
|
47
55
|
def create_multiline_arg(pickle_step, uri)
|
@@ -50,21 +58,34 @@ module Cucumber
|
|
50
58
|
doc_string = pickle_step.argument.doc_string
|
51
59
|
Test::DocString.new(
|
52
60
|
doc_string.content,
|
53
|
-
doc_string.
|
54
|
-
Test::Location.new(uri, doc_string.location.line)
|
61
|
+
doc_string.media_type
|
55
62
|
)
|
56
63
|
elsif pickle_step.argument.data_table
|
57
64
|
data_table = pickle_step.argument.data_table
|
58
|
-
first_cell = data_table.rows.first.cells.first
|
59
65
|
Test::DataTable.new(
|
60
|
-
data_table.rows.map { |row| row.cells.map { |cell| cell.value } }
|
61
|
-
Test::Location.new(uri, first_cell.location.line)
|
66
|
+
data_table.rows.map { |row| row.cells.map { |cell| cell.value } }
|
62
67
|
)
|
63
68
|
end
|
64
69
|
else
|
65
70
|
Test::EmptyMultilineArgument.new
|
66
71
|
end
|
67
72
|
end
|
73
|
+
|
74
|
+
def source_lines_for_pickle(pickle)
|
75
|
+
pickle.ast_node_ids.map { |id| source_line(id) }
|
76
|
+
end
|
77
|
+
|
78
|
+
def source_lines_for_pickle_step(pickle_step)
|
79
|
+
pickle_step.ast_node_ids.map { |id| source_line(id) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def source_line_for_pickle_tag(tag)
|
83
|
+
source_line(tag.ast_node_id)
|
84
|
+
end
|
85
|
+
|
86
|
+
def source_line(id)
|
87
|
+
gherkin_query.location(id).line
|
88
|
+
end
|
68
89
|
end
|
69
90
|
end
|
70
91
|
end
|
data/lib/cucumber/core/event.rb
CHANGED
data/lib/cucumber/core/events.rb
CHANGED
@@ -5,6 +5,10 @@ module Cucumber
|
|
5
5
|
module Core
|
6
6
|
module Events
|
7
7
|
|
8
|
+
class Envelope < Event.new(:envelope)
|
9
|
+
attr_reader :envelope
|
10
|
+
end
|
11
|
+
|
8
12
|
# Signals that a gherkin source has been parsed
|
9
13
|
class GherkinSourceParsed < Event.new(:gherkin_document)
|
10
14
|
# @return [GherkinDocument] the GherkinDocument Ast Node
|
@@ -12,6 +16,24 @@ module Cucumber
|
|
12
16
|
|
13
17
|
end
|
14
18
|
|
19
|
+
# Signals that a Test::Step was created from a PickleStep
|
20
|
+
class TestStepCreated < Event.new(:test_step, :pickle_step)
|
21
|
+
# The created test step
|
22
|
+
attr_reader :test_step
|
23
|
+
|
24
|
+
# The source pickle step
|
25
|
+
attr_reader :pickle_step
|
26
|
+
end
|
27
|
+
|
28
|
+
# Signals that a Test::Case was created from a Pickle
|
29
|
+
class TestCaseCreated < Event.new(:test_case, :pickle)
|
30
|
+
# The created test step
|
31
|
+
attr_reader :test_case
|
32
|
+
|
33
|
+
# The source pickle step
|
34
|
+
attr_reader :pickle
|
35
|
+
end
|
36
|
+
|
15
37
|
# Signals that a {Test::Case} is about to be executed
|
16
38
|
class TestCaseStarted < Event.new(:test_case)
|
17
39
|
|
@@ -55,7 +77,10 @@ module Cucumber
|
|
55
77
|
# that will be used by the {EventBus} by default.
|
56
78
|
def self.registry
|
57
79
|
build_registry(
|
80
|
+
Envelope,
|
58
81
|
GherkinSourceParsed,
|
82
|
+
TestStepCreated,
|
83
|
+
TestCaseCreated,
|
59
84
|
TestCaseStarted,
|
60
85
|
TestStepStarted,
|
61
86
|
TestStepFinished,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'gherkin
|
2
|
+
require 'gherkin'
|
3
3
|
|
4
4
|
module Cucumber
|
5
5
|
module Core
|
@@ -7,30 +7,41 @@ module Cucumber
|
|
7
7
|
ParseError = Class.new(StandardError)
|
8
8
|
|
9
9
|
class Parser
|
10
|
-
attr_reader :receiver, :event_bus
|
11
|
-
private :receiver, :event_bus
|
10
|
+
attr_reader :receiver, :event_bus, :gherkin_query
|
11
|
+
private :receiver, :event_bus, :gherkin_query
|
12
12
|
|
13
|
-
def initialize(receiver, event_bus)
|
13
|
+
def initialize(receiver, event_bus, gherkin_query)
|
14
14
|
@receiver = receiver
|
15
15
|
@event_bus = event_bus
|
16
|
+
@gherkin_query = gherkin_query
|
16
17
|
end
|
17
18
|
|
18
19
|
def document(document)
|
19
|
-
messages = ::Gherkin
|
20
|
+
messages = ::Gherkin.from_source(document.uri, document.body, gherkin_options(document))
|
20
21
|
messages.each do |message|
|
21
|
-
|
22
|
-
|
22
|
+
event_bus.envelope(message)
|
23
|
+
gherkin_query.update(message)
|
24
|
+
if !message.gherkin_document.nil?
|
25
|
+
event_bus.gherkin_source_parsed(message.gherkin_document)
|
23
26
|
elsif !message.pickle.nil?
|
24
27
|
receiver.pickle(message.pickle)
|
25
|
-
elsif
|
26
|
-
#
|
27
|
-
raise Core::Gherkin::ParseError.new("#{document.uri}: #{message.attachment.data}")
|
28
|
+
elsif message.parse_error
|
29
|
+
raise Core::Gherkin::ParseError.new("#{document.uri}: #{message.parse_error.message}")
|
28
30
|
else
|
29
31
|
raise "Unknown message: #{message.to_hash}"
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
36
|
+
def gherkin_options(document)
|
37
|
+
{
|
38
|
+
default_dialect: document.language,
|
39
|
+
include_source: false,
|
40
|
+
include_gherkin_document: true,
|
41
|
+
include_pickles: true
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
34
45
|
def done
|
35
46
|
receiver.done
|
36
47
|
self
|
@@ -48,7 +48,7 @@ module Cucumber
|
|
48
48
|
|
49
49
|
default_keyword 'Feature'
|
50
50
|
|
51
|
-
elements :background, :scenario, :scenario_outline
|
51
|
+
elements :background, :rule, :scenario, :scenario_outline
|
52
52
|
|
53
53
|
def build(source = [])
|
54
54
|
elements.inject(source + statements) { |acc, el| el.build(acc) + [NEW_LINE] }
|
@@ -85,7 +85,29 @@ module Cucumber
|
|
85
85
|
|
86
86
|
private
|
87
87
|
def statements
|
88
|
-
prepare_statements comments_statement,
|
88
|
+
prepare_statements comments_statement,
|
89
|
+
tag_statement,
|
90
|
+
name_statement,
|
91
|
+
description_statement
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class Rule
|
96
|
+
include HasElements
|
97
|
+
include HasOptionsInitializer
|
98
|
+
include HasDescription
|
99
|
+
include Indentation.level 2
|
100
|
+
|
101
|
+
default_keyword 'Rule'
|
102
|
+
|
103
|
+
elements :example, :scenario
|
104
|
+
|
105
|
+
private
|
106
|
+
def statements
|
107
|
+
prepare_statements comments_statement,
|
108
|
+
name_statement,
|
109
|
+
description_statement,
|
110
|
+
NEW_LINE
|
89
111
|
end
|
90
112
|
end
|
91
113
|
|
@@ -108,6 +130,12 @@ module Cucumber
|
|
108
130
|
end
|
109
131
|
end
|
110
132
|
|
133
|
+
class Example < Scenario
|
134
|
+
include Indentation.level 4
|
135
|
+
|
136
|
+
default_keyword 'Example'
|
137
|
+
end
|
138
|
+
|
111
139
|
class ScenarioOutline
|
112
140
|
include HasElements
|
113
141
|
include HasOptionsInitializer
|
@@ -7,10 +7,11 @@ module Cucumber
|
|
7
7
|
module Core
|
8
8
|
module Test
|
9
9
|
class Case
|
10
|
-
attr_reader :name, :test_steps, :location, :tags, :language, :around_hooks
|
10
|
+
attr_reader :id, :name, :test_steps, :location, :tags, :language, :around_hooks
|
11
11
|
|
12
|
-
def initialize(name, test_steps, location, tags, language, around_hooks = [])
|
12
|
+
def initialize(id, name, test_steps, location, tags, language, around_hooks = [])
|
13
13
|
raise ArgumentError.new("test_steps should be an Array but is a #{test_steps.class}") unless test_steps.is_a?(Array)
|
14
|
+
@id = id
|
14
15
|
@name = name
|
15
16
|
@test_steps = test_steps
|
16
17
|
@location = location
|
@@ -35,11 +36,11 @@ module Cucumber
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def with_steps(test_steps)
|
38
|
-
self.class.new(name, test_steps, location, tags, language, around_hooks)
|
39
|
+
self.class.new(id, name, test_steps, location, tags, language, around_hooks)
|
39
40
|
end
|
40
41
|
|
41
42
|
def with_around_hooks(around_hooks)
|
42
|
-
self.class.new(name, test_steps, location, tags, language, around_hooks)
|
43
|
+
self.class.new(id, name, test_steps, location, tags, language, around_hooks)
|
43
44
|
end
|
44
45
|
|
45
46
|
def match_tags?(*expressions)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'cucumber/core/test/location'
|
3
2
|
|
4
3
|
module Cucumber
|
5
4
|
module Core
|
@@ -24,18 +23,15 @@ module Cucumber
|
|
24
23
|
# This will store <tt>[['a', 'b'], ['c', 'd']]</tt> in the <tt>data</tt> variable.
|
25
24
|
#
|
26
25
|
class DataTable
|
27
|
-
include HasLocation
|
28
|
-
|
29
26
|
# Creates a new instance. +raw+ should be an Array of Array of String
|
30
27
|
# or an Array of Hash
|
31
28
|
# You don't typically create your own DataTable objects - Cucumber will do
|
32
29
|
# it internally and pass them to your Step Definitions.
|
33
30
|
#
|
34
|
-
def initialize(rows
|
31
|
+
def initialize(rows)
|
35
32
|
raw = ensure_array_of_array(rows)
|
36
33
|
verify_rows_are_same_length(raw)
|
37
34
|
@raw = raw.freeze
|
38
|
-
@location = location
|
39
35
|
end
|
40
36
|
attr_reader :raw
|
41
37
|
|
@@ -58,7 +54,7 @@ module Cucumber
|
|
58
54
|
# Creates a copy of this table
|
59
55
|
#
|
60
56
|
def dup
|
61
|
-
self.class.new(raw.dup
|
57
|
+
self.class.new(raw.dup)
|
62
58
|
end
|
63
59
|
|
64
60
|
# Returns a new, transposed table. Example:
|
@@ -73,7 +69,7 @@ module Cucumber
|
|
73
69
|
# | 4 | 2 |
|
74
70
|
#
|
75
71
|
def transpose
|
76
|
-
self.class.new(raw.transpose
|
72
|
+
self.class.new(raw.transpose)
|
77
73
|
end
|
78
74
|
|
79
75
|
def map(&block)
|
@@ -81,7 +77,7 @@ module Cucumber
|
|
81
77
|
row.map(&block)
|
82
78
|
end
|
83
79
|
|
84
|
-
self.class.new(new_raw
|
80
|
+
self.class.new(new_raw)
|
85
81
|
end
|
86
82
|
|
87
83
|
def ==(other)
|
@@ -89,7 +85,7 @@ module Cucumber
|
|
89
85
|
end
|
90
86
|
|
91
87
|
def inspect
|
92
|
-
%{#<#{self.class} #{raw.inspect}
|
88
|
+
%{#<#{self.class} #{raw.inspect})>}
|
93
89
|
end
|
94
90
|
|
95
91
|
private
|