Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2026-06-02 19:13:42 UTC using RuboCop version 1.87.0.
# on 2026-07-13 08:18:00 UTC using RuboCop version 1.88.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand All @@ -11,12 +11,26 @@
# TODO: [LH] v16 (Gherkin/Message bump) -> 61 files inspected, 272 offenses detected, 60 offenses autocorrectable
# TODO: [LH] v16.2 (Generic refactors / new events) -> 79 files inspected, 222 offenses detected, 10 offenses autocorrectable
# TODO: [LH] v17 prep -> 92 files inspected, 212 offenses detected, 10 offenses autocorrectable
# TODO: [LH] v18 prep -> 111 files inspected, 227 offenses detected, 16 offenses autocorrectable

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
Layout/ExtraSpacing:
Exclude:
- 'spec/cucumber/core/test/result/summary_spec.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Layout/LeadingEmptyLines:
Exclude:
- 'spec/cucumber/core/test/result/skipped_spec.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Layout/SpaceAroundMethodCallOperator:
Exclude:
- 'spec/cucumber/core/test/result_spec.rb'
- 'spec/cucumber/core/test/result/summary_spec.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Expand Down Expand Up @@ -60,7 +74,13 @@ RSpec/ExampleLength:
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Exclude:
- 'spec/cucumber/core/test/result_spec.rb'
- 'spec/cucumber/core/test/result/duration_spec.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
RSpec/LeadingSubject:
Exclude:
- 'spec/cucumber/core/test/result/raisable_spec.rb'

# Offense count: 23
RSpec/MissingExampleGroupArgument:
Expand All @@ -73,11 +93,11 @@ RSpec/MissingExampleGroupArgument:
- 'spec/cucumber/core/test/locations_filter_spec.rb'
- 'spec/cucumber/core_spec.rb'

# Offense count: 66
# Offense count: 64
RSpec/MultipleExpectations:
Max: 5

