cucumber-core 16.0.0 → 16.1.1

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/lib/cucumber/core/event.rb +2 -3
  4. data/lib/cucumber/core/event_bus.rb +2 -2
  5. data/lib/cucumber/core/events/envelope.rb +13 -0
  6. data/lib/cucumber/core/events/gherkin_source_parsed.rb +15 -0
  7. data/lib/cucumber/core/events/test_case_created.rb +18 -0
  8. data/lib/cucumber/core/events/test_case_finished.rb +18 -0
  9. data/lib/cucumber/core/events/test_case_started.rb +15 -0
  10. data/lib/cucumber/core/events/test_step_created.rb +18 -0
  11. data/lib/cucumber/core/events/test_step_finished.rb +18 -0
  12. data/lib/cucumber/core/events/test_step_started.rb +15 -0
  13. data/lib/cucumber/core/events.rb +14 -69
  14. data/lib/cucumber/core/gherkin/writer/background.rb +33 -0
  15. data/lib/cucumber/core/gherkin/writer/doc_string.rb +41 -0
  16. data/lib/cucumber/core/gherkin/writer/example.rb +18 -0
  17. data/lib/cucumber/core/gherkin/writer/examples.rb +39 -0
  18. data/lib/cucumber/core/gherkin/writer/feature.rb +49 -0
  19. data/lib/cucumber/core/gherkin/writer/gherkin.rb +39 -0
  20. data/lib/cucumber/core/gherkin/writer/rule.rb +35 -0
  21. data/lib/cucumber/core/gherkin/writer/scenario.rb +33 -0
  22. data/lib/cucumber/core/gherkin/writer/scenario_outline.rb +28 -0
  23. data/lib/cucumber/core/gherkin/writer/step.rb +37 -0
  24. data/lib/cucumber/core/gherkin/writer/table.rb +28 -0
  25. data/lib/cucumber/core/gherkin/writer.rb +17 -256
  26. data/lib/cucumber/core/test/action/defined.rb +2 -2
  27. data/lib/cucumber/core/test/action/unskippable.rb +2 -2
  28. data/lib/cucumber/core/test/around_hook.rb +2 -2
  29. data/lib/cucumber/core/test/data_table.rb +2 -2
  30. data/lib/cucumber/core/test/doc_string.rb +3 -3
  31. data/lib/cucumber/core/test/result.rb +22 -24
  32. data/lib/cucumber/core/test/runner.rb +6 -6
  33. data/lib/cucumber/core/test/step.rb +8 -8
  34. metadata +26 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae5673fa67e0a1c50b9fe74c72d62b39a70bdabcfbf39d4bfad7d01330e761dd
4
- data.tar.gz: 762169d03ecf48227ca67b9fd6cdb6937ced41a7a6f44bce713970ad323717ea
3
+ metadata.gz: 1710a14ed278897b31a075938c655efc6614d353ec7ca37102f43460bc454934
4
+ data.tar.gz: bd2fd69c1ddef3e4d41bcc3145495a3eb43b3e19645a3daf6f134debcc5e73e0
5
5
  SHA512:
6
- metadata.gz: 7cd05f0388967c84e03c3085a8b912a72c40db6f857012e79b77d969a23d10f567998ba7b760b92b9d1e042fa31b3dce2fd474546c7209c160c49eba38d8cddd
7
- data.tar.gz: 066153cce7b848259b19f358d26528d269df505fc86d5995490975a8f52d4c98b96e8e7332bc94f6edf4f57d99a72199e800fefc50cfff51b40fe9aeeaaf551e
6
+ metadata.gz: 6c59caed7891d014027f2d83511961cf768066a66f7f033a05dd1f868cb88fc843c276c3645ecf5af5ac020e048a62c3966277672bc3a356ba1f3ea94d0e76c9
7
+ data.tar.gz: 13a00c9ea789204fb36f2a45a71df9073e53f36953e1ef3640cd30c45baae405da85ff583f1d8d77edca34ffd97895bbd1b845cd7a345b7582cc817e2b85c7d6
data/CHANGELOG.md CHANGED
@@ -10,6 +10,15 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [16.1.1] - 2025-12-24
14
+ ### Fixed
15
+ - Added a fix that prevented the `Duration` class from not being able to calculate duration correctly
16
+
17
+ ## [16.1.0] - 2025-12-22
18
+ ### Changed
19
+ - Code re-organised into more sub-files. No user facing changes
20
+ - Further bumped the lower bounds of messages and gherkin several more versions
21
+
13
22
  ## [16.0.0] - 2025-12-16
