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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a5ba16d6f3fc1772d232afd8159f009c8464e586
4
- data.tar.gz: 69531a546edaa1bd2d51cb66510451043f32e87a
2
+ SHA256:
3
+ metadata.gz: c03c5c2ccda9326120bc377c75a0a3c56e386070c108c677f6bffea29bc21eb6
4
+ data.tar.gz: 965d2ec74b9fbfba44d2355d2d8ba083a24c82be5cd72d371a4ab504049a2f77
5
5
  SHA512:
6
- metadata.gz: ee28cc3b48def98ad79cae99e5b8eb4ded00dd08e550235d2289a89ad2d4a46a2ef58709294089289adb4aed9a69b60093f655879aa1a9e66164e23dba0942f2
7
- data.tar.gz: 1809cd9af683812a02b68fd82ef97a858bc5529dd9951718cfff8dd940fe8eef2a43eb6d5f78d62148588fe5c2698db031888b382928a64fdc1acbc351ca5685
6
+ metadata.gz: 063f801da4e9df7f0a0a592b3823ac173255dd218f52b97dccdddc0a735ecbd33317ffbb93f223688c563f43e0f567751ae98d47b4db5314200205c96bd2be58
7
+ data.tar.gz: 62f5793d529b180b0ace6012db447f763ba6029438a0140d9f665893dafa75bcef653d74ec641658d3075014a74b7661a0264ea776564c415d8fc3e6a020c387
@@ -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
- ## [In Git](https://github.com/cucumber/cucumber-ruby-core/compare/v5.0.0...master)
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
- * N/A
7
+ * Updated gems:
8
+ * `cucumber-gherkin` ~> 14.0.1
9
+ * `cucumber-messages` ~> 12.2.0
8
10
 
9
- ### Added
11
+ ## [7.0.0](https://github.com/cucumber/cucumber-ruby-core/compare/v6.0.0...v7.0.0)
10
12
 
11
- * N/A
13
+ ### Changed
12
14
 
13
- ### Fixed
15
+ * Updated monorepo libraries:
16
+ - cucumber-gherkin ~> 13
17
+ - cucumber-messages ~> 12
14
18
 
15
- * N/A
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
- * N/A
38
+ * Remove location for MultiLine arguments
20
39
 
21
- ### Improved
22
40
 
23
- * N/A
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
  [![Chat with us](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cucumber/cucumber-ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+ [![CircleCI](https://circleci.com/gh/cucumber/cucumber-ruby-core.svg?style=svg)](https://circleci.com/gh/cucumber/cucumber-ruby-core)
4
5
  [![Build Status](https://travis-ci.org/cucumber/cucumber-ruby-core.svg?branch=master)](https://travis-ci.org/cucumber/cucumber-ruby-core)
5
6
  [![Code Climate](https://codeclimate.com/github/cucumber/cucumber-ruby-core.svg)](https://codeclimate.com/github/cucumber/cucumber-ruby-core)
6
7
  [![Coverage Status](https://coveralls.io/repos/cucumber/cucumber-ruby-core/badge.svg?branch=master)](https://coveralls.io/r/cucumber/cucumber-ruby-core?branch=master)
@@ -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
- compiler = Compiler.new(first_receiver)
21
- parse gherkin_documents, compiler, event_bus
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.locations.map { |location| location.line }.sort.reverse
37
- tags = pickle.tags.map { |tag| Test::Tag.new(Test::Location.new(uri, tag.location.line), tag.name) }
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.locations.map { |location| location.line }.sort.reverse
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.contentType,
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
@@ -1,5 +1,3 @@
1
- require 'backports/2.1.0/array/to_h'
2
-
3
1
  module Cucumber
4
2
  module Core
5
3
  class Event
@@ -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/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::Gherkin.from_source(document.uri, document.body, {default_dialect: document.language, include_source: false})
20
+ messages = ::Gherkin.from_source(document.uri, document.body, gherkin_options(document))
20
21
  messages.each do |message|
21
- if !message.gherkinDocument.nil?
22
- event_bus.gherkin_source_parsed(message.gherkinDocument)
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 !message.attachment.nil?
26
- # Parse error
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, tag_statement, name_statement, description_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, location)
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, location)
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, location)
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, location)
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} (#{location})>}
88
+ %{#<#{self.class} #{raw.inspect})>}
93
89
  end
94
90
 
95
91
  private