# Offense count: 53
# Offense count: 59
# Configuration parameters: AllowSubject.
RSpec/MultipleMemoizedHelpers:
Max: 11
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
### Breaking Change
- Structure of Gherkin writer helpers have been changed. Now one helper per file, and all helpers are still available by requiring `gherkin/writer/helpers`.
See upgrading notes for [18.0.0.md](upgrading_notes/18.0.0.md#upgrading-to-cucumber-core-1800), for full changes
- Flaky results are now treated as a passing state. See upgrading notes for [18.0.0.md](upgrading_notes/18.0.0.md#upgrading-to-cucumber-core-1800), for full changes

### Changed
- Tidied up a bunch of mostly internal test code to be more rubocop compliant
Expand Down
2 changes: 1 addition & 1 deletion lib/cucumber/core/test/result/flaky.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Result
# retry, therefore only the class method self.ok? is needed.
class Flaky
def self.ok?
false
true
end
end
end
Expand Down
60 changes: 60 additions & 0 deletions spec/cucumber/core/test/result/ambiguous_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

require 'cucumber/core/test/result'
require 'support/duration_matcher'

describe Cucumber::Core::Test::Result::Ambiguous do
subject(:result) { described_class.new }

let(:visitor) { double }
let(:args) { double }

describe '.ok?' do
it { expect(described_class).not_to be_ok }
end

describe '#describe_to' do
it 'describes itself to a visitor' do
expect(visitor).to receive(:ambiguous).with(args)
expect(visitor).to receive(:duration).with(an_unknown_duration, args)

result.describe_to(visitor, args)
end
end

describe '#to_message' do
it 'is a `TestStepResult` message' do
expect(result.to_message).to be_a Cucumber::Messages::TestStepResult
end

it 'has a status' do
expect(result.to_message.status).to eq(Cucumber::Messages::TestStepResultStatus::AMBIGUOUS)
end

it 'has a duration' do
expect(result.to_message.duration).to have_attributes(seconds: 0, nanos: 0)
end
end

it { expect(result.to_sym).to eq(:ambiguous) }
it { expect(result.to_s).to eq('A') }

context 'with the BooleanMethods helper' do
describe '#ok?' do
it 'calls the class method' do
expect(described_class).to receive(:ok?)

result.ok?
end
end

it { expect(result).not_to be_failed }
it { expect(result).to be_ambiguous }
it { expect(result).not_to be_flaky }
it { expect(result).not_to be_undefined }
it { expect(result).not_to be_pending }
it { expect(result).not_to be_skipped }
it { expect(result).not_to be_passed }
it { expect(result).not_to be_unknown }
end
end
36 changes: 36 additions & 0 deletions spec/cucumber/core/test/result/duration_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require 'cucumber/core/test/result'
require 'support/duration_matcher'

describe Cucumber::Core::Test::Result::Duration do
subject(:duration) { described_class.new(10) }

describe '#nanoseconds' do
before { duration.tap { |duration| @duration = duration.nanoseconds } }

it '#nanoseconds can be accessed in #tap' do
expect(@duration).to eq(10)
end
end

describe '#to_message_duration' do
subject(:message_duration) { duration.to_message_duration }

it 'returns the correct message type' do
expect(message_duration).to be_a(Cucumber::Messages::Duration)
end

it 'returns a message with the correct seconds and nanos' do
expect(message_duration).to have_attributes(seconds: 0, nanos: 10)
end
end

describe '#seconds_to_duration' do
subject(:message_duration) { duration.seconds_to_duration(1.234) }

it 'returns a hash with the correct seconds and nanos' do
expect(message_duration).to eq({ seconds: 1, nanos: 234_000_000 })
end
end
end
99 changes: 99 additions & 0 deletions spec/cucumber/core/test/result/failed_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# frozen_string_literal: true

require 'cucumber/core/test/result'
require 'support/duration_matcher'

describe Cucumber::Core::Test::Result::Failed do
subject(:result) { described_class.new(duration, exception) }

let(:duration) { Cucumber::Core::Test::Result::Duration.new(1 * 1_000 * 1_000) }
let(:exception) { StandardError.new('error message') }
let(:visitor) { double }
let(:args) { double }
let(:filter_class) { double }
let(:filter) { double }
let(:filtered_exception) { double }

before do
allow(visitor).to receive(:failed)
allow(visitor).to receive(:duration)
allow(visitor).to receive(:exception)
end

it 'does nothing if step has no backtrace line' do
result.exception.set_backtrace('exception backtrace')
step = 'does not respond_to?(:backtrace_line)'

expect(result.with_appended_backtrace(step).exception.backtrace).to eq(['exception backtrace'])
end

it 'appends the backtrace line of the step' do
result.exception.set_backtrace('exception backtrace')
step = double
allow(step).to receive(:backtrace_line).and_return('step_line')

expect(result.with_appended_backtrace(step).exception.backtrace).to eq(['exception backtrace', 'step_line'])
end

it 'applies filters to the exception' do
# Permit an exception to be filtered and not excluded
allow(filter_class).to receive(:new).with(result.exception).and_return(filter)
allow(filter).to receive(:exception).and_return(filtered_exception)

expect(result.with_filtered_backtrace(filter_class).exception).to eq(filtered_exception)
end

describe '.ok?' do
it { expect(described_class).not_to be_ok }
end

describe '#describe_to' do
it 'is described as a failing test' do
expect(visitor).to receive(:failed).with(args)

result.describe_to(visitor, args)
end

it 'contains an exception message' do
expect(visitor).to receive(:exception).with(exception, args)

result.describe_to(visitor, args)
end
end

describe '#to_message' do
it 'is a `TestStepResult` message' do
expect(result.to_message).to be_a Cucumber::Messages::TestStepResult
end

it 'has a status' do
expect(result.to_message.status).to eq(Cucumber::Messages::TestStepResultStatus::FAILED)
end

it 'has a duration' do
expect(result.to_message.duration).to have_attributes(seconds: 0, nanos: 1_000_000)
end
end

it { expect(result.to_sym).to eq(:failed) }
it { expect(result.to_s).to eq('✗') }

context 'with the BooleanMethods helper' do
describe '#ok?' do
it 'calls the class method' do
expect(described_class).to receive(:ok?)

result.ok?
end
end

it { expect(result).to be_failed }
it { expect(result).not_to be_ambiguous }
it { expect(result).not_to be_flaky }
it { expect(result).not_to be_undefined }
it { expect(result).not_to be_pending }
it { expect(result).not_to be_skipped }
it { expect(result).not_to be_passed }
it { expect(result).not_to be_unknown }
end
end
12 changes: 12 additions & 0 deletions spec/cucumber/core/test/result/flaky_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'cucumber/core/test/result'
require 'support/duration_matcher'

describe Cucumber::Core::Test::Result::Flaky do
subject(:result) { described_class.new }

describe '.ok?' do
it { expect(described_class).to be_ok }
end
end
73 changes: 73 additions & 0 deletions spec/cucumber/core/test/result/passed_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

require 'cucumber/core/test/result'
require 'support/duration_matcher'

describe Cucumber::Core::Test::Result::Passed do
subject(:result) { described_class.new(duration) }

let(:duration) { Cucumber::Core::Test::Result::Duration.new(1 * 1_000 * 1_000) }
let(:visitor) { double }
let(:args) { double }

before do
allow(visitor).to receive(:duration)
allow(visitor).to receive(:passed)
end

it 'does nothing when appending the backtrace' do
expect(result.with_appended_backtrace(double)).to eq(result)
end

it 'does nothing when filtering the backtrace' do
expect(result.with_filtered_backtrace(double)).to eq(result)
end

describe '.ok?' do
it { expect(described_class).to be_ok }
end

describe '#describe_to' do
it 'is described as a passing test' do
expect(visitor).to receive(:passed).with(args)

result.describe_to(visitor, args)
end
end

describe '#to_message' do
it 'is a `TestStepResult` message' do
expect(result.to_message).to be_a Cucumber::Messages::TestStepResult
end

it 'has a status' do
expect(result.to_message.status).to eq(Cucumber::Messages::TestStepResultStatus::PASSED)
end

it 'has a duration' do
expect(result.to_message.duration).to have_attributes(seconds: 0, nanos: 1_000_000)
end
end

it { expect(result.to_sym).to eq(:passed) }
it { expect(result.to_s).to eq('✓') }

context 'with the BooleanMethods helper' do
describe '#ok?' do
it 'calls the class method' do
expect(described_class).to receive(:ok?)

result.ok?
end
end

it { expect(result).not_to be_failed }
it { expect(result).not_to be_ambiguous }
it { expect(result).not_to be_flaky }
it { expect(result).not_to be_undefined }
it { expect(result).not_to be_pending }
it { expect(result).not_to be_skipped }
it { expect(result).to be_passed }
it { expect(result).not_to be_unknown }
end
end
Loading
Loading