14
23
  ### Changed
15
24
  - Bumped the lower bounds of messages to v28, gherkin to v33 and tag-expressions to v6
@@ -118,7 +127,9 @@ See upgrading notes for [13.0.0.md](upgrading_notes/13.0.0.md#upgrading-to-cucum
118
127
  ### Changed
119
128
  - Updated `cucumber-gherkin` and `cucumber-messages`
120
129
 
121
- [Unreleased]: https://github.com/cucumber/cucumber-ruby-core/compare/v16.0.0...HEAD
130
+ [Unreleased]: https://github.com/cucumber/cucumber-ruby-core/compare/v16.1.1...HEAD
131
+ [16.1.1]: https://github.com/cucumber/cucumber-ruby-core/compare/v16.1.0...v16.1.1
132
+ [16.1.0]: https://github.com/cucumber/cucumber-ruby-core/compare/v16.0.0...v16.1.0
122
133
  [16.0.0]: https://github.com/cucumber/cucumber-ruby-core/compare/v15.4.0...v16.0.0
123
134
  [15.4.0]: https://github.com/cucumber/cucumber-ruby-core/compare/v15.3.0...v15.4.0
124
135
  [15.3.0]: https://github.com/cucumber/cucumber-ruby-core/compare/v15.2.1...v15.3.0
@@ -3,11 +3,10 @@
3
3
  module Cucumber
4
4
  module Core
5
5
  class Event
6
- # Macro to generate new sub-classes of {Event} with
7
- # attribute readers.
6
+ # Macro to generate new subclasses of {Event} with attribute readers.
8
7
  def self.new(*events)
9
8
  # Use normal constructor for subclasses of Event
10
- return super if ancestors.index(Event) > 0
9
+ return super if ancestors.index(Event).positive?
11
10
 
12
11
  Class.new(Event) do
13
12
  # NB: We need to use metaprogramming here instead of direct variable obtainment
@@ -34,9 +34,9 @@ module Cucumber
34
34
  @event_queue << event
35
35
  end
36
36
 
37
- def method_missing(event_id, *args)
37
+ def method_missing(event_id, *)
38
38
  event_class = event_types.fetch(event_id) { super }
39
- broadcast event_class.new(*args)
39
+ broadcast event_class.new(*)
40
40
  end
41
41
 
42
42
  def respond_to_missing?(event_id, *args)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ class Envelope < Event.new(:envelope)
9
+ attr_reader :envelope
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a gherkin source has been parsed
9
+ class GherkinSourceParsed < Event.new(:gherkin_document)
10
+ # @return [GherkinDocument] the GherkinDocument Ast Node
11
+ attr_reader :gherkin_document
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a Test::Case was created from a Pickle
9
+ class TestCaseCreated < Event.new(:test_case, :pickle)
10
+ # The created test step
11
+ attr_reader :test_case
12
+
13
+ # The source pickle step
14
+ attr_reader :pickle
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a {Test::Case} has finished executing
9
+ class TestCaseFinished < Event.new(:test_case, :result)
10
+ # @return [Test::Case] that was executed
11
+ attr_reader :test_case
12
+
13
+ # @return [Test::Result] the result of running the {Test::Step}
14
+ attr_reader :result
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a {Test::Case} is about to be executed
9
+ class TestCaseStarted < Event.new(:test_case)
10
+ # @return [Test::Case] the test case to be executed
11
+ attr_reader :test_case
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a Test::Step was created from a PickleStep
9
+ class TestStepCreated < Event.new(:test_step, :pickle_step)
10
+ # The created test step
11
+ attr_reader :test_step
12
+
13
+ # The source pickle step
14
+ attr_reader :pickle_step
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a {Test::Step} has finished executing
9
+ class TestStepFinished < Event.new(:test_step, :result)
10
+ # @return [Test::Step] the test step that was executed
11
+ attr_reader :test_step
12
+
13
+ # @return [Test::Result] the result of running the {Test::Step}
14
+ attr_reader :result
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../event'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Events
8
+ # Signals that a {Test::Step} is about to be executed
9
+ class TestStepStarted < Event.new(:test_step)
10
+ # @return [Test::Step] the test step to be executed
11
+ attr_reader :test_step
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,88 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/core/event'
3
+ require_relative 'events/envelope'
4
+ require_relative 'events/gherkin_source_parsed'
5
+ require_relative 'events/test_case_created'
6
+ require_relative 'events/test_case_started'
7
+ require_relative 'events/test_case_finished'
8
+ require_relative 'events/test_step_created'
9
+ require_relative 'events/test_step_started'
10
+ require_relative 'events/test_step_finished'
4
11
 
5
12
  module Cucumber
6
13
  module Core
7
14
  module Events
8
- class Envelope < Event.new(:envelope)
9
- attr_reader :envelope
10
- end
11
-
12
- # Signals that a gherkin source has been parsed
13
- class GherkinSourceParsed < Event.new(:gherkin_document)
14
- # @return [GherkinDocument] the GherkinDocument Ast Node
15
- attr_reader :gherkin_document
16
- end
17
-
18
- # Signals that a Test::Step was created from a PickleStep
19
- class TestStepCreated < Event.new(:test_step, :pickle_step)
20
- # The created test step
21
- attr_reader :test_step
22
-
23
- # The source pickle step
24
- attr_reader :pickle_step
25
- end
26
-
27
- # Signals that a Test::Case was created from a Pickle
28
- class TestCaseCreated < Event.new(:test_case, :pickle)
29
- # The created test step
30
- attr_reader :test_case
31
-
32
- # The source pickle step
33
- attr_reader :pickle
34
- end
35
-
36
- # Signals that a {Test::Case} is about to be executed
37
- class TestCaseStarted < Event.new(:test_case)
38
- # @return [Test::Case] the test case to be executed
39
- attr_reader :test_case
40
- end
41
-
42
- # Signals that a {Test::Step} is about to be executed
43
- class TestStepStarted < Event.new(:test_step)
44
- # @return [Test::Step] the test step to be executed
45
- attr_reader :test_step
46
- end
47
-
48
- # Signals that a {Test::Step} has finished executing
49
- class TestStepFinished < Event.new(:test_step, :result)
50
- # @return [Test::Step] the test step that was executed
51
- attr_reader :test_step
52
-
53
- # @return [Test::Result] the result of running the {Test::Step}
54
- attr_reader :result
55
- end
56
-
57
- # Signals that a {Test::Case} has finished executing
58
- class TestCaseFinished < Event.new(:test_case, :result)
59
- # @return [Test::Case] that was executed
60
- attr_reader :test_case
61
-
62
- # @return [Test::Result] the result of running the {Test::Step}
63
- attr_reader :result
64
- end
65
-
66
- # The registry contains all the events registered in the core,
67
- # that will be used by the {EventBus} by default.
15
+ # The registry contains all the events registered in the core, that will be used by the {EventBus} by default.
68
16
  def self.registry
69
17
  build_registry(
70
18
  Envelope,
71
19
  GherkinSourceParsed,
72
- TestStepCreated,
73
20
  TestCaseCreated,
74
21
  TestCaseStarted,
22
+ TestCaseFinished,
23
+ TestStepCreated,
75
24
  TestStepStarted,
76
- TestStepFinished,
77
- TestCaseFinished
25
+ TestStepFinished
78
26
  )
79
27
  end
80
28
 
81
- # Build an event registry to be passed to the {EventBus}
82
- # constructor from a list of types.
83
- #
84
- # Each type must respond to `event_id` so that it can be added
85
- # to the registry hash.
29
+ # Build an event registry to be passed to the {EventBus} constructor from a list of types.
30
+ # Each type must respond to `event_id` so that it can be added to the registry hash
86
31
  #
87
32
  # @return [Hash{Symbol => Class}]
88
33
  def self.build_registry(*types)
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class Background
10
+ include HasElements
11
+ include HasOptionsInitializer
12
+ include HasDescription
13
+ include Indentation.level 2
14
+
15
+ default_keyword 'Background'
16
+
17
+ elements :step
18
+
19
+ private
20
+
21
+ def statements
22
+ prepare_statements(
23
+ comments_statement,
24
+ tag_statement,
25
+ name_statement,
26
+ description_statement
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class DocString
10
+ include Indentation.level(6)
11
+
12
+ attr_reader :strings, :content_type
13
+ private :strings, :content_type
14
+
15
+ def initialize(string, content_type)
16
+ @strings = string.split("\n").map(&:strip)
17
+ @content_type = content_type
18
+ end
19
+
20
+ def build(source)
21
+ source + statements
22
+ end
23
+
24
+ private
25
+
26
+ def statements
27
+ prepare_statements doc_string_statement
28
+ end
29
+
30
+ def doc_string_statement
31
+ [
32
+ %("""#{content_type}),
33
+ strings,
34
+ '"""'
35
+ ]
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+ require_relative 'scenario'
5
+
6
+ module Cucumber
7
+ module Core
8
+ module Gherkin
9
+ module Writer
10
+ class Example < Scenario
11
+ include Indentation.level 4
12
+
13
+ default_keyword 'Example'
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class Examples
10
+ NEW_LINE = ''
11
+
12
+ include HasOptionsInitializer
13
+ include HasRows
14
+ include HasDescription
15
+ include Indentation.level(4)
16
+
17
+ default_keyword 'Examples'
18
+
19
+ def build(source)
20
+ source + statements
21
+ end
22
+
23
+ private
24
+
25
+ def statements
26
+ prepare_statements(
27
+ NEW_LINE,
28
+ comments_statement,
29
+ tag_statement,
30
+ name_statement,
31
+ description_statement,
32
+ row_statements(2)
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class Feature
10
+ NEW_LINE = ''
11
+
12
+ include HasElements
13
+ include HasOptionsInitializer
14
+ include HasDescription
15
+ include Indentation.level(0)
16
+
17
+ default_keyword 'Feature'
18
+
19
+ elements :background, :rule, :scenario, :scenario_outline
20
+
21
+ def build(source = [])
22
+ elements.inject(source + statements) { |acc, el| el.build(acc) + [NEW_LINE] }
23
+ end
24
+
25
+ private
26
+
27
+ def language
28
+ options[:language]
29
+ end
30
+
31
+ def statements
32
+ prepare_statements(
33
+ language_statement,
34
+ comments_statement,
35
+ tag_statement,
36
+ name_statement,
37
+ description_statement,
38
+ NEW_LINE
39
+ )
40
+ end
41
+
42
+ def language_statement
43
+ "# language: #{language}" if language
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../document'
4
+ require_relative 'feature'
5
+
6
+ module Cucumber
7
+ module Core
8
+ module Gherkin
9
+ module Writer
10
+ class Gherkin
11
+ def initialize(uri, &source)
12
+ @uri = uri
13
+ @source = source
14
+ end
15
+
16
+ def comment(line)
17
+ comment_lines << "# #{line}"
18
+ end
19
+
20
+ def comment_lines
21
+ @comment_lines ||= []
22
+ end
23
+
24
+ def feature(*args, &source)
25
+ @feature = Feature.new(comment_lines, *args).tap do |builder|
26
+ builder.instance_exec(&source) if source
27
+ end
28
+ self
29
+ end
30
+
31
+ def build
32
+ instance_exec(&@source)
33
+ Document.new(@uri, @feature.build.join("\n"))
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class Rule
10
+ NEW_LINE = ''
11
+
12
+ include HasElements
13
+ include HasOptionsInitializer
14
+ include HasDescription
15
+ include Indentation.level 2
16
+
17
+ default_keyword 'Rule'
18
+
19
+ elements :example, :scenario
20
+
21
+ private
22
+
23
+ def statements
24
+ prepare_statements(
25
+ comments_statement,
26
+ name_statement,
27
+ description_statement,
28
+ NEW_LINE
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class Scenario
10
+ include HasElements
11
+ include HasOptionsInitializer
12
+ include HasDescription
13
+ include Indentation.level 2
14
+
15
+ default_keyword 'Scenario'
16
+
17
+ elements :step
18
+
19
+ private
20
+
21
+ def statements
22
+ prepare_statements(
23
+ comments_statement,
24
+ tag_statement,
25
+ name_statement,
26
+ description_statement
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class ScenarioOutline
10
+ include HasElements
11
+ include HasOptionsInitializer
12
+ include HasDescription
13
+ include Indentation.level 2
14
+
15
+ default_keyword 'Scenario Outline'
16
+
17
+ elements :step, :examples
18
+
19
+ private
20
+
21
+ def statements
22
+ prepare_statements comments_statement, tag_statement, name_statement, description_statement
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ require_relative 'doc_string'
6
+
7
+ module Cucumber
8
+ module Core
9
+ module Gherkin
10
+ module Writer
11
+ class Step
12
+ include HasElements
13
+ include HasOptionsInitializer
14
+ include Indentation.level 4
15
+
16
+ default_keyword 'Given'
17
+
18
+ elements :table
19
+
20
+ def doc_string(string, content_type = '')
21
+ elements << DocString.new(string, content_type)
22
+ end
23
+
24
+ private
25
+
26
+ def statements
27
+ prepare_statements comments_statement, name_statement
28
+ end
29
+
30
+ def name_statement
31
+ "#{keyword} #{name}"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Gherkin
8
+ module Writer
9
+ class Table
10
+ include Indentation.level(6)
11
+ include HasRows
12
+
13
+ def initialize(*); end
14
+
15
+ def build(source)
16
+ source + statements
17
+ end
18
+
19
+ private
20
+
21
+ def statements
22
+ row_statements
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,266 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/core/gherkin/writer/helpers'
4
- require 'cucumber/core/gherkin/document'
3
+ require_relative 'document'
4
+
5
+ require_relative 'writer/helpers'
6
+
7
+ require_relative 'writer/gherkin'
8
+ require_relative 'writer/feature'
9
+ require_relative 'writer/background'
10
+ require_relative 'writer/rule'
11
+ require_relative 'writer/scenario'
12
+ require_relative 'writer/example'
13
+ require_relative 'writer/scenario_outline'
14
+ require_relative 'writer/step'
15
+ require_relative 'writer/table'
16
+ require_relative 'writer/doc_string'
17
+ require_relative 'writer/examples'
5
18
 
6
19
  module Cucumber
7
20
  module Core
8
21
  module Gherkin
9
22
  module Writer
10
- NEW_LINE = ''
11
- def gherkin(uri = nil, &source)
12
- uri ||= 'features/test.feature'
13
- builder = Gherkin.new(uri, &source)
14
- builder.build
15
- end
16
-
17
- class Gherkin
18
- def initialize(uri, &source)
19
- @uri = uri
20
- @source = source
21
- end
22
-
23
- def comment(line)
24
- comment_lines << "# #{line}"
25
- end
26
-
27
- def comment_lines
28
- @comment_lines ||= []
29
- end
30
-
31
- def feature(*args, &source)
32
- @feature = Feature.new(comment_lines, *args).tap do |builder|
33
- builder.instance_exec(&source) if source
34
- end
35
- self
36
- end
37
-
38
- def build
39
- instance_exec(&@source)
40
- Document.new(@uri, @feature.build.join("\n"))
41
- end
42
- end
43
-
44
- class Feature
45
- include HasElements
46
- include HasOptionsInitializer
47
- include HasDescription
48
- include Indentation.level(0)
49
-
50
- default_keyword 'Feature'
51
-
52
- elements :background, :rule, :scenario, :scenario_outline
53
-
54
- def build(source = [])
55
- elements.inject(source + statements) { |acc, el| el.build(acc) + [NEW_LINE] }
56
- end
57
-
58
- private
59
-
60
- def language
61
- options[:language]
62
- end
63
-
64
- def statements
65
- prepare_statements(
66
- language_statement,
67
- comments_statement,
68
- tag_statement,
69
- name_statement,
70
- description_statement,
71
- NEW_LINE
72
- )
73
- end
74
-
75
- def language_statement
76
- "# language: #{language}" if language
77
- end
78
- end
79
-
80
- class Background
81
- include HasElements
82
- include HasOptionsInitializer
83
- include HasDescription
84
- include Indentation.level 2
85
-
86
- default_keyword 'Background'
87
-
88
- elements :step
89
-
90
- private
91
-
92
- def statements
93
- prepare_statements(
94
- comments_statement,
95
- tag_statement,
96
- name_statement,
97
- description_statement
98
- )
99
- end
100
- end
101
-
102
- class Rule
103
- include HasElements
104
- include HasOptionsInitializer
105
- include HasDescription
106
- include Indentation.level 2
107
-
108
- default_keyword 'Rule'
109
-
110
- elements :example, :scenario
111
-
112
- private
113
-
114
- def statements
115
- prepare_statements(
116
- comments_statement,
117
- name_statement,
118
- description_statement,
119
- NEW_LINE
120
- )
121
- end
122
- end
123
-
124
- class Scenario
125
- include HasElements
126
- include HasOptionsInitializer
127
- include HasDescription
128
- include Indentation.level 2
129
-
130
- default_keyword 'Scenario'
131
-
132
- elements :step
133
-
134
- private
135
-
136
- def statements
137
- prepare_statements(
138
- comments_statement,
139
- tag_statement,
140
- name_statement,
141
- description_statement
142
- )
143
- end
144
- end
145
-
146
- class Example < Scenario
147
- include Indentation.level 4
148
-
149
- default_keyword 'Example'
150
- end
151
-
152
- class ScenarioOutline
153
- include HasElements
154
- include HasOptionsInitializer
155
- include HasDescription
156
- include Indentation.level 2
157
-
158
- default_keyword 'Scenario Outline'
159
-
160
- elements :step, :examples
161
-
162
- private
163
-
164
- def statements
165
- prepare_statements comments_statement, tag_statement, name_statement, description_statement
166
- end
167
- end
168
-
169
- class Step
170
- include HasElements
171
- include HasOptionsInitializer
172
- include Indentation.level 4
173
-
174
- default_keyword 'Given'
175
-
176
- elements :table
177
-
178
- def doc_string(string, content_type = '')
179
- elements << DocString.new(string, content_type)
180
- end
181
-
182
- private
183
-
184
- def statements
185
- prepare_statements comments_statement, name_statement
186
- end
187
-
188
- def name_statement
189
- "#{keyword} #{name}"
190
- end
191
- end
192
-
193
- class Table
194
- include Indentation.level(6)
195
- include HasRows
196
-
197
- def initialize(*); end
198
-
199
- def build(source)
200
- source + statements
201
- end
202
-
203
- private
204
-
205
- def statements
206
- row_statements
207
- end
208
- end
209
-
210
- class DocString
211
- include Indentation.level(6)
212
-
213
- attr_reader :strings, :content_type
214
- private :strings, :content_type
215
-
216
- def initialize(string, content_type)
217
- @strings = string.split("\n").map(&:strip)
218
- @content_type = content_type
219
- end
220
-
221
- def build(source)
222
- source + statements
223
- end
224
-
225
- private
226
-
227
- def statements
228
- prepare_statements doc_string_statement
229
- end
230
-
231
- def doc_string_statement
232
- [
233
- %("""#{content_type}),
234
- strings,
235
- '"""'
236
- ]
237
- end
238
- end
239
-
240
- class Examples
241
- include HasOptionsInitializer
242
- include HasRows
243
- include HasDescription
244
- include Indentation.level(4)
245
-
246
- default_keyword 'Examples'
247
-
248
- def build(source)
249
- source + statements
250
- end
251
-
252
- private
253
-
254
- def statements
255
- prepare_statements(
256
- NEW_LINE,
257
- comments_statement,
258
- tag_statement,
259
- name_statement,
260
- description_statement,
261
- row_statements(2)
262
- )
263
- end
23
+ def gherkin(uri = 'features/test.feature', &)
24
+ Gherkin.new(uri, &).build
264
25
  end
265
26
  end
266
27
  end
@@ -19,9 +19,9 @@ module Cucumber
19
19
  @timer = Timer.new
20
20
  end
21
21
 
22
- def execute(*args)
22
+ def execute(*)
23
23
  @timer.start
24
- @block.call(*args)
24
+ @block.call(*)
25
25
  passed
26
26
  rescue Result::Raisable => e
27
27
  e.with_duration(@timer.duration)
@@ -8,8 +8,8 @@ module Cucumber
8
8
  module Test
9
9
  module Action
10
10
  class Unskippable < Defined
11
- def skip(*args)
12
- execute(*args)
11
+ def skip(*)
12
+ execute(*)
13
13
  end
14
14
  end
15
15
  end
@@ -9,8 +9,8 @@ module Cucumber
9
9
  @timer = Timer.new
10
10
  end
11
11
 
12
- def describe_to(visitor, *args, &continue)
13
- visitor.around_hook(self, *args, &continue)
12
+ def describe_to(visitor, *, &)
13
+ visitor.around_hook(self, *, &)
14
14
  end
15
15
 
16
16
  def hook?
@@ -35,8 +35,8 @@ module Cucumber
35
35
  end
36
36
  attr_reader :raw
37
37
 
38
- def describe_to(visitor, *args)
39
- visitor.data_table(self, *args)
38
+ def describe_to(visitor, *)
39
+ visitor.data_table(self, *)
40
40
  end
41
41
 
42
42
  def to_step_definition_arg
@@ -26,11 +26,11 @@ module Cucumber
26
26
  def initialize(content, content_type)
27
27
  @content = content
28
28
  @content_type = content_type
29
- super @content
29
+ super(@content)
30
30
  end
31
31
 
32
- def describe_to(visitor, *args)
33
- visitor.doc_string(self, *args)
32
+ def describe_to(visitor, *)
33
+ visitor.doc_string(self, *)
34
34
  end
35
35
 
36
36
  def data_table?
@@ -67,9 +67,9 @@ module Cucumber
67
67
  @duration = duration
68
68
  end
69
69
 
70
- def describe_to(visitor, *args)
71
- visitor.passed(*args)
72
- visitor.duration(duration, *args)
70
+ def describe_to(visitor, *)
71
+ visitor.passed(*)
72
+ visitor.duration(duration, *)
73
73
  self
74
74
  end
75
75
 
@@ -114,10 +114,10 @@ module Cucumber
114
114
  @exception = exception
115
115
  end
116
116
 
117
- def describe_to(visitor, *args)
118
- visitor.failed(*args)
119
- visitor.duration(duration, *args)
120
- visitor.exception(exception, *args) if exception
117
+ def describe_to(visitor, *)
118
+ visitor.failed(*)
119
+ visitor.duration(duration, *)
120
+ visitor.exception(exception, *) if exception
121
121
  self
122
122
  end
123
123
 
@@ -211,9 +211,9 @@ module Cucumber
211
211
  !strict
212
212
  end
213
213
 
214
- def describe_to(visitor, *args)
215
- visitor.undefined(*args)
216
- visitor.duration(duration, *args)
214
+ def describe_to(visitor, *)
215
+ visitor.undefined(*)
216
+ visitor.duration(duration, *)
217
217
  self
218
218
  end
219
219
 
@@ -236,9 +236,9 @@ module Cucumber
236
236
  true
237
237
  end
238
238
 
239
- def describe_to(visitor, *args)
240
- visitor.skipped(*args)
241
- visitor.duration(duration, *args)
239
+ def describe_to(visitor, *)
240
+ visitor.skipped(*)
241
+ visitor.duration(duration, *)
242
242
  self
243
243
  end
244
244
 
@@ -261,9 +261,9 @@ module Cucumber
261
261
  !strict
262
262
  end
263
263
 
264
- def describe_to(visitor, *args)
265
- visitor.pending(self, *args)
266
- visitor.duration(duration, *args)
264
+ def describe_to(visitor, *)
265
+ visitor.pending(self, *)
266
+ visitor.duration(duration, *)
267
267
  self
268
268
  end
269
269
 
@@ -409,19 +409,17 @@ module Cucumber
409
409
 
410
410
  def to_message_duration
411
411
  duration_hash = seconds_to_duration(nanoseconds.to_f / NANOSECONDS_PER_SECOND)
412
- duration_hash.transform_keys! do |key|
413
- key.to_sym
414
- rescue Error
415
- return key
416
- end
412
+ Cucumber::Messages::Duration.new(seconds: duration_hash[:seconds], nanos: duration_hash[:nanos])
413
+ end
417
414
 
418
- Cucumber::Messages::Duration.from_h(duration_hash)
415
+ def seconds_to_duration(seconds_float)
416
+ seconds, second_modulus = seconds_float.divmod(1)
417
+ nanos = second_modulus * NANOSECONDS_PER_SECOND
418
+ { seconds: seconds, nanos: nanos.to_i }
419
419
  end
420
420
  end
421
421
 
422
422
  class UnknownDuration
423
- include Cucumber::Messages::Helpers::TimeConversion
424
-
425
423
  def tap
426
424
  self
427
425
  end
@@ -33,8 +33,8 @@ module Cucumber
33
33
  self
34
34
  end
35
35
 
36
- def around_hook(hook, &continue)
37
- result = running_test_case.execute(hook, &continue)
36
+ def around_hook(hook, &)
37
+ result = running_test_case.execute(hook, &)
38
38
  event_bus.test_step_finished running_test_step, result if running_test_step
39
39
  @running_test_step = nil
40
40
  self
@@ -50,8 +50,8 @@ module Cucumber
50
50
  @status = Status::Unknown.new(Result::Unknown.new)
51
51
  end
52
52
 
53
- def execute(test_step, &continue)
54
- status.execute(test_step, self, &continue)
53
+ def execute(test_step, &)
54
+ status.execute(test_step, self, &)
55
55
  end
56
56
 
57
57
  def result
@@ -103,8 +103,8 @@ module Cucumber
103
103
  @step_result = step_result
104
104
  end
105
105
 
106
- def execute(test_step, monitor, &continue)
107
- result = test_step.execute(monitor.result, &continue)
106
+ def execute(test_step, monitor, &)
107
+ result = test_step.execute(monitor.result, &)
108
108
  result = result.with_message(%(Undefined step: "#{test_step.text}")) if result.undefined?
109
109
  result = result.with_appended_backtrace(test_step) unless test_step.hook?
110
110
  result.describe_to(monitor, result)
@@ -20,24 +20,24 @@ module Cucumber
20
20
  @action = action
21
21
  end
22
22
 
23
- def describe_to(visitor, *args)
24
- visitor.test_step(self, *args)
23
+ def describe_to(visitor, *)
24
+ visitor.test_step(self, *)
25
25
  end
26
26
 
27
27
  def hook?
28
28
  false
29
29
  end
30
30
 
31
- def skip(*args)
32
- @action.skip(*args)
31
+ def skip(*)
32
+ @action.skip(*)
33
33
  end
34
34
 
35
- def execute(*args)
36
- @action.execute(*args)
35
+ def execute(*)
36
+ @action.execute(*)
37
37
  end
38
38
 
39
- def with_action(action_location = nil, &block)
40
- self.class.new(id, text, location, multiline_arg, Test::Action::Defined.new(action_location, &block))
39
+ def with_action(action_location = nil, &)
40
+ self.class.new(id, text, location, multiline_arg, Test::Action::Defined.new(action_location, &))
41
41
  end
42
42
 
43
43
  def backtrace_line
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 16.0.0
4
+ version: 16.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aslak Hellesøy
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2025-12-16 00:00:00.000000000 Z
15
+ date: 2025-12-24 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: cucumber-gherkin
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">"
22
22
  - !ruby/object:Gem::Version
23
- version: '33'
23
+ version: '36'
24
24
  - - "<"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '40'
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">"
32
32
  - !ruby/object:Gem::Version
33
- version: '33'
33
+ version: '36'
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
36
  version: '40'
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - ">"
42
42
  - !ruby/object:Gem::Version
43
- version: '28'
43
+ version: '31'
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '33'
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ">"
52
52
  - !ruby/object:Gem::Version
53
- version: '28'
53
+ version: '31'
54
54
  - - "<"
55
55
  - !ruby/object:Gem::Version
56
56
  version: '33'
@@ -172,11 +172,30 @@ files:
172
172
  - lib/cucumber/core/event.rb
173
173
  - lib/cucumber/core/event_bus.rb
174
174
  - lib/cucumber/core/events.rb
175
+ - lib/cucumber/core/events/envelope.rb
176
+ - lib/cucumber/core/events/gherkin_source_parsed.rb
177
+ - lib/cucumber/core/events/test_case_created.rb
178
+ - lib/cucumber/core/events/test_case_finished.rb
179
+ - lib/cucumber/core/events/test_case_started.rb
180
+ - lib/cucumber/core/events/test_step_created.rb
181
+ - lib/cucumber/core/events/test_step_finished.rb
182
+ - lib/cucumber/core/events/test_step_started.rb
175
183
  - lib/cucumber/core/filter.rb
176
184
  - lib/cucumber/core/gherkin/document.rb
177
185
  - lib/cucumber/core/gherkin/parser.rb
178
186
  - lib/cucumber/core/gherkin/writer.rb
187
+ - lib/cucumber/core/gherkin/writer/background.rb
188
+ - lib/cucumber/core/gherkin/writer/doc_string.rb
189
+ - lib/cucumber/core/gherkin/writer/example.rb
190
+ - lib/cucumber/core/gherkin/writer/examples.rb
191
+ - lib/cucumber/core/gherkin/writer/feature.rb
192
+ - lib/cucumber/core/gherkin/writer/gherkin.rb
179
193
  - lib/cucumber/core/gherkin/writer/helpers.rb
194
+ - lib/cucumber/core/gherkin/writer/rule.rb
195
+ - lib/cucumber/core/gherkin/writer/scenario.rb
196
+ - lib/cucumber/core/gherkin/writer/scenario_outline.rb
197
+ - lib/cucumber/core/gherkin/writer/step.rb
198
+ - lib/cucumber/core/gherkin/writer/table.rb
180
199
  - lib/cucumber/core/platform.rb
181
200
  - lib/cucumber/core/report/summary.rb
182
201
  - lib/cucumber/core/test/action.rb
@@ -228,5 +247,5 @@ requirements: []
228
247
  rubygems_version: 3.4.20
229
248
  signing_key:
230
249
  specification_version: 4
231
- summary: cucumber-core-16.0.0
250
+ summary: cucumber-core-16.1.1
232
251
  test_files: []