From 51ac33d3bc389443674a0b3d7c4f3de10cdd32a7 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Tue, 17 Mar 2026 23:07:48 +0000 Subject: [PATCH 1/3] Regen TODO file and use later rubocop versions --- .rubocop_todo.yml | 57 +++++++++++++++++++++++++++-------------------- cucumber.gemspec | 4 ++-- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 7ad63ea77..4f6db6d91 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,18 +1,16 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-12-15 17:20:38 UTC using RuboCop version 1.71.2. +# on 2026-03-17 23:06:46 UTC using RuboCop version 1.85.1. # 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 # versions of RuboCop, may require this file to be generated again. -# TODO - [LH] -> Feb '24 - 370 files inspected, 635 offenses detected, 166 offenses autocorrectable -# TODO - [LH] -> Jul '24 - 370 files inspected, 637 offenses detected, 97 offenses autocorrectable -# TODO - [LH] -> Jul '24 - 369 files inspected, 661 offenses detected, 98 offenses autocorrectable # TODO - [LH] -> Jan '25 (Updated deps and v10 prep) - 369 files inspected, 704 offenses detected, 112 offenses autocorrectable # TODO - [LH] -> Mar '25 (v10 prep) - 370 files inspected, 721 offenses detected, 116 offenses autocorrectable # TODO - [LH] -> Dec '25 - 375 files inspected, 713 offenses detected, 109 offenses autocorrectable -# TODO - [LH] -> Dec '26 (query prep) - 378 files inspected, 729 offenses detected, 109 offenses autocorrectable +# TODO - [LH] -> Dec '25 (query prep) - 378 files inspected, 729 offenses detected, 109 offenses autocorrectable +# TODO - [LH] -> Mar '26 (v11 prep) - 378 files inspected, 732 offenses detected, 109 offenses autocorrectable # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). @@ -36,14 +34,13 @@ Lint/RescueException: # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect, ContextCreatingMethods, MethodCreatingMethods. +# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. Lint/UselessAccessModifier: Exclude: - 'lib/cucumber/formatter/curl_option_parser.rb' # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect. Lint/UselessMethodDefinition: Exclude: - 'lib/cucumber/glue/proto_world.rb' @@ -53,7 +50,7 @@ Lint/UselessMethodDefinition: Metrics/AbcSize: Max: 127 -# Offense count: 1 +# Offense count: 2 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode. # AllowedMethods: refine Metrics/BlockLength: @@ -64,25 +61,25 @@ Metrics/BlockLength: Metrics/ClassLength: Max: 516 -# Offense count: 10 +# Offense count: 8 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: - Max: 15 + Max: 12 -# Offense count: 83 +# Offense count: 82 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 65 -# Offense count: 15 +# Offense count: 14 # Configuration parameters: CountComments, CountAsOne. Metrics/ModuleLength: Max: 804 -# Offense count: 10 +# Offense count: 8 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: - Max: 15 + Max: 13 # Offense count: 1 # Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. @@ -142,7 +139,6 @@ RSpec/ContextWording: # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect. RSpec/EmptyExampleGroup: Exclude: - 'spec/cucumber/filters/activate_steps_spec.rb' @@ -180,12 +176,12 @@ RSpec/ExpectInHook: - 'spec/cucumber/multiline_argument/data_table_spec.rb' - 'spec/cucumber/runtime/meta_message_builder_spec.rb' -# Offense count: 14 +# Offense count: 13 RSpec/ExpectOutput: Exclude: - 'spec/cucumber/formatter/interceptor_spec.rb' -# Offense count: 63 +# Offense count: 61 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: implicit, each, example @@ -199,11 +195,12 @@ RSpec/IndexedLet: - 'spec/cucumber/filters/retry_spec.rb' - 'spec/cucumber/glue/registry_and_more_spec.rb' -# Offense count: 37 +# Offense count: 52 # Configuration parameters: AssignmentOnly. RSpec/InstanceVariable: Exclude: - 'spec/cucumber/formatter/interceptor_spec.rb' + - 'spec/cucumber/formatter/json_spec.rb' - 'spec/cucumber/formatter/query/hook_by_test_step_spec.rb' - 'spec/support/shared_context/http_server.rb' @@ -228,7 +225,7 @@ RSpec/MissingExampleGroupArgument: - 'spec/cucumber/formatter/fail_fast_spec.rb' - 'spec/cucumber/formatter/rerun_spec.rb' -# Offense count: 60 +# Offense count: 58 RSpec/MultipleExpectations: Max: 3 @@ -294,14 +291,13 @@ RSpec/RepeatedExample: # Offense count: 3 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect. RSpec/ScatteredLet: Exclude: - 'spec/cucumber/runtime/support_code_spec.rb' # Offense count: 1 -# Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata. -# Include: **/*_spec.rb +# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector. +# SupportedInflectors: default, active_support RSpec/SpecFilePathFormat: Exclude: - 'spec/cucumber/formatter/interceptor_spec.rb' @@ -319,13 +315,12 @@ RSpec/SubjectDeclaration: - 'spec/cucumber/runtime/after_hooks_spec.rb' - 'spec/cucumber/runtime/before_hooks_spec.rb' -# Offense count: 57 +# Offense count: 53 # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: Exclude: - 'spec/cucumber/cli/main_spec.rb' - 'spec/cucumber/configuration_spec.rb' - - 'spec/cucumber/filters/activate_steps_spec.rb' - 'spec/cucumber/filters/gated_receiver_spec.rb' - 'spec/cucumber/filters/retry_spec.rb' - 'spec/cucumber/filters/tag_limits/test_case_index_spec.rb' @@ -366,6 +361,14 @@ Style/MutableConstant: Exclude: - 'lib/cucumber/formatter/unicode.rb' +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowedMethods. +# AllowedMethods: infinite?, nonzero? +Style/RedundantCondition: + Exclude: + - 'lib/cucumber/cli/options.rb' + # Offense count: 5 # This cop supports safe autocorrection (--autocorrect). Style/RedundantFreeze: @@ -375,6 +378,12 @@ Style/RedundantFreeze: - 'lib/cucumber/runtime.rb' - 'lib/cucumber/term/ansicolor.rb' +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantParentheses: + Exclude: + - 'lib/cucumber/glue/invoke_in_world.rb' + # Offense count: 5 # This cop supports safe autocorrection (--autocorrect). Style/StderrPuts: diff --git a/cucumber.gemspec b/cucumber.gemspec index fdd7fd492..27ab180ff 100644 --- a/cucumber.gemspec +++ b/cucumber.gemspec @@ -40,10 +40,10 @@ Gem::Specification.new do |s| s.add_development_dependency 'nokogiri', '~> 1.15' s.add_development_dependency 'rake', '~> 13.2' s.add_development_dependency 'rspec', '~> 3.13' - s.add_development_dependency 'rubocop', '~> 1.71.0' + s.add_development_dependency 'rubocop', '~> 1.85.1' s.add_development_dependency 'rubocop-packaging', '~> 0.5.2' s.add_development_dependency 'rubocop-rake', '~> 0.6.0' - s.add_development_dependency 'rubocop-rspec', '~> 3.4.0' + s.add_development_dependency 'rubocop-rspec', '~> 3.8.0' s.add_development_dependency 'simplecov', '~> 0.22.0' s.add_development_dependency 'webrick', '~> 1.8' From 78a8c36363c5b493beca08882611dbaa8e040d8b Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Tue, 17 Mar 2026 23:14:40 +0000 Subject: [PATCH 2/3] Fix up namespaces for all cli tests and expose options iVar --- lib/cucumber/cli/configuration.rb | 2 +- spec/cucumber/cli/configuration_spec.rb | 653 +++++++++-------- spec/cucumber/cli/main_spec.rb | 109 ++- spec/cucumber/cli/options_spec.rb | 883 +++++++++++------------ spec/cucumber/cli/profile_loader_spec.rb | 129 ++-- spec/cucumber/cli/rerun_spec.rb | 156 ++-- 6 files changed, 951 insertions(+), 981 deletions(-) diff --git a/lib/cucumber/cli/configuration.rb b/lib/cucumber/cli/configuration.rb index 8afbca789..ba2693218 100644 --- a/lib/cucumber/cli/configuration.rb +++ b/lib/cucumber/cli/configuration.rb @@ -15,7 +15,7 @@ module Cli class Configuration include Constantize - attr_reader :out_stream + attr_reader :out_stream, :options def initialize(out_stream = $stdout, error_stream = $stderr) @out_stream = out_stream diff --git a/spec/cucumber/cli/configuration_spec.rb b/spec/cucumber/cli/configuration_spec.rb index 6c92248ff..6c8fd4d65 100644 --- a/spec/cucumber/cli/configuration_spec.rb +++ b/spec/cucumber/cli/configuration_spec.rb @@ -1,460 +1,451 @@ # frozen_string_literal: true -require 'spec_helper' require 'yaml' -module Cucumber - module Cli - module ExposesOptions - attr_reader :options - end - - describe Configuration do - def given_cucumber_yml_defined_as(hash_or_string) - allow(File).to receive(:exist?).and_return(true) - cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string - allow(IO).to receive(:read).with('cucumber.yml') { cucumber_yml } - end +describe Cucumber::Cli::Configuration do + def given_cucumber_yml_defined_as(hash_or_string) + allow(File).to receive(:exist?).and_return(true) + cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string + allow(IO).to receive(:read).with('cucumber.yml') { cucumber_yml } + end - def given_the_following_files(*files) - allow(File).to receive(:directory?).and_return(true) - allow(File).to receive(:file?).and_return(true) - allow(Dir).to receive(:[]) { files } - end + def given_the_following_files(*files) + allow(File).to receive(:directory?).and_return(true) + allow(File).to receive(:file?).and_return(true) + allow(Dir).to receive(:[]) { files } + end - before do - allow(File).to receive(:exist?).and_return(false) - allow(Kernel).to receive(:exit) - end + before do + allow(File).to receive(:exist?).and_return(false) + allow(Kernel).to receive(:exit) + end - def config - @config ||= Configuration.new(@out = StringIO.new, @error = StringIO.new).extend(ExposesOptions) - end + def config + @config ||= described_class.new(@out = StringIO.new, @error = StringIO.new) + end - def reset_config - @config = nil - end + def reset_config + @config = nil + end - attr_reader :out, :error + attr_reader :out, :error - it 'uses the default profile when no profile is defined' do - given_cucumber_yml_defined_as('default' => '--require some_file') - config.parse!(%w[--format progress]) + it 'uses the default profile when no profile is defined' do + given_cucumber_yml_defined_as('default' => '--require some_file') + config.parse!(%w[--format progress]) - expect(config.options[:require]).to include('some_file') - end + expect(config.options[:require]).to include('some_file') + end - context 'when using the --profile flag' do - it 'expands args from profiles in the cucumber.yml file' do - given_cucumber_yml_defined_as('bongo' => '--require from/yml') - config.parse!(%w[--format progress --profile bongo]) + context 'when using the --profile flag' do + it 'expands args from profiles in the cucumber.yml file' do + given_cucumber_yml_defined_as('bongo' => '--require from/yml') + config.parse!(%w[--format progress --profile bongo]) - expect(config.options[:formats]).to eq [['progress', {}, out]] - expect(config.options[:require]).to eq ['from/yml'] - end + expect(config.options[:formats]).to eq [['progress', {}, out]] + expect(config.options[:require]).to eq ['from/yml'] + end - it 'expands args from the default profile when no flags are provided' do - given_cucumber_yml_defined_as('default' => '--require from/yml') - config.parse!([]) + it 'expands args from the default profile when no flags are provided' do + given_cucumber_yml_defined_as('default' => '--require from/yml') + config.parse!([]) - expect(config.options[:require]).to eq ['from/yml'] - end + expect(config.options[:require]).to eq ['from/yml'] + end - it 'allows --strict to be set by a profile' do - given_cucumber_yml_defined_as('bongo' => '--strict') - config.parse!(%w[--profile bongo]) + it 'allows --strict to be set by a profile' do + given_cucumber_yml_defined_as('bongo' => '--strict') + config.parse!(%w[--profile bongo]) - expect(config.options[:strict].strict?(:undefined)).to be true - expect(config.options[:strict].strict?(:pending)).to be true - expect(config.options[:strict].strict?(:flaky)).to be true - end + expect(config.options[:strict].strict?(:undefined)).to be true + expect(config.options[:strict].strict?(:pending)).to be true + expect(config.options[:strict].strict?(:flaky)).to be true + end - it 'allows --strict from a profile to be selectively overridden' do - given_cucumber_yml_defined_as('bongo' => '--strict') - config.parse!(%w[--profile bongo --no-strict-flaky]) + it 'allows --strict from a profile to be selectively overridden' do + given_cucumber_yml_defined_as('bongo' => '--strict') + config.parse!(%w[--profile bongo --no-strict-flaky]) - expect(config.options[:strict].strict?(:undefined)).to be true - expect(config.options[:strict].strict?(:pending)).to be true - expect(config.options[:strict].strict?(:flaky)).to be false - end + expect(config.options[:strict].strict?(:undefined)).to be true + expect(config.options[:strict].strict?(:pending)).to be true + expect(config.options[:strict].strict?(:flaky)).to be false + end - it 'parses ERB syntax in the cucumber.yml file' do - given_cucumber_yml_defined_as("---\ndefault: \"<%=\"--require some_file\"%>\"\n") - config.parse!([]) + it 'parses ERB syntax in the cucumber.yml file' do + given_cucumber_yml_defined_as("---\ndefault: \"<%=\"--require some_file\"%>\"\n") + config.parse!([]) - expect(config.options[:require]).to include('some_file') - end + expect(config.options[:require]).to include('some_file') + end - it 'parses ERB in cucumber.yml that makes uses nested ERB sessions' do - given_cucumber_yml_defined_as(<<~ERB_YML) - <%= ERB.new({'standard' => '--require some_file'}.to_yaml).result %> - <%= ERB.new({'enhanced' => '--require other_file'}.to_yaml).result %> - ERB_YML + it 'parses ERB in cucumber.yml that makes uses nested ERB sessions' do + given_cucumber_yml_defined_as(<<~ERB_YML) + <%= ERB.new({'standard' => '--require some_file'}.to_yaml).result %> + <%= ERB.new({'enhanced' => '--require other_file'}.to_yaml).result %> + ERB_YML - config.parse!(%w[-p standard]) + config.parse!(%w[-p standard]) - expect(config.options[:require]).to include('some_file') - end + expect(config.options[:require]).to include('some_file') + end - it 'provides a helpful error message when a specified profile does not exists in cucumber.yml' do - given_cucumber_yml_defined_as('default' => '--require from/yml', 'json_report' => '--format json') + it 'provides a helpful error message when a specified profile does not exists in cucumber.yml' do + given_cucumber_yml_defined_as('default' => '--require from/yml', 'json_report' => '--format json') - expected_message = <<~END_OF_MESSAGE - Could not find profile: 'i_do_not_exist' + expected_message = <<~END_OF_MESSAGE + Could not find profile: 'i_do_not_exist' - Defined profiles in cucumber.yml: - * default - * json_report - END_OF_MESSAGE + Defined profiles in cucumber.yml: + * default + * json_report + END_OF_MESSAGE - expect { config.parse!(%w[--profile i_do_not_exist]) }.to raise_error(ProfileNotFound, expected_message) - end + expect { config.parse!(%w[--profile i_do_not_exist]) }.to raise_error(Cucumber::Cli::ProfileNotFound, expected_message) + end - it 'allows profiles to be defined in arrays' do - given_cucumber_yml_defined_as('foo' => ['-f', 'progress']) - config.parse!(%w[--profile foo]) + it 'allows profiles to be defined in arrays' do + given_cucumber_yml_defined_as('foo' => ['-f', 'progress']) + config.parse!(%w[--profile foo]) - expect(config.options[:formats]).to eq [['progress', {}, out]] - end + expect(config.options[:formats]).to eq [['progress', {}, out]] + end - it 'disregards default STDOUT formatter defined in profile when another is passed in (via cmd line)' do - given_cucumber_yml_defined_as('foo' => %w[--format pretty]) - config.parse!(%w[--format progress --profile foo]) + it 'disregards default STDOUT formatter defined in profile when another is passed in (via cmd line)' do + given_cucumber_yml_defined_as('foo' => %w[--format pretty]) + config.parse!(%w[--format progress --profile foo]) - expect(config.options[:formats]).to eq [['progress', {}, out]] - end + expect(config.options[:formats]).to eq [['progress', {}, out]] + end - ['--no-profile', '-P'].each do |flag| - context "when #{flag} is specified with none" do - it 'disables profiles' do - given_cucumber_yml_defined_as('default' => '-v --require file_specified_in_default_profile.rb') - config.parse!("#{flag} --require some_file.rb".split(' ')) + ['--no-profile', '-P'].each do |flag| + context "when #{flag} is specified with none" do + it 'disables profiles' do + given_cucumber_yml_defined_as('default' => '-v --require file_specified_in_default_profile.rb') + config.parse!("#{flag} --require some_file.rb".split(' ')) - expect(config.options[:require]).to eq ['some_file.rb'] - end + expect(config.options[:require]).to eq ['some_file.rb'] + end - it 'notifies the user that the profiles are being disabled' do - given_cucumber_yml_defined_as('default' => '-v') - config.parse!("#{flag} --require some_file.rb".split(' ')) + it 'notifies the user that the profiles are being disabled' do + given_cucumber_yml_defined_as('default' => '-v') + config.parse!("#{flag} --require some_file.rb".split(' ')) - expect(out.string).to match(/Disabling profiles.../) - end - end + expect(out.string).to match(/Disabling profiles.../) end + end + end - it 'issues a helpful error message when a specified profile exists but is nil or blank' do - [nil, ' '].each do |bad_input| - given_cucumber_yml_defined_as('foo' => bad_input) - expected_error = /The 'foo' profile in cucumber.yml was blank. Please define the command line arguments for the 'foo' profile in cucumber.yml./ + it 'issues a helpful error message when a specified profile exists but is nil or blank' do + [nil, ' '].each do |bad_input| + given_cucumber_yml_defined_as('foo' => bad_input) + expected_error = /The 'foo' profile in cucumber.yml was blank. Please define the command line arguments for the 'foo' profile in cucumber.yml./ - expect { config.parse!(%w[--profile foo]) }.to raise_error(expected_error) - end - end + expect { config.parse!(%w[--profile foo]) }.to raise_error(expected_error) + end + end - it 'issues a helpful error message when no YAML file exists and a profile is specified' do - expect(File).to receive(:exist?).with('cucumber.yml').and_return(false) + it 'issues a helpful error message when no YAML file exists and a profile is specified' do + expect(File).to receive(:exist?).with('cucumber.yml').and_return(false) - expect { config.parse!(%w[--profile i_do_not_exist]) }.to raise_error(/cucumber\.yml was not found/) - end + expect { config.parse!(%w[--profile i_do_not_exist]) }.to raise_error(/cucumber\.yml was not found/) + end - it 'issues a helpful error message when cucumber.yml is blank or malformed' do - expected_error_message = /cucumber\.yml was found, but was blank or malformed.\nPlease refer to cucumber's documentation on correct profile usage./ + it 'issues a helpful error message when cucumber.yml is blank or malformed' do + expected_error_message = /cucumber\.yml was found, but was blank or malformed.\nPlease refer to cucumber's documentation on correct profile usage./ - ['', 'sfsadfs', "--- \n- an\n- array\n", '---dddfd'].each do |bad_input| - given_cucumber_yml_defined_as(bad_input) + ['', 'sfsadfs', "--- \n- an\n- array\n", '---dddfd'].each do |bad_input| + given_cucumber_yml_defined_as(bad_input) - expect { config.parse!([]) }.to raise_error(expected_error_message) + expect { config.parse!([]) }.to raise_error(expected_error_message) - reset_config - end - end + reset_config + end + end - it 'issues a helpful error message when cucumber.yml can not be parsed' do - given_cucumber_yml_defined_as('input that causes an exception in YAML loading') + it 'issues a helpful error message when cucumber.yml can not be parsed' do + given_cucumber_yml_defined_as('input that causes an exception in YAML loading') - expect(YAML).to receive(:load).and_raise(ArgumentError) - expect { config.parse!([]) }.to raise_error(/cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage./) - end + expect(YAML).to receive(:load).and_raise(ArgumentError) + expect { config.parse!([]) }.to raise_error(/cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage./) + end - it 'issues a helpful error message when cucumber.yml can not be parsed by ERB' do - given_cucumber_yml_defined_as('<% this_fails %>') + it 'issues a helpful error message when cucumber.yml can not be parsed by ERB' do + given_cucumber_yml_defined_as('<% this_fails %>') - expect { config.parse!([]) }.to raise_error(/cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage./) - end - end + expect { config.parse!([]) }.to raise_error(/cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage./) + end + end - it 'accepts --dry-run option' do - config.parse!(%w[--dry-run]) + it 'accepts --dry-run option' do + config.parse!(%w[--dry-run]) - expect(config.options[:dry_run]).to be true - end + expect(config.options[:dry_run]).to be true + end - it 'implies --no-duration with --dry-run option' do - config.parse!(%w[--dry-run]) + it 'implies --no-duration with --dry-run option' do + config.parse!(%w[--dry-run]) - expect(config.options[:duration]).to be false - end + expect(config.options[:duration]).to be false + end - it 'accepts --no-source option' do - config.parse!(%w[--no-source]) + it 'accepts --no-source option' do + config.parse!(%w[--no-source]) - expect(config.options[:source]).to be false - end + expect(config.options[:source]).to be false + end - it 'accepts --no-snippets option' do - config.parse!(%w[--no-snippets]) + it 'accepts --no-snippets option' do + config.parse!(%w[--no-snippets]) - expect(config.options[:snippets]).to be false - end + expect(config.options[:snippets]).to be false + end - it 'sets snippets and source and duration to false with --quiet option' do - config.parse!(%w[--quiet]) + it 'sets snippets and source and duration to false with --quiet option' do + config.parse!(%w[--quiet]) - expect(config.options[:snippets]).to be false - expect(config.options[:source]).to be false - expect(config.options[:duration]).to be false - end + expect(config.options[:snippets]).to be false + expect(config.options[:source]).to be false + expect(config.options[:duration]).to be false + end - it 'sets duration to false with --no-duration' do - config.parse!(%w[--no-duration]) + it 'sets duration to false with --no-duration' do + config.parse!(%w[--no-duration]) - expect(config.options[:duration]).to be false - end + expect(config.options[:duration]).to be false + end - it 'accepts --verbose option' do - config.parse!(%w[--verbose]) + it 'accepts --verbose option' do + config.parse!(%w[--verbose]) - expect(config.options[:verbose]).to be true - end + expect(config.options[:verbose]).to be true + end - it 'uses the pretty formatter to stdout when no formatter is defined' do - config.parse!([]) + it 'uses the pretty formatter to stdout when no formatter is defined' do + config.parse!([]) - expect(config.formats).to eq [['pretty', {}, out]] - end + expect(config.formats).to eq [['pretty', {}, out]] + end - it 'adds the default formatter when no other formatter is defined with --publish' do - config.parse!(['--publish']) + it 'adds the default formatter when no other formatter is defined with --publish' do + config.parse!(['--publish']) - expect(config.formats).to eq [ - ['pretty', {}, out], - ['message', {}, 'https://messages.cucumber.io/api/reports -X GET'] - ] - end + expect(config.formats).to eq [ + ['pretty', {}, out], + ['message', {}, 'https://messages.cucumber.io/api/reports -X GET'] + ] + end - it 'does not add the default formatter when a formatter is defined with --publish' do - config.parse!(['--publish', '--format', 'progress']) + it 'does not add the default formatter when a formatter is defined with --publish' do + config.parse!(['--publish', '--format', 'progress']) - expect(config.formats).to eq [ - ['progress', {}, out], - ['message', {}, 'https://messages.cucumber.io/api/reports -X GET'] - ] - end + expect(config.formats).to eq [ + ['progress', {}, out], + ['message', {}, 'https://messages.cucumber.io/api/reports -X GET'] + ] + end - it 'does not add the default formatter with --format message' do - config.parse!(['--format', 'message']) + it 'does not add the default formatter with --format message' do + config.parse!(['--format', 'message']) - expect(config.formats).to eq [ - ['message', {}, out] - ] - end + expect(config.formats).to eq [ + ['message', {}, out] + ] + end - it 'accepts --out option' do - config.parse!(%w[--out jalla.txt]) + it 'accepts --out option' do + config.parse!(%w[--out jalla.txt]) - expect(config.formats).to eq [['pretty', {}, 'jalla.txt']] - end + expect(config.formats).to eq [['pretty', {}, 'jalla.txt']] + end - it 'accepts multiple --out options' do - config.parse!(%w[--format progress --out file1 --out file2]) + it 'accepts multiple --out options' do + config.parse!(%w[--format progress --out file1 --out file2]) - expect(config.formats).to eq [['progress', {}, 'file2']] - end + expect(config.formats).to eq [['progress', {}, 'file2']] + end - it 'accepts multiple --format options and put the STDOUT one first so progress is seen' do - config.parse!(%w[--format pretty --out pretty.txt --format progress]) + it 'accepts multiple --format options and put the STDOUT one first so progress is seen' do + config.parse!(%w[--format pretty --out pretty.txt --format progress]) - expect(config.formats).to eq [['progress', {}, out], ['pretty', {}, 'pretty.txt']] - end + expect(config.formats).to eq [['progress', {}, out], ['pretty', {}, 'pretty.txt']] + end - it 'does not accept multiple --format options when both use implicit STDOUT' do - expect { config.parse!(%w[--format pretty --format progress]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') - end + it 'does not accept multiple --format options when both use implicit STDOUT' do + expect { config.parse!(%w[--format pretty --format progress]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') + end - it 'does not accept multiple --format options when both use implicit STDOUT (using profile with no formatters)' do - given_cucumber_yml_defined_as('default' => ['-q']) - expect { config.parse!(%w[--format pretty --format progress]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') - end + it 'does not accept multiple --format options when both use implicit STDOUT (using profile with no formatters)' do + given_cucumber_yml_defined_as('default' => ['-q']) + expect { config.parse!(%w[--format pretty --format progress]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') + end - it 'accepts same --format options with implicit STDOUT, and keep only one' do - config.parse!(%w[--format pretty --format pretty]) + it 'accepts same --format options with implicit STDOUT, and keep only one' do + config.parse!(%w[--format pretty --format pretty]) - expect(config.formats).to eq [['pretty', {}, out]] - end + expect(config.formats).to eq [['pretty', {}, out]] + end - it 'does not accept multiple --out streams pointing to the same place' do - expected_error = 'All but one formatter must use --out, only one can print to each stream (or STDOUT)' - expect { config.parse!(%w[--format pretty --out file1 --format progress --out file1]) }.to raise_error(expected_error) - end + it 'does not accept multiple --out streams pointing to the same place' do + expected_error = 'All but one formatter must use --out, only one can print to each stream (or STDOUT)' + expect { config.parse!(%w[--format pretty --out file1 --format progress --out file1]) }.to raise_error(expected_error) + end - it 'does not accept multiple --out streams pointing to the same place (one from profile, one from command line)' do - given_cucumber_yml_defined_as('default' => ['-f', 'progress', '--out', 'file1']) - expect { config.parse!(%w[--format pretty --out file1]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') - end + it 'does not accept multiple --out streams pointing to the same place (one from profile, one from command line)' do + given_cucumber_yml_defined_as('default' => ['-f', 'progress', '--out', 'file1']) + expect { config.parse!(%w[--format pretty --out file1]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') + end - it 'associates --out to previous --format' do - config.parse!(%w[--format progress --out file1 --format profile --out file2]) + it 'associates --out to previous --format' do + config.parse!(%w[--format progress --out file1 --format profile --out file2]) - expect(config.formats).to match_array([['progress', {}, 'file1'], ['profile', {}, 'file2']]) - end + expect(config.formats).to match_array([['progress', {}, 'file1'], ['profile', {}, 'file2']]) + end - it 'accepts same --format options with same --out streams and keep only one' do - config.parse!(%w[--format json --out file --format pretty --format json --out file]) + it 'accepts same --format options with same --out streams and keep only one' do + config.parse!(%w[--format json --out file --format pretty --format json --out file]) - expect(config.formats).to eq [['pretty', {}, out], ['json', {}, 'file']] - end + expect(config.formats).to eq [['pretty', {}, out], ['json', {}, 'file']] + end - it 'accepts same --format options with different --out streams' do - config.parse!(%w[--format json --out file1 --format json --out file2]) + it 'accepts same --format options with different --out streams' do + config.parse!(%w[--format json --out file1 --format json --out file2]) - expect(config.formats).to match_array([['json', {}, 'file1'], ['json', {}, 'file2']]) - end + expect(config.formats).to match_array([['json', {}, 'file1'], ['json', {}, 'file2']]) + end - it 'accepts --color option' do - expect(Cucumber::Term::ANSIColor).to receive(:coloring=).with(true) + it 'accepts --color option' do + expect(Cucumber::Term::ANSIColor).to receive(:coloring=).with(true) - config.parse!(['--color']) - end + config.parse!(['--color']) + end - it 'accepts --no-color option' do - expect(Cucumber::Term::ANSIColor).to receive(:coloring=).with(false) + it 'accepts --no-color option' do + expect(Cucumber::Term::ANSIColor).to receive(:coloring=).with(false) - config = described_class.new(StringIO.new) - config.parse!(['--no-color']) - end + config = described_class.new(StringIO.new) + config.parse!(['--no-color']) + end - describe '--backtrace' do - before do - Cucumber.use_full_backtrace = false - end + describe '--backtrace' do + before do + Cucumber.use_full_backtrace = false + end - after do - Cucumber.use_full_backtrace = false - end + after do + Cucumber.use_full_backtrace = false + end - it 'shows full backtrace when --backtrace is present' do - Main.new(['--backtrace']) - expect('x').to eq('y') - rescue RSpec::Expectations::ExpectationNotMetError => e - expect(e.backtrace[0]).not_to eq "#{__FILE__}:#{__LINE__ - 2}" - end - end + it 'shows full backtrace when --backtrace is present' do + Cucumber::Cli::Main.new(['--backtrace']) + expect('x').to eq('y') + rescue RSpec::Expectations::ExpectationNotMetError => e + expect(e.backtrace[0]).not_to eq "#{__FILE__}:#{__LINE__ - 2}" + end + end - it 'accepts multiple --name options' do - config.parse!(['--name', 'User logs in', '--name', 'User signs up']) + it 'accepts multiple --name options' do + config.parse!(['--name', 'User logs in', '--name', 'User signs up']) - expect(config.options[:name_regexps]).to include(/User logs in/) - expect(config.options[:name_regexps]).to include(/User signs up/) - end + expect(config.options[:name_regexps]).to include(/User logs in/) + expect(config.options[:name_regexps]).to include(/User signs up/) + end - it 'accepts multiple -n options' do - config.parse!(['-n', 'User logs in', '-n', 'User signs up']) + it 'accepts multiple -n options' do + config.parse!(['-n', 'User logs in', '-n', 'User signs up']) - expect(config.options[:name_regexps]).to include(/User logs in/) - expect(config.options[:name_regexps]).to include(/User signs up/) - end + expect(config.options[:name_regexps]).to include(/User logs in/) + expect(config.options[:name_regexps]).to include(/User signs up/) + end - it 'allows specifying environment variables on the command line' do - config.parse!(['foo=bar']) + it 'allows specifying environment variables on the command line' do + config.parse!(['foo=bar']) - expect(ENV['foo']).to eq 'bar' - expect(config.paths).not_to include('foo=bar') - end + expect(ENV['foo']).to eq 'bar' + expect(config.paths).not_to include('foo=bar') + end - it 'allows specifying environment variables in profiles' do - given_cucumber_yml_defined_as('selenium' => 'RAILS_ENV=selenium') - config.parse!(['--profile', 'selenium']) + it 'allows specifying environment variables in profiles' do + given_cucumber_yml_defined_as('selenium' => 'RAILS_ENV=selenium') + config.parse!(['--profile', 'selenium']) - expect(ENV['RAILS_ENV']).to eq 'selenium' - expect(config.paths).not_to include('RAILS_ENV=selenium') - end + expect(ENV['RAILS_ENV']).to eq 'selenium' + expect(config.paths).not_to include('RAILS_ENV=selenium') + end - describe '#tag_expressions' do - it 'returns an empty expression when no tags are specified' do - config.parse!([]) + describe '#tag_expressions' do + it 'returns an empty expression when no tags are specified' do + config.parse!([]) - expect(config.tag_expressions).to be_empty - end + expect(config.tag_expressions).to be_empty + end - it 'returns an expression when tags are specified' do - config.parse!(['--tags', '@foo']) + it 'returns an expression when tags are specified' do + config.parse!(['--tags', '@foo']) - expect(config.tag_expressions).not_to be_empty - end - end + expect(config.tag_expressions).not_to be_empty + end + end - describe '#tag_limits' do - it 'returns an empty hash when no limits are specified' do - config.parse!([]) + describe '#tag_limits' do + it 'returns an empty hash when no limits are specified' do + config.parse!([]) - expect(config.tag_limits).to eq({}) - end + expect(config.tag_limits).to eq({}) + end - it 'returns a hash of limits when limits are specified' do - config.parse!(['--tags', '@foo:1']) + it 'returns a hash of limits when limits are specified' do + config.parse!(['--tags', '@foo:1']) - expect(config.tag_limits).to eq('@foo' => 1) - end - end + expect(config.tag_limits).to eq('@foo' => 1) + end + end - describe '#dry_run?' do - it 'returns true when --dry-run was specified on in the arguments' do - config.parse!(['--dry-run']) + describe '#dry_run?' do + it 'returns true when --dry-run was specified on in the arguments' do + config.parse!(['--dry-run']) - expect(config.dry_run?).to be true - end + expect(config.dry_run?).to be true + end - it 'returns true when --dry-run was specified in yaml file' do - given_cucumber_yml_defined_as('default' => '--dry-run') - config.parse!([]) + it 'returns true when --dry-run was specified in yaml file' do + given_cucumber_yml_defined_as('default' => '--dry-run') + config.parse!([]) - expect(config.dry_run?).to be true - end + expect(config.dry_run?).to be true + end - it 'returns false by default' do - config.parse!([]) + it 'returns false by default' do + config.parse!([]) - expect(config.dry_run?).to be false - end - end + expect(config.dry_run?).to be false + end + end - describe '#snippet_type' do - it 'returns the snippet type when it was set' do - config.parse!(['--snippet-type', 'classic']) + describe '#snippet_type' do + it 'returns the snippet type when it was set' do + config.parse!(['--snippet-type', 'classic']) - expect(config.snippet_type).to eq(:classic) - end + expect(config.snippet_type).to eq(:classic) + end - it 'returns the snippet type when it was set with shorthand option' do - config.parse!(['-I', 'classic']) + it 'returns the snippet type when it was set with shorthand option' do + config.parse!(['-I', 'classic']) - expect(config.snippet_type).to eq(:classic) - end + expect(config.snippet_type).to eq(:classic) + end - it 'returns the default snippet type if it was not set' do - config.parse!([]) + it 'returns the default snippet type if it was not set' do + config.parse!([]) - expect(config.snippet_type).to eq(:cucumber_expression) - end - end + expect(config.snippet_type).to eq(:cucumber_expression) + end + end - describe '#retry_attempts' do - it 'returns the specified number of retries' do - config.parse!(['--retry=3']) + describe '#retry_attempts' do + it 'returns the specified number of retries' do + config.parse!(['--retry=3']) - expect(config.retry_attempts).to eq(3) - end - end + expect(config.retry_attempts).to eq(3) end end end diff --git a/spec/cucumber/cli/main_spec.rb b/spec/cucumber/cli/main_spec.rb index 8183d5c1e..123e26c38 100644 --- a/spec/cucumber/cli/main_spec.rb +++ b/spec/cucumber/cli/main_spec.rb @@ -1,85 +1,80 @@ # frozen_string_literal: true -require 'spec_helper' require 'yaml' -module Cucumber - module Cli - describe Main do - before(:each) do - allow(File).to receive(:exist?).and_return(false) # When Configuration checks for cucumber.yml - allow(Dir).to receive(:[]).and_return([]) # to prevent cucumber's features dir to being laoded - end +describe Cucumber::Cli::Main do + before(:each) do + allow(File).to receive(:exist?).and_return(false) # When Configuration checks for cucumber.yml + allow(Dir).to receive(:[]).and_return([]) # to prevent cucumber's features dir to being laoded + end - let(:args) { [] } - let(:stdout) { StringIO.new } - let(:stderr) { StringIO.new } - let(:kernel) { double(:kernel) } + let(:args) { [] } + let(:stdout) { StringIO.new } + let(:stderr) { StringIO.new } + let(:kernel) { double(:kernel) } - subject { described_class.new(args, stdout, stderr, kernel) } + subject { described_class.new(args, stdout, stderr, kernel) } - describe '#execute!' do - context 'when passed an existing runtime' do - let(:existing_runtime) { double('runtime').as_null_object } + describe '#execute!' do + context 'when passed an existing runtime' do + let(:existing_runtime) { double('runtime').as_null_object } - def do_execute - subject.execute!(existing_runtime) - end + def do_execute + subject.execute!(existing_runtime) + end - it 'configures that runtime' do - expected_configuration = double('Configuration').as_null_object + it 'configures that runtime' do + expected_configuration = double('Configuration').as_null_object - allow(Configuration).to receive(:new) { expected_configuration } - expect(existing_runtime).to receive(:configure).with(expected_configuration) - expect(kernel).to receive(:exit).with(1) + allow(Cucumber::Cli::Configuration).to receive(:new) { expected_configuration } + expect(existing_runtime).to receive(:configure).with(expected_configuration) + expect(kernel).to receive(:exit).with(1) - do_execute - end + do_execute + end - it 'uses that runtime for running and reporting results' do - expected_results = double('results', failure?: true) + it 'uses that runtime for running and reporting results' do + expected_results = double('results', failure?: true) - expect(existing_runtime).to receive(:run!) - allow(existing_runtime).to receive(:results) { expected_results } - expect(kernel).to receive(:exit).with(1) + expect(existing_runtime).to receive(:run!) + allow(existing_runtime).to receive(:results) { expected_results } + expect(kernel).to receive(:exit).with(1) - do_execute - end - end + do_execute + end + end - context 'when interrupted with ctrl-c' do - after do - Cucumber.wants_to_quit = false - end + context 'when interrupted with ctrl-c' do + after do + Cucumber.wants_to_quit = false + end - it 'exits with error code' do - results = double('results', failure?: false) + it 'exits with error code' do + results = double('results', failure?: false) - allow_any_instance_of(Runtime).to receive(:run!) - allow_any_instance_of(Runtime).to receive(:results) { results } + allow_any_instance_of(Cucumber::Runtime).to receive(:run!) + allow_any_instance_of(Cucumber::Runtime).to receive(:results) { results } - Cucumber.wants_to_quit = true + Cucumber.wants_to_quit = true - expect(kernel).to receive(:exit).with(2) + expect(kernel).to receive(:exit).with(2) - subject.execute! - end - end + subject.execute! end + end + end - [ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_klass| - it "rescues #{exception_klass}, prints the message to the error stream" do - configuration = double('configuration') + [Cucumber::Cli::ProfilesNotDefinedError, Cucumber::Cli::YmlLoadError, Cucumber::Cli::ProfileNotFound].each do |exception_klass| + it "rescues #{exception_klass}, prints the message to the error stream" do + configuration = double('configuration') - allow(Configuration).to receive(:new) { configuration } - allow(configuration).to receive(:parse!).and_raise(exception_klass.new('error message')) - allow(kernel).to receive(:exit).with(2) + allow(Cucumber::Cli::Configuration).to receive(:new) { configuration } + allow(configuration).to receive(:parse!).and_raise(exception_klass.new('error message')) + allow(kernel).to receive(:exit).with(2) - subject.execute! + subject.execute! - expect(stderr.string).to eq "error message\n" - end - end + expect(stderr.string).to eq "error message\n" end end end diff --git a/spec/cucumber/cli/options_spec.rb b/spec/cucumber/cli/options_spec.rb index 47d4d9e21..59ab496b0 100644 --- a/spec/cucumber/cli/options_spec.rb +++ b/spec/cucumber/cli/options_spec.rb @@ -1,594 +1,589 @@ # frozen_string_literal: true -require 'spec_helper' require 'yaml' require 'cucumber/cli/options' -module Cucumber - module Cli - describe Options do - def given_cucumber_yml_defined_as(hash_or_string) - allow(File).to receive(:exist?).and_return(true) +describe Cucumber::Cli::Options do + def given_cucumber_yml_defined_as(hash_or_string) + allow(File).to receive(:exist?).and_return(true) - cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string + cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string - allow(IO).to receive(:read).with('cucumber.yml') { cucumber_yml } - end + allow(IO).to receive(:read).with('cucumber.yml') { cucumber_yml } + end - before(:each) do - allow(File).to receive(:exist?).and_return(false) # Meaning, no cucumber.yml exists - allow(Kernel).to receive(:exit) - end + before(:each) do + allow(File).to receive(:exist?).and_return(false) # Meaning, no cucumber.yml exists + allow(Kernel).to receive(:exit) + end - def output_stream - @output_stream ||= StringIO.new - end + def output_stream + @output_stream ||= StringIO.new + end - def error_stream - @error_stream ||= StringIO.new - end + def error_stream + @error_stream ||= StringIO.new + end - def options - @options ||= Options.new(output_stream, error_stream) - end + def options + @options ||= described_class.new(output_stream, error_stream) + end - def prepare_args(args) - args.is_a?(Array) ? args : args.split(' ') - end + def prepare_args(args) + args.is_a?(Array) ? args : args.split(' ') + end - describe 'parsing' do - def when_parsing(args) - yield - options.parse!(prepare_args(args)) - end + describe 'parsing' do + def when_parsing(args) + yield + options.parse!(prepare_args(args)) + end - def after_parsing(args) - options.parse!(prepare_args(args)) - yield - end + def after_parsing(args) + options.parse!(prepare_args(args)) + yield + end - def with_env(name, value) - previous_value = ENV[name] - ENV[name] = value.to_s - yield - if previous_value.nil? - ENV.delete(name) - else - ENV[name] = previous_value - end - end + def with_env(name, value) + previous_value = ENV[name] + ENV[name] = value.to_s + yield + if previous_value.nil? + ENV.delete(name) + else + ENV[name] = previous_value + end + end - context 'when using -r or --require' do - it 'collects all specified files into an array' do - after_parsing('--require some_file.rb -r another_file.rb') do - expect(options[:require]).to eq ['some_file.rb', 'another_file.rb'] - end - end + context 'when using -r or --require' do + it 'collects all specified files into an array' do + after_parsing('--require some_file.rb -r another_file.rb') do + expect(options[:require]).to eq ['some_file.rb', 'another_file.rb'] end + end + end - context 'with --i18n-languages' do - it 'lists all known languages' do - after_parsing '--i18n-languages' do - ::Gherkin::DIALECTS.keys.map do |key| - expect(@output_stream.string).to include(key.to_s) - end - end - end - - it 'exits the program' do - when_parsing('--i18n-languages') { expect(Kernel).to receive(:exit) } + context 'with --i18n-languages' do + it 'lists all known languages' do + after_parsing '--i18n-languages' do + ::Gherkin::DIALECTS.keys.map do |key| + expect(@output_stream.string).to include(key.to_s) end end + end - context 'with --i18n-keywords but an invalid LANG' do - it 'exits' do - when_parsing '--i18n-keywords foo' do - expect(Kernel).to receive(:exit) - end - end - - it 'says the language was invalid' do - after_parsing '--i18n-keywords foo' do - expect(@output_stream.string).to include("Invalid language 'foo'. Available languages are:") - end - end + it 'exits the program' do + when_parsing('--i18n-languages') { expect(Kernel).to receive(:exit) } + end + end - it 'displays the language table' do - after_parsing '--i18n-keywords foo' do - ::Gherkin::DIALECTS.keys.map do |key| - expect(@output_stream.string).to include(key.to_s) - end - end - end + context 'with --i18n-keywords but an invalid LANG' do + it 'exits' do + when_parsing '--i18n-keywords foo' do + expect(Kernel).to receive(:exit) end + end - context 'when using -f FORMAT or --format FORMAT' do - it 'defaults the output for the formatter to the output stream (STDOUT)' do - after_parsing('-f pretty') { expect(options[:formats]).to eq [['pretty', {}, output_stream]] } - end + it 'says the language was invalid' do + after_parsing '--i18n-keywords foo' do + expect(@output_stream.string).to include("Invalid language 'foo'. Available languages are:") + end + end - it 'extracts per-formatter options' do - after_parsing('-f pretty,foo=bar,foo2=bar2') do - expect(options[:formats]).to eq [['pretty', { 'foo' => 'bar', 'foo2' => 'bar2' }, output_stream]] - end + it 'displays the language table' do + after_parsing '--i18n-keywords foo' do + ::Gherkin::DIALECTS.keys.map do |key| + expect(@output_stream.string).to include(key.to_s) end + end + end + end - it 'extracts junit formatter file attribute option' do - after_parsing('-f junit,file-attribute=true') do - expect(options[:formats]).to eq [['junit', { 'file-attribute' => 'true' }, output_stream]] - end - end + context 'when using -f FORMAT or --format FORMAT' do + it 'defaults the output for the formatter to the output stream (STDOUT)' do + after_parsing('-f pretty') { expect(options[:formats]).to eq [['pretty', {}, output_stream]] } + end - it 'extracts junit formatter file attribute option with pretty' do - after_parsing('-f pretty -f junit,file-attribute=true -o file.txt') do - expect(options[:formats]).to eq [['pretty', {}, output_stream], ['junit', { 'file-attribute' => 'true' }, 'file.txt']] - end - end + it 'extracts per-formatter options' do + after_parsing('-f pretty,foo=bar,foo2=bar2') do + expect(options[:formats]).to eq [['pretty', { 'foo' => 'bar', 'foo2' => 'bar2' }, output_stream]] end + end - context 'when using -o [FILE|DIR] or --out [FILE|DIR]' do - it "defaults the formatter to 'pretty' when not specified earlier" do - after_parsing('-o file.txt') { expect(options[:formats]).to eq [['pretty', {}, 'file.txt']] } - end - - it 'sets the output for the formatter defined immediately before it' do - after_parsing('-f profile --out file.txt -f pretty -o file2.txt') do - expect(options[:formats]).to eq [['profile', {}, 'file.txt'], ['pretty', {}, 'file2.txt']] - end - end + it 'extracts junit formatter file attribute option' do + after_parsing('-f junit,file-attribute=true') do + expect(options[:formats]).to eq [['junit', { 'file-attribute' => 'true' }, output_stream]] end + end - context 'when handling multiple formatters' do - let(:options) { described_class.new(output_stream, error_stream, default_profile: 'default') } + it 'extracts junit formatter file attribute option with pretty' do + after_parsing('-f pretty -f junit,file-attribute=true -o file.txt') do + expect(options[:formats]).to eq [['pretty', {}, output_stream], ['junit', { 'file-attribute' => 'true' }, 'file.txt']] + end + end + end - it 'catches multiple command line formatters using the same stream' do - expect { options.parse!(prepare_args('-f pretty -f progress')) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') - end + context 'when using -o [FILE|DIR] or --out [FILE|DIR]' do + it "defaults the formatter to 'pretty' when not specified earlier" do + after_parsing('-o file.txt') { expect(options[:formats]).to eq [['pretty', {}, 'file.txt']] } + end - it 'catches multiple profile formatters using the same stream' do - given_cucumber_yml_defined_as('default' => '-f progress -f pretty') + it 'sets the output for the formatter defined immediately before it' do + after_parsing('-f profile --out file.txt -f pretty -o file2.txt') do + expect(options[:formats]).to eq [['profile', {}, 'file.txt'], ['pretty', {}, 'file2.txt']] + end + end + end - expect { options.parse!(%w[]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') - end + context 'when handling multiple formatters' do + let(:options) { described_class.new(output_stream, error_stream, default_profile: 'default') } - it 'profiles does not affect the catching of multiple command line formatters using the same stream' do - given_cucumber_yml_defined_as('default' => '-q') + it 'catches multiple command line formatters using the same stream' do + expect { options.parse!(prepare_args('-f pretty -f progress')) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') + end - expect { options.parse!(%w[-f progress -f pretty]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') - end + it 'catches multiple profile formatters using the same stream' do + given_cucumber_yml_defined_as('default' => '-f progress -f pretty') - it 'merges profile formatters and command line formatters' do - given_cucumber_yml_defined_as('default' => '-f junit -o result.xml') - options.parse!(%w[-f pretty]) + expect { options.parse!(%w[]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') + end - expect(options[:formats]).to eq [['pretty', {}, output_stream], ['junit', {}, 'result.xml']] - end - end + it 'profiles does not affect the catching of multiple command line formatters using the same stream' do + given_cucumber_yml_defined_as('default' => '-q') - context 'when using -t TAGS or --tags TAGS' do - it 'handles tag expressions as argument' do - after_parsing(['--tags', 'not @foo or @bar']) do - expect(options[:tag_expressions]).to eq(['not @foo or @bar']) - end - end + expect { options.parse!(%w[-f progress -f pretty]) }.to raise_error('All but one formatter must use --out, only one can print to each stream (or STDOUT)') + end - it 'stores tags passed with different --tags separately' do - after_parsing('--tags @foo --tags @bar') do - expect(options[:tag_expressions]).to eq(['@foo', '@bar']) - end - end + it 'merges profile formatters and command line formatters' do + given_cucumber_yml_defined_as('default' => '-f junit -o result.xml') + options.parse!(%w[-f pretty]) - it 'strips tag limits from the tag expressions stored' do - after_parsing(['--tags', 'not @foo:2 or @bar:3']) do - expect(options[:tag_expressions]).to eq(['not @foo or @bar']) - end - end + expect(options[:formats]).to eq [['pretty', {}, output_stream], ['junit', {}, 'result.xml']] + end + end - it 'stores tag limits separately' do - after_parsing(['--tags', 'not @foo:2 or @bar:3']) do - expect(options[:tag_limits]).to eq({ '@foo' => 2, '@bar' => 3 }) - end - end + context 'when using -t TAGS or --tags TAGS' do + it 'handles tag expressions as argument' do + after_parsing(['--tags', 'not @foo or @bar']) do + expect(options[:tag_expressions]).to eq(['not @foo or @bar']) + end + end - it 'raise exception for inconsistent tag limits' do - expect { after_parsing('--tags @foo:2 --tags @foo:3') }.to raise_error(RuntimeError, 'Inconsistent tag limits for @foo: 2 and 3') - end + it 'stores tags passed with different --tags separately' do + after_parsing('--tags @foo --tags @bar') do + expect(options[:tag_expressions]).to eq(['@foo', '@bar']) end + end - context 'when using -n NAME or --name NAME' do - it 'stores the provided names as regular expressions' do - after_parsing('-n foo --name bar') do - expect(options[:name_regexps]).to eq([/foo/, /bar/]) - end - end + it 'strips tag limits from the tag expressions stored' do + after_parsing(['--tags', 'not @foo:2 or @bar:3']) do + expect(options[:tag_expressions]).to eq(['not @foo or @bar']) end + end - context 'when using -e PATTERN or --exclude PATTERN' do - it 'stores the provided exclusions as regular expressions' do - after_parsing('-e foo --exclude bar') do - expect(options[:excludes]).to eq([/foo/, /bar/]) - end - end + it 'stores tag limits separately' do + after_parsing(['--tags', 'not @foo:2 or @bar:3']) do + expect(options[:tag_limits]).to eq({ '@foo' => 2, '@bar' => 3 }) end + end - context 'when using -l LINES or --lines LINES' do - it 'adds line numbers to args' do - options.parse!(%w[-l24 FILE]) + it 'raise exception for inconsistent tag limits' do + expect { after_parsing('--tags @foo:2 --tags @foo:3') }.to raise_error(RuntimeError, 'Inconsistent tag limits for @foo: 2 and 3') + end + end - expect(options.instance_variable_get(:@args)).to eq(['FILE:24']) - end + context 'when using -n NAME or --name NAME' do + it 'stores the provided names as regular expressions' do + after_parsing('-n foo --name bar') do + expect(options[:name_regexps]).to eq([/foo/, /bar/]) end + end + end - context 'when using -p PROFILE or --profile PROFILE' do - it 'uses the default profile passed in during initialization if none are specified by the user' do - given_cucumber_yml_defined_as('default' => '--require some_file') - options = described_class.new(output_stream, error_stream, default_profile: 'default') - options.parse!(%w[--format progress]) - - expect(options[:require]).to include('some_file') - end + context 'when using -e PATTERN or --exclude PATTERN' do + it 'stores the provided exclusions as regular expressions' do + after_parsing('-e foo --exclude bar') do + expect(options[:excludes]).to eq([/foo/, /bar/]) + end + end + end - it 'merges all uniq values from both cmd line and the profile' do - given_cucumber_yml_defined_as('foo' => %w[--verbose]) - options.parse!(%w[--wip --profile foo]) + context 'when using -l LINES or --lines LINES' do + it 'adds line numbers to args' do + options.parse!(%w[-l24 FILE]) - expect(options[:wip]).to be true - expect(options[:verbose]).to be true - end + expect(options.instance_variable_get(:@args)).to eq(['FILE:24']) + end + end - it "gives precedence to the original options' paths" do - given_cucumber_yml_defined_as('foo' => %w[features]) - options.parse!(%w[my.feature -p foo]) + context 'when using -p PROFILE or --profile PROFILE' do + it 'uses the default profile passed in during initialization if none are specified by the user' do + given_cucumber_yml_defined_as('default' => '--require some_file') + options = described_class.new(output_stream, error_stream, default_profile: 'default') + options.parse!(%w[--format progress]) - expect(options[:paths]).to eq(%w[my.feature]) - end + expect(options[:require]).to include('some_file') + end - it 'combines the require files of both' do - given_cucumber_yml_defined_as('bar' => %w[--require features -r dog.rb]) - options.parse!(%w[--require foo.rb -p bar]) + it 'merges all uniq values from both cmd line and the profile' do + given_cucumber_yml_defined_as('foo' => %w[--verbose]) + options.parse!(%w[--wip --profile foo]) - expect(options[:require]).to eq(%w[foo.rb features dog.rb]) - end + expect(options[:wip]).to be true + expect(options[:verbose]).to be true + end - it 'combines the tag names of both' do - given_cucumber_yml_defined_as('baz' => %w[-t @bar]) - options.parse!(%w[--tags @foo -p baz]) + it "gives precedence to the original options' paths" do + given_cucumber_yml_defined_as('foo' => %w[features]) + options.parse!(%w[my.feature -p foo]) - expect(options[:tag_expressions]).to eq(['@foo', '@bar']) - end + expect(options[:paths]).to eq(%w[my.feature]) + end - it 'combines the tag limits of both' do - given_cucumber_yml_defined_as('baz' => %w[-t @bar:2]) - options.parse!(%w[--tags @foo:3 -p baz]) + it 'combines the require files of both' do + given_cucumber_yml_defined_as('bar' => %w[--require features -r dog.rb]) + options.parse!(%w[--require foo.rb -p bar]) - expect(options[:tag_limits]).to eq({ '@foo' => 3, '@bar' => 2 }) - end + expect(options[:require]).to eq(%w[foo.rb features dog.rb]) + end - it 'raise exceptions for inconsistent tag limits' do - given_cucumber_yml_defined_as('baz' => %w[-t @bar:2]) + it 'combines the tag names of both' do + given_cucumber_yml_defined_as('baz' => %w[-t @bar]) + options.parse!(%w[--tags @foo -p baz]) - expect { options.parse!(%w[--tags @bar:3 -p baz]) }.to raise_error(RuntimeError, 'Inconsistent tag limits for @bar: 3 and 2') - end + expect(options[:tag_expressions]).to eq(['@foo', '@bar']) + end - it 'only takes the paths from the original options, and disgregards the profiles' do - given_cucumber_yml_defined_as('baz' => %w[features]) - options.parse!(%w[my.feature -p baz]) + it 'combines the tag limits of both' do + given_cucumber_yml_defined_as('baz' => %w[-t @bar:2]) + options.parse!(%w[--tags @foo:3 -p baz]) - expect(options[:paths]).to eq(['my.feature']) - end + expect(options[:tag_limits]).to eq({ '@foo' => 3, '@bar' => 2 }) + end - it 'uses the paths from the profile when none are specified originally' do - given_cucumber_yml_defined_as('baz' => %w[some.feature]) - options.parse!(%w[-p baz]) + it 'raise exceptions for inconsistent tag limits' do + given_cucumber_yml_defined_as('baz' => %w[-t @bar:2]) - expect(options[:paths]).to eq(['some.feature']) - end + expect { options.parse!(%w[--tags @bar:3 -p baz]) }.to raise_error(RuntimeError, 'Inconsistent tag limits for @bar: 3 and 2') + end - it 'combines environment variables from the profile but gives precendene to cmd line args' do - given_cucumber_yml_defined_as('baz' => %w[FOO=bar CHEESE=swiss]) - options.parse!(%w[-p baz CHEESE=cheddar BAR=foo]) + it 'only takes the paths from the original options, and disgregards the profiles' do + given_cucumber_yml_defined_as('baz' => %w[features]) + options.parse!(%w[my.feature -p baz]) - expect(options[:env_vars]).to eq('BAR' => 'foo', 'FOO' => 'bar', 'CHEESE' => 'cheddar') - end + expect(options[:paths]).to eq(['my.feature']) + end - it 'disregards STDOUT formatter defined in profile when another is passed in (via cmd line)' do - given_cucumber_yml_defined_as('foo' => %w[--format pretty]) - options.parse!(%w[--format progress --profile foo]) + it 'uses the paths from the profile when none are specified originally' do + given_cucumber_yml_defined_as('baz' => %w[some.feature]) + options.parse!(%w[-p baz]) - expect(options[:formats]).to eq([['progress', {}, output_stream]]) - end + expect(options[:paths]).to eq(['some.feature']) + end - it 'includes any non-STDOUT formatters from the profile' do - given_cucumber_yml_defined_as('json' => %w[--format json -o features.json]) - options.parse!(%w[--format progress --profile json]) + it 'combines environment variables from the profile but gives precendene to cmd line args' do + given_cucumber_yml_defined_as('baz' => %w[FOO=bar CHEESE=swiss]) + options.parse!(%w[-p baz CHEESE=cheddar BAR=foo]) - expect(options[:formats]).to eq([['progress', {}, output_stream], ['json', {}, 'features.json']]) - end + expect(options[:env_vars]).to eq('BAR' => 'foo', 'FOO' => 'bar', 'CHEESE' => 'cheddar') + end - it 'does not include STDOUT formatters from the profile if there is a STDOUT formatter in command line' do - given_cucumber_yml_defined_as('json' => %w[--format json -o features.json --format pretty]) - options.parse!(%w[--format progress --profile json]) + it 'disregards STDOUT formatter defined in profile when another is passed in (via cmd line)' do + given_cucumber_yml_defined_as('foo' => %w[--format pretty]) + options.parse!(%w[--format progress --profile foo]) - expect(options[:formats]).to eq([['progress', {}, output_stream], ['json', {}, 'features.json']]) - end + expect(options[:formats]).to eq([['progress', {}, output_stream]]) + end - it 'includes any STDOUT formatters from the profile if no STDOUT formatter was specified in command line' do - given_cucumber_yml_defined_as('json' => %w[--format json]) - options.parse!(%w[--format rerun -o rerun.txt --profile json]) + it 'includes any non-STDOUT formatters from the profile' do + given_cucumber_yml_defined_as('json' => %w[--format json -o features.json]) + options.parse!(%w[--format progress --profile json]) - expect(options[:formats]).to eq([['json', {}, output_stream], ['rerun', {}, 'rerun.txt']]) - end + expect(options[:formats]).to eq([['progress', {}, output_stream], ['json', {}, 'features.json']]) + end - it 'assumes all of the formatters defined in the profile when none are specified on cmd line' do - given_cucumber_yml_defined_as('json' => %w[--format progress --format json -o features.json]) - options.parse!(%w[--profile json]) + it 'does not include STDOUT formatters from the profile if there is a STDOUT formatter in command line' do + given_cucumber_yml_defined_as('json' => %w[--format json -o features.json --format pretty]) + options.parse!(%w[--format progress --profile json]) - expect(options[:formats]).to eq([['progress', {}, output_stream], ['json', {}, 'features.json']]) - end + expect(options[:formats]).to eq([['progress', {}, output_stream], ['json', {}, 'features.json']]) + end - it 'only reads cucumber.yml once' do - original_parse_count = $cucumber_yml_read_count - $cucumber_yml_read_count = 0 - - begin - given_cucumber_yml_defined_as(<<-YML - <% $cucumber_yml_read_count += 1 %> - default: --format pretty - YML - ) - options = described_class.new(output_stream, error_stream, default_profile: 'default') - options.parse!(%w[-f progress]) - - expect($cucumber_yml_read_count).to eq 1 - ensure - $cucumber_yml_read_count = original_parse_count - end - end + it 'includes any STDOUT formatters from the profile if no STDOUT formatter was specified in command line' do + given_cucumber_yml_defined_as('json' => %w[--format json]) + options.parse!(%w[--format rerun -o rerun.txt --profile json]) - it 'respects --quiet when defined in the profile' do - given_cucumber_yml_defined_as('foo' => '-q') - options.parse!(%w[-p foo]) + expect(options[:formats]).to eq([['json', {}, output_stream], ['rerun', {}, 'rerun.txt']]) + end - expect(options[:publish_quiet]).to be true - end + it 'assumes all of the formatters defined in the profile when none are specified on cmd line' do + given_cucumber_yml_defined_as('json' => %w[--format progress --format json -o features.json]) + options.parse!(%w[--profile json]) - it 'uses --no-duration when defined in the profile' do - given_cucumber_yml_defined_as('foo' => '--no-duration') - options.parse!(%w[-p foo]) + expect(options[:formats]).to eq([['progress', {}, output_stream], ['json', {}, 'features.json']]) + end - expect(options[:duration]).to be false - end + it 'only reads cucumber.yml once' do + original_parse_count = $cucumber_yml_read_count + $cucumber_yml_read_count = 0 + + begin + given_cucumber_yml_defined_as(<<-YML + <% $cucumber_yml_read_count += 1 %> + default: --format pretty + YML + ) + options = described_class.new(output_stream, error_stream, default_profile: 'default') + options.parse!(%w[-f progress]) + + expect($cucumber_yml_read_count).to eq 1 + ensure + $cucumber_yml_read_count = original_parse_count + end + end - context 'with --retry' do - context 'when --retry is not defined on the command line' do - it 'uses the --retry option from the profile' do - given_cucumber_yml_defined_as('foo' => '--retry 2') - options.parse!(%w[-p foo]) + it 'respects --quiet when defined in the profile' do + given_cucumber_yml_defined_as('foo' => '-q') + options.parse!(%w[-p foo]) - expect(options[:retry]).to eq(2) - end - end + expect(options[:publish_quiet]).to be true + end - context 'when --retry is defined on the command line' do - it 'ignores the --retry option from the profile' do - given_cucumber_yml_defined_as('foo' => '--retry 2') - options.parse!(%w[--retry 1 -p foo]) + it 'uses --no-duration when defined in the profile' do + given_cucumber_yml_defined_as('foo' => '--no-duration') + options.parse!(%w[-p foo]) - expect(options[:retry]).to eq(1) - end - end - end + expect(options[:duration]).to be false + end - context 'with --retry-total' do - context 'when --retry-total is not defined on the command line' do - it 'uses the --retry-total option from the profile' do - given_cucumber_yml_defined_as('foo' => '--retry-total 2') - options.parse!(%w[-p foo]) + context 'with --retry' do + context 'when --retry is not defined on the command line' do + it 'uses the --retry option from the profile' do + given_cucumber_yml_defined_as('foo' => '--retry 2') + options.parse!(%w[-p foo]) - expect(options[:retry_total]).to eq(2) - end - end + expect(options[:retry]).to eq(2) + end + end - context 'when --retry-total is defined on the command line' do - it 'ignores the --retry-total option from the profile' do - given_cucumber_yml_defined_as('foo' => '--retry-total 2') - options.parse!(%w[--retry-total 1 -p foo]) + context 'when --retry is defined on the command line' do + it 'ignores the --retry option from the profile' do + given_cucumber_yml_defined_as('foo' => '--retry 2') + options.parse!(%w[--retry 1 -p foo]) - expect(options[:retry_total]).to eq(1) - end - end + expect(options[:retry]).to eq(1) end end + end - context 'when using -P or --no-profile' do - it 'disables profiles' do - given_cucumber_yml_defined_as('default' => '-v --require file_specified_in_default_profile.rb') + context 'with --retry-total' do + context 'when --retry-total is not defined on the command line' do + it 'uses the --retry-total option from the profile' do + given_cucumber_yml_defined_as('foo' => '--retry-total 2') + options.parse!(%w[-p foo]) - after_parsing('-P --require some_file.rb') do - expect(options[:require]).to eq(['some_file.rb']) - end + expect(options[:retry_total]).to eq(2) end + end - it 'notifies the user that the profiles are being disabled' do - given_cucumber_yml_defined_as('default' => '-v') + context 'when --retry-total is defined on the command line' do + it 'ignores the --retry-total option from the profile' do + given_cucumber_yml_defined_as('foo' => '--retry-total 2') + options.parse!(%w[--retry-total 1 -p foo]) - after_parsing('--no-profile --require some_file.rb') do - expect(output_stream.string).to match(/Disabling profiles.../) - end + expect(options[:retry_total]).to eq(1) end end + end + end - context 'when using -b or --backtrace' do - it "turns on cucumber's full backtrace" do - when_parsing('-b') do - expect(Cucumber).to receive(:use_full_backtrace=).with(true) - end - end + context 'when using -P or --no-profile' do + it 'disables profiles' do + given_cucumber_yml_defined_as('default' => '-v --require file_specified_in_default_profile.rb') + + after_parsing('-P --require some_file.rb') do + expect(options[:require]).to eq(['some_file.rb']) end + end - context 'with --version' do - it "displays the cucumber version" do - after_parsing('--version') do - expect(output_stream.string).to match(/#{Cucumber::VERSION}/) - end - end + it 'notifies the user that the profiles are being disabled' do + given_cucumber_yml_defined_as('default' => '-v') - it 'exits the program' do - when_parsing('--version') { expect(Kernel).to receive(:exit) } - end + after_parsing('--no-profile --require some_file.rb') do + expect(output_stream.string).to match(/Disabling profiles.../) end + end + end - context 'when using environment variables (i.e. MODE=webrat)' do - it 'places all of the environment variables into a hash' do - after_parsing('MODE=webrat FOO=bar') do - expect(options[:env_vars]).to eq('MODE' => 'webrat', 'FOO' => 'bar') - end - end + context 'when using -b or --backtrace' do + it "turns on cucumber's full backtrace" do + when_parsing('-b') do + expect(Cucumber).to receive(:use_full_backtrace=).with(true) end + end + end - context 'with --retry' do - it 'is 0 by default' do - after_parsing('') do - expect(options[:retry]).to eq(0) - end - end + context 'with --version' do + it "displays the cucumber version" do + after_parsing('--version') do + expect(output_stream.string).to match(/#{Cucumber::VERSION}/) + end + end - it 'sets the options[:retry] value' do - after_parsing('--retry 4') do - expect(options[:retry]).to eq(4) - end - end + it 'exits the program' do + when_parsing('--version') { expect(Kernel).to receive(:exit) } + end + end + + context 'when using environment variables (i.e. MODE=webrat)' do + it 'places all of the environment variables into a hash' do + after_parsing('MODE=webrat FOO=bar') do + expect(options[:env_vars]).to eq('MODE' => 'webrat', 'FOO' => 'bar') end + end + end - context 'with --retry-total' do - it 'is INFINITY by default' do - after_parsing('') do - expect(options[:retry_total]).to eq(Float::INFINITY) - end - end + context 'with --retry' do + it 'is 0 by default' do + after_parsing('') do + expect(options[:retry]).to eq(0) + end + end - it 'sets the options[:retry_total] value' do - after_parsing('--retry-total 10') do - expect(options[:retry_total]).to eq(10) - end - end + it 'sets the options[:retry] value' do + after_parsing('--retry 4') do + expect(options[:retry]).to eq(4) end + end + end - it 'assigns any extra arguments as paths to features' do - after_parsing('-f pretty my_feature.feature my_other_features') do - expect(options[:paths]).to eq(['my_feature.feature', 'my_other_features']) - end + context 'with --retry-total' do + it 'is INFINITY by default' do + after_parsing('') do + expect(options[:retry_total]).to eq(Float::INFINITY) end + end - it 'does not mistake environment variables as feature paths' do - after_parsing('my_feature.feature FOO=bar') do - expect(options[:paths]).to eq(['my_feature.feature']) - end + it 'sets the options[:retry_total] value' do + after_parsing('--retry-total 10') do + expect(options[:retry_total]).to eq(10) end + end + end - context 'with --snippet-type' do - it 'parses the snippet type argument' do - after_parsing('--snippet-type classic') do - expect(options[:snippet_type]).to eq(:classic) - end - end + it 'assigns any extra arguments as paths to features' do + after_parsing('-f pretty my_feature.feature my_other_features') do + expect(options[:paths]).to eq(['my_feature.feature', 'my_other_features']) + end + end + + it 'does not mistake environment variables as feature paths' do + after_parsing('my_feature.feature FOO=bar') do + expect(options[:paths]).to eq(['my_feature.feature']) + end + end + + context 'with --snippet-type' do + it 'parses the snippet type argument' do + after_parsing('--snippet-type classic') do + expect(options[:snippet_type]).to eq(:classic) end + end + end - context 'with --publish' do - it 'adds message formatter with output to default reports publishing url' do - after_parsing('--publish') do - expect(@options[:formats]).to include(['message', {}, Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL]) - end - end + context 'with --publish' do + it 'adds message formatter with output to default reports publishing url' do + after_parsing('--publish') do + expect(@options[:formats]).to include(['message', {}, Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL]) + end + end - it 'adds message formatter with output to default reports publishing url when CUCUMBER_PUBLISH_ENABLED=true' do - with_env('CUCUMBER_PUBLISH_ENABLED', 'true') do - after_parsing('') do - expect(@options[:formats]).to include(['message', {}, Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL]) - end - end + it 'adds message formatter with output to default reports publishing url when CUCUMBER_PUBLISH_ENABLED=true' do + with_env('CUCUMBER_PUBLISH_ENABLED', 'true') do + after_parsing('') do + expect(@options[:formats]).to include(['message', {}, Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL]) end + end + end - it 'enables publishing when CUCUMBER_PUBLISH_ENABLED=true' do - with_env('CUCUMBER_PUBLISH_ENABLED', 'true') do - after_parsing('') do - expect(@options[:publish_enabled]).to be true - end - end + it 'enables publishing when CUCUMBER_PUBLISH_ENABLED=true' do + with_env('CUCUMBER_PUBLISH_ENABLED', 'true') do + after_parsing('') do + expect(@options[:publish_enabled]).to be true end + end + end - it 'does not enable publishing when CUCUMBER_PUBLISH_ENABLED=false' do - with_env('CUCUMBER_PUBLISH_ENABLED', 'false') do - after_parsing('') do - expect(@options[:publish_enabled]).to be nil - end - end + it 'does not enable publishing when CUCUMBER_PUBLISH_ENABLED=false' do + with_env('CUCUMBER_PUBLISH_ENABLED', 'false') do + after_parsing('') do + expect(@options[:publish_enabled]).to be nil end + end + end - it 'adds authentication header with CUCUMBER_PUBLISH_TOKEN environment variable value if set' do - with_env('CUCUMBER_PUBLISH_TOKEN', 'abcd1234') do - after_parsing('--publish') do - expect(@options[:formats]).to include(['message', {}, %(#{Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL} -H "Authorization: Bearer abcd1234")]) - end - end + it 'adds authentication header with CUCUMBER_PUBLISH_TOKEN environment variable value if set' do + with_env('CUCUMBER_PUBLISH_TOKEN', 'abcd1234') do + after_parsing('--publish') do + expect(@options[:formats]).to include(['message', {}, %(#{Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL} -H "Authorization: Bearer abcd1234")]) end + end + end - it 'enables publishing if CUCUMBER_PUBLISH_TOKEN environment variable is set' do - with_env('CUCUMBER_PUBLISH_TOKEN', 'abcd1234') do - after_parsing('--publish') do - expect(@options[:publish_enabled]).to be true - end - end + it 'enables publishing if CUCUMBER_PUBLISH_TOKEN environment variable is set' do + with_env('CUCUMBER_PUBLISH_TOKEN', 'abcd1234') do + after_parsing('--publish') do + expect(@options[:publish_enabled]).to be true end + end + end - it 'adds authentication header with CUCUMBER_PUBLISH_TOKEN environment variable value if set and no --publish' do - with_env('CUCUMBER_PUBLISH_TOKEN', 'abcd1234') do - after_parsing('') do - expect(@options[:formats]).to include(['message', {}, %(#{Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL} -H "Authorization: Bearer abcd1234")]) - end - end + it 'adds authentication header with CUCUMBER_PUBLISH_TOKEN environment variable value if set and no --publish' do + with_env('CUCUMBER_PUBLISH_TOKEN', 'abcd1234') do + after_parsing('') do + expect(@options[:formats]).to include(['message', {}, %(#{Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL} -H "Authorization: Bearer abcd1234")]) end end + end + end - context 'with --publish-quiet' do - it 'silences publish banner' do - after_parsing('--publish-quiet') do - expect(@options[:publish_quiet]).to be true - end - end + context 'with --publish-quiet' do + it 'silences publish banner' do + after_parsing('--publish-quiet') do + expect(@options[:publish_quiet]).to be true + end + end - it 'enables publishing when CUCUMBER_PUBLISH_QUIET=true' do - with_env('CUCUMBER_PUBLISH_QUIET', 'true') do - after_parsing('') do - expect(@options[:publish_quiet]).to be true - end - end + it 'enables publishing when CUCUMBER_PUBLISH_QUIET=true' do + with_env('CUCUMBER_PUBLISH_QUIET', 'true') do + after_parsing('') do + expect(@options[:publish_quiet]).to be true end end end + end + end - describe 'dry-run' do - it 'has the default value for snippets' do - given_cucumber_yml_defined_as('foo' => %w[--dry-run]) - options.parse!(%w[--dry-run]) + describe 'dry-run' do + it 'has the default value for snippets' do + given_cucumber_yml_defined_as('foo' => %w[--dry-run]) + options.parse!(%w[--dry-run]) - expect(options[:snippets]).to be true - end + expect(options[:snippets]).to be true + end - it 'sets snippets to false when no-snippets provided after dry-run' do - given_cucumber_yml_defined_as('foo' => %w[--dry-run --no-snippets]) - options.parse!(%w[--dry-run --no-snippets]) + it 'sets snippets to false when no-snippets provided after dry-run' do + given_cucumber_yml_defined_as('foo' => %w[--dry-run --no-snippets]) + options.parse!(%w[--dry-run --no-snippets]) - expect(options[:snippets]).to be false - end + expect(options[:snippets]).to be false + end - it 'sets snippets to false when no-snippets provided before dry-run' do - given_cucumber_yml_defined_as('foo' => %w[--no-snippet --dry-run]) - options.parse!(%w[--no-snippets --dry-run]) + it 'sets snippets to false when no-snippets provided before dry-run' do + given_cucumber_yml_defined_as('foo' => %w[--no-snippet --dry-run]) + options.parse!(%w[--no-snippets --dry-run]) - expect(options[:snippets]).to be false - end - end + expect(options[:snippets]).to be false end end end diff --git a/spec/cucumber/cli/profile_loader_spec.rb b/spec/cucumber/cli/profile_loader_spec.rb index 69d04d979..1b39600cb 100644 --- a/spec/cucumber/cli/profile_loader_spec.rb +++ b/spec/cucumber/cli/profile_loader_spec.rb @@ -1,95 +1,90 @@ # frozen_string_literal: true -require 'spec_helper' require 'yaml' -module Cucumber - module Cli - describe ProfileLoader do - subject(:loader) { described_class.new } +describe Cucumber::Cli::ProfileLoader do + subject(:loader) { described_class.new } - def given_cucumber_yml_defined_as(hash_or_string) - allow(Dir).to receive(:glob).with('{,.config/,config/}cucumber{.yml,.yaml}').and_return(['cucumber.yml']) - allow(File).to receive(:exist?).and_return(true) - cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string - allow(IO).to receive(:read).with('cucumber.yml') { cucumber_yml } - end + def given_cucumber_yml_defined_as(hash_or_string) + allow(Dir).to receive(:glob).with('{,.config/,config/}cucumber{.yml,.yaml}').and_return(['cucumber.yml']) + allow(File).to receive(:exist?).and_return(true) + cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string + allow(IO).to receive(:read).with('cucumber.yml') { cucumber_yml } + end - context 'when on a Windows OS' do - before { skip('These tests are only to be ran on Windows') unless Cucumber::WINDOWS } + context 'when on a Windows OS' do + before { skip('These tests are only to be ran on Windows') unless Cucumber::WINDOWS } - it 'treats backslashes as literals in rerun.txt when on Windows (JRuby or MRI)' do - given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22') + it 'treats backslashes as literals in rerun.txt when on Windows (JRuby or MRI)' do + given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22') - expect(loader.args_from('default')).to eq(%w[--format pretty features\sync_imap_mailbox.feature:16:22]) - end + expect(loader.args_from('default')).to eq(%w[--format pretty features\sync_imap_mailbox.feature:16:22]) + end - it 'treats forward slashes as literals' do - given_cucumber_yml_defined_as('default' => '--format "ugly" features/sync_imap_mailbox.feature:16:22') + it 'treats forward slashes as literals' do + given_cucumber_yml_defined_as('default' => '--format "ugly" features/sync_imap_mailbox.feature:16:22') - expect(loader.args_from('default')).to eq(%w[--format ugly features/sync_imap_mailbox.feature:16:22]) - end + expect(loader.args_from('default')).to eq(%w[--format ugly features/sync_imap_mailbox.feature:16:22]) + end - it 'treats percent sign as ERB code block after YAML directive' do - yml = <<~HERE - --- - % x = '--format "pretty" features/sync_imap_mailbox.feature:16:22' - default: <%= x %> - HERE - given_cucumber_yml_defined_as yml - expect(loader.args_from('default')).to eq(%w[--format pretty features/sync_imap_mailbox.feature:16:22]) - end + it 'treats percent sign as ERB code block after YAML directive' do + yml = <<~HERE + --- + % x = '--format "pretty" features/sync_imap_mailbox.feature:16:22' + default: <%= x %> + HERE + given_cucumber_yml_defined_as yml + expect(loader.args_from('default')).to eq(%w[--format pretty features/sync_imap_mailbox.feature:16:22]) + end - it 'correctly parses a profile that uses tag expressions (with double quotes)' do - given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22 --tags "not @jruby"') + it 'correctly parses a profile that uses tag expressions (with double quotes)' do + given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22 --tags "not @jruby"') - expect(loader.args_from('default')).to eq(['--format', 'pretty', 'features\sync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) - end + expect(loader.args_from('default')).to eq(['--format', 'pretty', 'features\sync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) + end - it 'correctly parses a profile that uses tag expressions (with single quotes)' do - given_cucumber_yml_defined_as('default' => "--format 'pretty' features\\sync_imap_mailbox.feature:16:22 --tags 'not @jruby'") + it 'correctly parses a profile that uses tag expressions (with single quotes)' do + given_cucumber_yml_defined_as('default' => "--format 'pretty' features\\sync_imap_mailbox.feature:16:22 --tags 'not @jruby'") - expect(loader.args_from('default')).to eq(['--format', 'pretty', 'features\sync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) - end - end + expect(loader.args_from('default')).to eq(['--format', 'pretty', 'features\sync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) + end + end - context 'when on non-Windows OS' do - before { skip('These tests are only to be ran on a "Non-Windows" OS') if Cucumber::WINDOWS } + context 'when on non-Windows OS' do + before { skip('These tests are only to be ran on a "Non-Windows" OS') if Cucumber::WINDOWS } - it 'treats backslashes as literals in rerun.txt when on Windows (JRuby or MRI)' do - given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22') + it 'treats backslashes as literals in rerun.txt when on Windows (JRuby or MRI)' do + given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22') - expect(loader.args_from('default')).to eq(['--format', 'pretty', 'featuressync_imap_mailbox.feature:16:22']) - end + expect(loader.args_from('default')).to eq(['--format', 'pretty', 'featuressync_imap_mailbox.feature:16:22']) + end - it 'treats forward slashes as literals' do - given_cucumber_yml_defined_as('default' => '--format "ugly" features/sync_imap_mailbox.feature:16:22') + it 'treats forward slashes as literals' do + given_cucumber_yml_defined_as('default' => '--format "ugly" features/sync_imap_mailbox.feature:16:22') - expect(loader.args_from('default')).to eq ['--format', 'ugly', 'features/sync_imap_mailbox.feature:16:22'] - end + expect(loader.args_from('default')).to eq ['--format', 'ugly', 'features/sync_imap_mailbox.feature:16:22'] + end - it 'treats percent sign as ERB code block after YAML directive' do - yml = <<~HERE - --- - % x = '--format "pretty" features/sync_imap_mailbox.feature:16:22' - default: <%= x %> - HERE - given_cucumber_yml_defined_as yml - expect(loader.args_from('default')).to eq ['--format', 'pretty', 'features/sync_imap_mailbox.feature:16:22'] - end + it 'treats percent sign as ERB code block after YAML directive' do + yml = <<~HERE + --- + % x = '--format "pretty" features/sync_imap_mailbox.feature:16:22' + default: <%= x %> + HERE + given_cucumber_yml_defined_as yml + expect(loader.args_from('default')).to eq ['--format', 'pretty', 'features/sync_imap_mailbox.feature:16:22'] + end - it 'correctly parses a profile that uses tag expressions (with double quotes)' do - given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22 --tags "not @jruby"') + it 'correctly parses a profile that uses tag expressions (with double quotes)' do + given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22 --tags "not @jruby"') - expect(loader.args_from('default')).to eq(['--format', 'pretty', 'featuressync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) - end + expect(loader.args_from('default')).to eq(['--format', 'pretty', 'featuressync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) + end - it 'correctly parses a profile that uses tag expressions (with single quotes)' do - given_cucumber_yml_defined_as('default' => "--format 'pretty' features\\sync_imap_mailbox.feature:16:22 --tags 'not @jruby'") + it 'correctly parses a profile that uses tag expressions (with single quotes)' do + given_cucumber_yml_defined_as('default' => "--format 'pretty' features\\sync_imap_mailbox.feature:16:22 --tags 'not @jruby'") - expect(loader.args_from('default')).to eq(['--format', 'pretty', 'featuressync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) - end - end + expect(loader.args_from('default')).to eq(['--format', 'pretty', 'featuressync_imap_mailbox.feature:16:22', '--tags', 'not @jruby']) end end end diff --git a/spec/cucumber/cli/rerun_spec.rb b/spec/cucumber/cli/rerun_spec.rb index bb72a2cd3..af4f46f7e 100644 --- a/spec/cucumber/cli/rerun_spec.rb +++ b/spec/cucumber/cli/rerun_spec.rb @@ -1,86 +1,80 @@ # frozen_string_literal: true -require 'spec_helper' - -module Cucumber - module Cli - describe RerunFile do - let(:rerun_file) { described_class.new('@rerun.txt') } - - it 'expects rerun files to have a leading @' do - allow(File).to receive(:file?).and_return(true) - expect(described_class.can_read?('rerun.txt')).to eq false - expect(described_class.can_read?('@rerun.txt')).to eq true - end - - it 'does not treat directories as rerun files' do - allow(File).to receive(:file?).and_return(false) - expect(described_class.can_read?('@rerun.txt')).to eq false - end - - it 'removes leading @ character from filename' do - expect(rerun_file.path).to eq 'rerun.txt' - end - - context 'with a rerun file containing a single feature reference' do - before(:each) do - allow(IO).to receive(:read).and_return('cucumber.feature') - end - - it 'produces an array containing a single feature file path' do - expect(rerun_file.features).to eq %w[cucumber.feature] - end - end - - context 'with a rerun file containing multiple feature references on multiple lines' do - before(:each) do - allow(IO).to receive(:read).and_return("cucumber.feature\nfoo.feature") - end - - it 'produces an array containing multiple feature file paths' do - expect(rerun_file.features).to eq %w[cucumber.feature foo.feature] - end - end - - context 'with a rerun file containing multiple feature references on the same line' do - before(:each) do - allow(IO).to receive(:read).and_return('cucumber.feature foo.feature') - end - - it 'produces an array containing multiple feature file paths' do - expect(rerun_file.features).to eq %w[cucumber.feature foo.feature] - end - end - - context 'with a rerun file containing multiple scenario references on the same line' do - before(:each) do - allow(IO).to receive(:read).and_return('cucumber.feature:8 foo.feature:8:16') - end - - it 'produces an array containing multiple feature file paths with scenario lines' do - expect(rerun_file.features).to eq %w[cucumber.feature:8 foo.feature:8:16] - end - end - - context 'with a rerun file containing multiple feature references with spaces in file names' do - before(:each) do - allow(IO).to receive(:read).and_return('cucumber test.feature:8 foo.feature:8:16') - end - - it 'produces an array containing multiple feature file paths with scenario lines' do - expect(rerun_file.features).to eq ['cucumber test.feature:8', 'foo.feature:8:16'] - end - end - - context 'with a rerun file containing multiple scenario references without spaces in between them' do - before(:each) do - allow(IO).to receive(:read).and_return('cucumber test.feature:8foo.feature:8:16') - end - - it 'produces an array containing multiple feature file paths with scenario lines' do - expect(rerun_file.features).to eq ['cucumber test.feature:8', 'foo.feature:8:16'] - end - end +describe Cucumber::Cli::RerunFile do + let(:rerun_file) { described_class.new('@rerun.txt') } + + it 'expects rerun files to have a leading @' do + allow(File).to receive(:file?).and_return(true) + expect(described_class.can_read?('rerun.txt')).to eq false + expect(described_class.can_read?('@rerun.txt')).to eq true + end + + it 'does not treat directories as rerun files' do + allow(File).to receive(:file?).and_return(false) + expect(described_class.can_read?('@rerun.txt')).to eq false + end + + it 'removes leading @ character from filename' do + expect(rerun_file.path).to eq 'rerun.txt' + end + + context 'with a rerun file containing a single feature reference' do + before(:each) do + allow(IO).to receive(:read).and_return('cucumber.feature') + end + + it 'produces an array containing a single feature file path' do + expect(rerun_file.features).to eq %w[cucumber.feature] + end + end + + context 'with a rerun file containing multiple feature references on multiple lines' do + before(:each) do + allow(IO).to receive(:read).and_return("cucumber.feature\nfoo.feature") + end + + it 'produces an array containing multiple feature file paths' do + expect(rerun_file.features).to eq %w[cucumber.feature foo.feature] + end + end + + context 'with a rerun file containing multiple feature references on the same line' do + before(:each) do + allow(IO).to receive(:read).and_return('cucumber.feature foo.feature') + end + + it 'produces an array containing multiple feature file paths' do + expect(rerun_file.features).to eq %w[cucumber.feature foo.feature] + end + end + + context 'with a rerun file containing multiple scenario references on the same line' do + before(:each) do + allow(IO).to receive(:read).and_return('cucumber.feature:8 foo.feature:8:16') + end + + it 'produces an array containing multiple feature file paths with scenario lines' do + expect(rerun_file.features).to eq %w[cucumber.feature:8 foo.feature:8:16] + end + end + + context 'with a rerun file containing multiple feature references with spaces in file names' do + before(:each) do + allow(IO).to receive(:read).and_return('cucumber test.feature:8 foo.feature:8:16') + end + + it 'produces an array containing multiple feature file paths with scenario lines' do + expect(rerun_file.features).to eq ['cucumber test.feature:8', 'foo.feature:8:16'] + end + end + + context 'with a rerun file containing multiple scenario references without spaces in between them' do + before(:each) do + allow(IO).to receive(:read).and_return('cucumber test.feature:8foo.feature:8:16') + end + + it 'produces an array containing multiple feature file paths with scenario lines' do + expect(rerun_file.features).to eq ['cucumber test.feature:8', 'foo.feature:8:16'] end end end From c5428ce57a3a300dc06b2a53480f462871985fdc Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Tue, 17 Mar 2026 23:15:51 +0000 Subject: [PATCH 3/3] Remove a bunch of duplicate redundant requires in specs --- spec/cucumber/formatter/io_http_buffer_spec.rb | 1 - spec/cucumber/formatter/message_spec.rb | 1 - spec/cucumber/formatter/progress_spec.rb | 1 - spec/cucumber/formatter/query/hook_by_test_step_spec.rb | 1 - spec/cucumber/formatter/query/pickle_by_test_spec.rb | 1 - spec/cucumber/formatter/query/pickle_step_by_test_step_spec.rb | 1 - .../formatter/query/step_definitions_by_test_step_spec.rb | 1 - .../formatter/query/test_case_started_by_test_case_spec.rb | 1 - 8 files changed, 8 deletions(-) diff --git a/spec/cucumber/formatter/io_http_buffer_spec.rb b/spec/cucumber/formatter/io_http_buffer_spec.rb index 9b5446eee..0a17466a4 100644 --- a/spec/cucumber/formatter/io_http_buffer_spec.rb +++ b/spec/cucumber/formatter/io_http_buffer_spec.rb @@ -3,7 +3,6 @@ require 'stringio' require 'webrick' require 'webrick/https' -require 'spec_helper' require 'cucumber/formatter/io' require 'support/shared_context/http_server' diff --git a/spec/cucumber/formatter/message_spec.rb b/spec/cucumber/formatter/message_spec.rb index afdb41c32..94b24681e 100644 --- a/spec/cucumber/formatter/message_spec.rb +++ b/spec/cucumber/formatter/message_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/message' require 'cucumber/cli/options' diff --git a/spec/cucumber/formatter/progress_spec.rb b/spec/cucumber/formatter/progress_spec.rb index 5d5f99653..7d5abf0e8 100644 --- a/spec/cucumber/formatter/progress_spec.rb +++ b/spec/cucumber/formatter/progress_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/progress' require 'cucumber/cli/options' diff --git a/spec/cucumber/formatter/query/hook_by_test_step_spec.rb b/spec/cucumber/formatter/query/hook_by_test_step_spec.rb index 8f52e2c16..69aed7a42 100644 --- a/spec/cucumber/formatter/query/hook_by_test_step_spec.rb +++ b/spec/cucumber/formatter/query/hook_by_test_step_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/query/hook_by_test_step' diff --git a/spec/cucumber/formatter/query/pickle_by_test_spec.rb b/spec/cucumber/formatter/query/pickle_by_test_spec.rb index e01fdfc77..f6441ca25 100644 --- a/spec/cucumber/formatter/query/pickle_by_test_spec.rb +++ b/spec/cucumber/formatter/query/pickle_by_test_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/query/pickle_by_test' diff --git a/spec/cucumber/formatter/query/pickle_step_by_test_step_spec.rb b/spec/cucumber/formatter/query/pickle_step_by_test_step_spec.rb index a94e213b7..edfc83176 100644 --- a/spec/cucumber/formatter/query/pickle_step_by_test_step_spec.rb +++ b/spec/cucumber/formatter/query/pickle_step_by_test_step_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/query/pickle_step_by_test_step' diff --git a/spec/cucumber/formatter/query/step_definitions_by_test_step_spec.rb b/spec/cucumber/formatter/query/step_definitions_by_test_step_spec.rb index ebc001a8a..5afe02897 100644 --- a/spec/cucumber/formatter/query/step_definitions_by_test_step_spec.rb +++ b/spec/cucumber/formatter/query/step_definitions_by_test_step_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/query/step_definitions_by_test_step' diff --git a/spec/cucumber/formatter/query/test_case_started_by_test_case_spec.rb b/spec/cucumber/formatter/query/test_case_started_by_test_case_spec.rb index aee22485c..70b42e276 100644 --- a/spec/cucumber/formatter/query/test_case_started_by_test_case_spec.rb +++ b/spec/cucumber/formatter/query/test_case_started_by_test_case_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'spec_helper' require 'cucumber/formatter/spec_helper' require 'cucumber/formatter/query/test_case_started_by_test_case'