class Cucumber::Cli::Options
Constants
- BUILTIN_FORMATS
rubocop:disable Layout/MultilineOperationIndentation
- FAIL_FAST_FLAG
- FORMAT_HELP
- FORMAT_HELP_MSG
- INDENT
- NO_PROFILE_LONG_FLAG
- NO_PROFILE_SHORT_FLAG
- OPTIONS_WITH_ARGS
- ORDER_TYPES
- PROFILE_LONG_FLAG
- PROFILE_SHORT_FLAG
- RETRY_FLAG
- TAG_LIMIT_MATCHER
Attributes
expanded_args[R]
options[R]
profiles[R]
Public Class Methods
new(out_stream = STDOUT, error_stream = STDERR, options = {})
click to toggle source
# File lib/cucumber/cli/options.rb, line 68 def initialize(out_stream = STDOUT, error_stream = STDERR, options = {}) @out_stream = out_stream @error_stream = error_stream @default_profile = options[:default_profile] @profiles = options[:profiles] || [] @overridden_paths = [] @options = default_options.merge(options) @profile_loader = options[:profile_loader] @options[:skip_profile_information] = options[:skip_profile_information] @disable_profile_loading = nil end
parse(args, out_stream, error_stream, options = {})
click to toggle source
# File lib/cucumber/cli/options.rb, line 64 def self.parse(args, out_stream, error_stream, options = {}) new(out_stream, error_stream, options).parse!(args) end
Public Instance Methods
[](key)
click to toggle source
# File lib/cucumber/cli/options.rb, line 82 def [](key) @options[key] end
[]=(key, value)
click to toggle source
# File lib/cucumber/cli/options.rb, line 86 def []=(key, value) @options[key] = value end
check_formatter_stream_conflicts()
click to toggle source
# File lib/cucumber/cli/options.rb, line 174 def check_formatter_stream_conflicts() streams = @options[:formats].uniq.map { |(_, _, stream)| stream } return if streams == streams.uniq raise 'All but one formatter must use --out, only one can print to each stream (or STDOUT)' end
custom_profiles()
click to toggle source
# File lib/cucumber/cli/options.rb, line 166 def custom_profiles @profiles - [@default_profile] end
filters()
click to toggle source
# File lib/cucumber/cli/options.rb, line 170 def filters @options[:filters] ||= [] end
parse!(args)
click to toggle source
# File lib/cucumber/cli/options.rb, line 90 def parse!(args) # rubocop:disable Metrics/AbcSize @args = args @expanded_args = @args.dup @args.extend(::OptionParser::Arguable) @args.options do |opts| opts.banner = banner opts.on('-r LIBRARY|DIR', '--require LIBRARY|DIR', *require_files_msg) { |lib| require_files(lib) } if Cucumber::JRUBY opts.on('-j DIR', '--jars DIR', 'Load all the jars under DIR') { |jars| load_jars(jars) } end opts.on("#{RETRY_FLAG} ATTEMPTS", *retry_msg) { |v| set_option :retry, v.to_i } opts.on('--i18n-languages', *i18n_languages_msg) { list_languages_and_exit } opts.on('--i18n-keywords LANG', *i18n_keywords_msg) { |lang| language lang } opts.on(FAIL_FAST_FLAG, 'Exit immediately following the first failing scenario') { set_option :fail_fast } opts.on('-f FORMAT', '--format FORMAT', *format_msg, *FORMAT_HELP) do |v| add_option :formats, [*parse_formats(v), @out_stream] end opts.on('--init', *init_msg) { |v| initialize_project } opts.on('-o', '--out [FILE|DIR]', *out_msg) { |v| out_stream v } opts.on('-t TAG_EXPRESSION', '--tags TAG_EXPRESSION', *tags_msg) { |v| add_tag v } opts.on('-n NAME', '--name NAME', *name_msg) { |v| add_option :name_regexps, /#{v}/ } opts.on('-e', '--exclude PATTERN', *exclude_msg) { |v| add_option :excludes, Regexp.new(v) } opts.on(PROFILE_SHORT_FLAG, "#{PROFILE_LONG_FLAG} PROFILE", *profile_short_flag_msg) { |v| add_profile v } opts.on(NO_PROFILE_SHORT_FLAG, NO_PROFILE_LONG_FLAG, *no_profile_short_flag_msg) { |v| disable_profile_loading } opts.on('-c', '--[no-]color', *color_msg) { |v| color v } opts.on('-d', '--dry-run', *dry_run_msg) { set_dry_run_and_duration } opts.on('-m', '--no-multiline', "Don't print multiline strings and tables under steps.") { set_option :no_multiline } opts.on('-s', '--no-source', "Don't print the file and line of the step definition with the steps.") { set_option :source, false } opts.on('-i', '--no-snippets', "Don't print snippets for pending steps.") { set_option :snippets, false } opts.on('-I', '--snippet-type TYPE', *snippet_type_msg) { |v| set_option :snippet_type, v.to_sym } opts.on('-q', '--quiet', 'Alias for --no-snippets --no-source.') { shut_up } opts.on('--no-duration', "Don't print the duration at the end of the summary") { set_option :duration, false } opts.on('-b', '--backtrace', 'Show full backtrace for all errors.') { Cucumber.use_full_backtrace = true } opts.on('-S', '--[no-]strict', *strict_msg) { |setting| set_strict(setting) } opts.on('--[no-]strict-undefined', 'Fail if there are any undefined results.') { |setting| set_strict(setting, :undefined) } opts.on('--[no-]strict-pending', 'Fail if there are any pending results.') { |setting| set_strict(setting, :pending) } opts.on('--[no-]strict-flaky', 'Fail if there are any flaky results.') { |setting| set_strict(setting, :flaky) } opts.on('-w', '--wip', 'Fail if there are any passing scenarios.') { set_option :wip } opts.on('-v', '--verbose', 'Show the files and features loaded.') { set_option :verbose } opts.on('-g', '--guess', 'Guess best match for Ambiguous steps.') { set_option :guess } opts.on('-l', '--lines LINES', *lines_msg) { |lines| set_option :lines, lines } opts.on('-x', '--expand', 'Expand Scenario Outline Tables in output.') { set_option :expand } opts.on('--order TYPE[:SEED]', 'Run examples in the specified order. Available types:', *<<-TEXT.split("\n")) do |order| [defined] Run scenarios in the order they were defined (default). [random] Shuffle scenarios before running. Specify SEED to reproduce the shuffling from a previous run. e.g. --order random:5738 TEXT @options[:order], @options[:seed] = *order.split(':') unless ORDER_TYPES.include?(@options[:order]) fail "'#{@options[:order]}' is not a recognised order type. Please use one of #{ORDER_TYPES.join(", ")}." end end opts.on_tail('--version', 'Show version.') { exit_ok(Cucumber::VERSION) } opts.on_tail('-h', '--help', "You're looking at it.") { exit_ok(opts.help) } end.parse! @args.map! { |a| "#{a}:#{@options[:lines]}" } if @options[:lines] extract_environment_variables @options[:paths] = @args.dup # whatver is left over check_formatter_stream_conflicts() merge_profiles self end
to_hash()
click to toggle source
# File lib/cucumber/cli/options.rb, line 180 def to_hash Hash(@options) end
Private Instance Methods
add_option(option, value)
click to toggle source
# File lib/cucumber/cli/options.rb, line 372 def add_option(option, value) @options[option] << value end
add_profile(p)
click to toggle source
# File lib/cucumber/cli/options.rb, line 404 def add_profile(p) @profiles << p end
add_tag(value)
click to toggle source
# File lib/cucumber/cli/options.rb, line 376 def add_tag(value) warn("Deprecated: Found tags option '#{value}'. Support for '~@tag' will be removed from the next release of Cucumber. Please use 'not @tag' instead.") if value.include?('~') warn("Deprecated: Found tags option '#{value}'. Support for '@tag1,@tag2' will be removed from the next release of Cucumber. Please use '@tag or @tag2' instead.") if value.include?(',') @options[:tag_expressions] << value.gsub(/(@\w+)(:\d+)?/, '\1') add_tag_limits(value) end
add_tag_limit(tag_limits, tag_name, limit)
click to toggle source
# File lib/cucumber/cli/options.rb, line 389 def add_tag_limit(tag_limits, tag_name, limit) if tag_limits[tag_name] && tag_limits[tag_name] != limit raise "Inconsistent tag limits for #{tag_name}: #{tag_limits[tag_name]} and #{limit}" end tag_limits[tag_name] = limit end
add_tag_limits(value)
click to toggle source
# File lib/cucumber/cli/options.rb, line 383 def add_tag_limits(value) value.split(/[, ]/).map { |part| TAG_LIMIT_MATCHER.match(part) }.compact.each do |matchdata| add_tag_limit(@options[:tag_limits], matchdata[:tag_name], matchdata[:limit].to_i) end end
color(color)
click to toggle source
# File lib/cucumber/cli/options.rb, line 396 def color(color) Cucumber::Term::ANSIColor.coloring = color end
color_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 191 def color_msg [ 'Whether or not to use ANSI color in the output. Cucumber decides', 'based on your platform and the output destination if not specified.' ] end
default_options()
click to toggle source
# File lib/cucumber/cli/options.rb, line 572 def default_options { :strict => Cucumber::Core::Test::Result::StrictConfiguration.new, :require => [], :dry_run => false, :formats => [], :excludes => [], :tag_expressions => [], :tag_limits => {}, :name_regexps => [], :env_vars => {}, :diff_enabled => true, :snippets => true, :source => true, :duration => true, :retry => 0 } end
default_profile_should_be_used?()
click to toggle source
# File lib/cucumber/cli/options.rb, line 474 def default_profile_should_be_used? @profiles.empty? && profile_loader.cucumber_yml_defined? && profile_loader.has_profile?(@default_profile) end
disable_profile_loading()
click to toggle source
# File lib/cucumber/cli/options.rb, line 364 def disable_profile_loading @disable_profile_loading = true end
disable_profile_loading?()
click to toggle source
# File lib/cucumber/cli/options.rb, line 445 def disable_profile_loading? @disable_profile_loading end
dry_run_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 198 def dry_run_msg [ 'Invokes formatters without executing the steps.', 'This also omits the loading of your support/env.rb file if it exists.' ] end
exclude_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 205 def exclude_msg ["Don't run feature files or require ruby files matching PATTERN"] end
exit_ok(text)
click to toggle source
# File lib/cucumber/cli/options.rb, line 417 def exit_ok(text) @out_stream.puts text Kernel.exit(0) end
extract_environment_variables()
click to toggle source
# File lib/cucumber/cli/options.rb, line 436 def extract_environment_variables @args.delete_if do |arg| if arg =~ /^(\w+)=(.*)$/ @options[:env_vars][$1] = $2 true end end end
format_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 209 def format_msg ['How to format features (Default: pretty). Available formats:'] end
i18n_keywords_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 219 def i18n_keywords_msg [ 'List keywords for in a particular language', %{Run with "--i18n help" to see all languages} ] end
i18n_languages_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 213 def i18n_languages_msg [ 'List all available languages' ] end
indicate_invalid_language_and_exit(lang)
click to toggle source
# File lib/cucumber/cli/options.rb, line 522 def indicate_invalid_language_and_exit(lang) @out_stream.write("Invalid language '#{lang}'. Available languages are:\n") list_languages_and_exit end
init_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 226 def init_msg [ 'Initializes folder structure and generates conventional files for', 'a Cucumber project.' ] end
initialize_project()
click to toggle source
# File lib/cucumber/cli/options.rb, line 400 def initialize_project ProjectInitializer.new.run && Kernel.exit(0) end
language(lang)
click to toggle source
# File lib/cucumber/cli/options.rb, line 357 def language(lang) require 'gherkin/dialect' return indicate_invalid_language_and_exit(lang) unless ::Gherkin::DIALECTS.keys.include? lang list_keywords_and_exit(lang) end
lines_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 233 def lines_msg ['Run given line numbers. Equivalent to FILE:LINE syntax'] end
list_keywords_and_exit(lang)
click to toggle source
# File lib/cucumber/cli/options.rb, line 527 def list_keywords_and_exit(lang) require 'gherkin/dialect' language = ::Gherkin::Dialect.for(lang) data = Cucumber::MultilineArgument::DataTable.from( [ ['feature', to_keywords_string(language.feature_keywords)], ['background', to_keywords_string(language.background_keywords)], ['scenario', to_keywords_string(language.scenario_keywords)], ['scenario_outline', to_keywords_string(language.scenario_outline_keywords)], ['examples', to_keywords_string(language.examples_keywords)], ['given', to_keywords_string(language.given_keywords)], ['when', to_keywords_string(language.when_keywords)], ['then', to_keywords_string(language.then_keywords)], ['and', to_keywords_string(language.and_keywords)], ['but', to_keywords_string(language.but_keywords)], ['given (code)', to_code_keywords_string(language.given_keywords)], ['when (code)', to_code_keywords_string(language.when_keywords)], ['then (code)', to_code_keywords_string(language.then_keywords)], ['and (code)', to_code_keywords_string(language.and_keywords)], ['but (code)', to_code_keywords_string(language.but_keywords)] ] ) @out_stream.write(data.to_s({ color: false, prefixes: Hash.new('') })) Kernel.exit(0) end
list_languages_and_exit()
click to toggle source
# File lib/cucumber/cli/options.rb, line 553 def list_languages_and_exit require 'gherkin/dialect' data = Cucumber::MultilineArgument::DataTable.from( ::Gherkin::DIALECTS.keys.map do |key| [key, ::Gherkin::DIALECTS[key].fetch('name'), ::Gherkin::DIALECTS[key].fetch('native')] end ) @out_stream.write(data.to_s({ color: false, prefixes: Hash.new('') })) Kernel.exit(0) end
merge_profiles()
click to toggle source
# File lib/cucumber/cli/options.rb, line 449 def merge_profiles if @disable_profile_loading @out_stream.puts 'Disabling profiles...' return end @profiles << @default_profile if default_profile_should_be_used? @profiles.each do |profile| merge_with_profile(profile) end @options[:profiles] = @profiles end
merge_tag_limits(option_limits, other_limits)
click to toggle source
# File lib/cucumber/cli/options.rb, line 518 def merge_tag_limits(option_limits, other_limits) other_limits.each { |key, value| add_tag_limit(option_limits, key, value) } end
merge_with_profile(profile)
click to toggle source
# File lib/cucumber/cli/options.rb, line 464 def merge_with_profile(profile) profile_args = profile_loader.args_from(profile) profile_options = Options.parse( profile_args, @out_stream, @error_stream, :skip_profile_information => true, :profile_loader => profile_loader ) reverse_merge(profile_options) end
name_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 257 def name_msg [ 'Only execute the feature elements which match part of the given name.', 'If this option is given more than once, it will match against all the', 'given names.' ] end
no_profile_short_flag_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 237 def no_profile_short_flag_msg [ "Disables all profile loading to avoid using the 'default' profile." ] end
non_stdout_formats()
click to toggle source
# File lib/cucumber/cli/options.rb, line 368 def non_stdout_formats @options[:formats].select { |_, _, output| output != @out_stream } end
out_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 306 def out_msg [ 'Write output to a file/directory instead of STDOUT. This option', 'applies to the previously specified --format, or the', 'default format if no format is specified. Check the specific', "formatter's docs to see whether to pass a file or a dir." ] end
out_stream(v)
click to toggle source
# File lib/cucumber/cli/options.rb, line 278 def out_stream(v) @options[:formats] << ['pretty', {}, nil] if @options[:formats].empty? @options[:formats][-1][2] = v end
parse_formats(v)
click to toggle source
# File lib/cucumber/cli/options.rb, line 272 def parse_formats(v) formatter, *formatter_options = v.split(',') options_hash = Hash[formatter_options.map { |s| s.split('=') }] [formatter, options_hash] end
profile_loader()
click to toggle source
# File lib/cucumber/cli/options.rb, line 480 def profile_loader @profile_loader ||= ProfileLoader.new end
profile_short_flag_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 243 def profile_short_flag_msg [ 'Pull commandline arguments from cucumber.yml which can be defined as', "strings or arrays. When a 'default' profile is defined and no profile", 'is specified it is always used. (Unless disabled, see -P below.)', 'When feature files are defined in a profile and on the command line', 'then only the ones from the command line are used.' ] end
require_files(v)
click to toggle source
# File lib/cucumber/cli/options.rb, line 346 def require_files(v) @options[:require] << v return unless Cucumber::JRUBY && File.directory?(v) require 'java' $CLASSPATH << v end
require_files_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 315 def require_files_msg [ 'Require files before executing the features. If this', 'option is not specified, all *.rb files that are', 'siblings or below the features will be loaded auto-', 'matically. Automatic loading is disabled when this', 'option is specified, and all loading becomes explicit.', 'Files under directories named "support" are always', 'loaded first.', 'This option can be specified multiple times.' ] end
require_jars(jars)
click to toggle source
# File lib/cucumber/cli/options.rb, line 353 def require_jars(jars) Dir["#{jars}/**/*.jar"].each { |jar| require jar } end
retry_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 253 def retry_msg ['Specify the number of times to retry failing tests (default: 0)'] end
reverse_merge(other_options)
click to toggle source
# File lib/cucumber/cli/options.rb, line 484 def reverse_merge(other_options) @options = other_options.options.merge(@options) @options[:require] += other_options[:require] @options[:excludes] += other_options[:excludes] @options[:name_regexps] += other_options[:name_regexps] @options[:tag_expressions] += other_options[:tag_expressions] merge_tag_limits(@options[:tag_limits], other_options[:tag_limits]) @options[:env_vars] = other_options[:env_vars].merge(@options[:env_vars]) if @options[:paths].empty? @options[:paths] = other_options[:paths] else @overridden_paths += (other_options[:paths] - @options[:paths]) end @options[:source] &= other_options[:source] @options[:snippets] &= other_options[:snippets] @options[:duration] &= other_options[:duration] @options[:strict] = other_options[:strict].merge!(@options[:strict]) @options[:dry_run] |= other_options[:dry_run] @profiles += other_options.profiles @expanded_args += other_options.expanded_args if @options[:formats].empty? @options[:formats] = other_options[:formats] else @options[:formats] += other_options[:formats] @options[:formats] = stdout_formats[0..0] + non_stdout_formats end @options[:retry] = other_options[:retry] if @options[:retry] == 0 self end
set_dry_run_and_duration()
click to toggle source
# File lib/cucumber/cli/options.rb, line 412 def set_dry_run_and_duration @options[:dry_run] = true @options[:duration] = false end
set_option(option, value = nil)
click to toggle source
# File lib/cucumber/cli/options.rb, line 408 def set_option(option, value = nil) @options[option] = value.nil? ? true : value end
set_strict(setting, type = nil)
click to toggle source
# File lib/cucumber/cli/options.rb, line 428 def set_strict(setting, type = nil) @options[:strict].set_strict(setting, type) end
shut_up()
click to toggle source
# File lib/cucumber/cli/options.rb, line 422 def shut_up @options[:snippets] = false @options[:source] = false @options[:duration] = false end
snippet_type_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 328 def snippet_type_msg [ 'Use different snippet type (Default: cucumber_expression). Available types:', Cucumber::Glue::RegistryAndMore.cli_snippet_type_options ].flatten end
stdout_formats()
click to toggle source
# File lib/cucumber/cli/options.rb, line 432 def stdout_formats @options[:formats].select { |_, _, output| output == @out_stream } end
strict_msg()
click to toggle source
# File lib/cucumber/cli/options.rb, line 265 def strict_msg [ 'Fail if there are any strict affected results ', '(that is undefined, pending or flaky results).' ] end
to_code_keywords_string(list)
click to toggle source
# File lib/cucumber/cli/options.rb, line 568 def to_code_keywords_string(list) to_keywords_string(Cucumber::Gherkin::I18n.code_keywords_for(list)) end
to_keywords_string(list)
click to toggle source
# File lib/cucumber/cli/options.rb, line 564 def to_keywords_string(list) list.map { |item| "\"#{item}\"" }.join(', ') end