Class: Cucumber::Cli::Options

Inherits:
Object
  • Object
show all
Defined in:
lib/cucumber/cli/options.rb

Constant Summary collapse

CUCUMBER_PUBLISH_URL =
ENV['CUCUMBER_PUBLISH_URL'] || 'https://messages.cucumber.io/api/reports -X GET'
INDENT =
' ' * 53
BUILTIN_FORMATS =
{
  'pretty'      => ['Cucumber::Formatter::Pretty',      'Prints the feature as is - in colours.'],
  'progress'    => ['Cucumber::Formatter::Progress',    'Prints one character per scenario.'],
  'rerun'       => ['Cucumber::Formatter::Rerun',       'Prints failing files with line numbers.'],
  'usage'       => ['Cucumber::Formatter::Usage',       "Prints where step definitions are used.\n" \
                                                        "#{INDENT}The slowest step definitions (with duration) are\n" \
                                                        "#{INDENT}listed first. If --dry-run is used the duration\n" \
                                                        "#{INDENT}is not shown, and step definitions are sorted by\n" \
                                                        "#{INDENT}filename instead."],
  'stepdefs'    => ['Cucumber::Formatter::Stepdefs',    "Prints All step definitions with their locations. Same as\n" \
                                                        "#{INDENT}the usage formatter, except that steps are not printed."],
  'junit'       => ['Cucumber::Formatter::Junit',       'Generates a report similar to Ant+JUnit.'],
  'json'        => ['Cucumber::Formatter::Json',        '[DEPRECATED] Prints the feature as JSON'],
  'message'     => ['Cucumber::Formatter::Message',     'Outputs protobuf messages'],
  'html'        => ['Cucumber::Formatter::HTML',        'Outputs HTML report'],
  'summary'     => ['Cucumber::Formatter::Summary',     'Summary output of feature and scenarios']
}.freeze
FORMAT_HELP_MSG =
[
  'Use --format rerun --out rerun.txt to write out failing',
  'features. You can rerun them with cucumber @rerun.txt.',
  'FORMAT can also be the fully qualified class name of',
  "your own custom formatter. If the class isn't loaded,",
  'Cucumber will attempt to require a file with a relative',
  'file name that is the underscore name of the class name.',
  'Example: --format Foo::BarZap -> Cucumber will look for',
  'foo/bar_zap.rb. You can place the file with this relative',
  'path underneath your features/support directory or anywhere',
  "on Ruby's LOAD_PATH, for example in a Ruby gem."
].freeze
FORMAT_HELP =
(BUILTIN_FORMATS.keys.sort.map do |key|
  "  #{key}#{' ' * (max - key.length)} : #{BUILTIN_FORMATS[key][1]}"
end) + FORMAT_HELP_MSG
PROFILE_SHORT_FLAG =
'-p'.freeze
NO_PROFILE_SHORT_FLAG =
'-P'.freeze
PROFILE_LONG_FLAG =
'--profile'.freeze
NO_PROFILE_LONG_FLAG =
'--no-profile'.freeze
FAIL_FAST_FLAG =
'--fail-fast'.freeze
RETRY_FLAG =
'--retry'.freeze
OPTIONS_WITH_ARGS =
[
  '-r', '--require', '--i18n-keywords', '-f', '--format', '-o',
  '--out', '-t', '--tags', '-n', '--name', '-e', '--exclude',
  PROFILE_SHORT_FLAG, PROFILE_LONG_FLAG, RETRY_FLAG, '-l',
  '--lines', '--port', '-I', '--snippet-type'
].freeze
ORDER_TYPES =
%w[defined random].freeze
TAG_LIMIT_MATCHER =
/(?<tag_name>\@\w+):(?<limit>\d+)/x

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(out_stream = STDOUT, error_stream = STDERR, options = {}) ⇒ Options

Returns a new instance of Options.


67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/cucumber/cli/options.rb', line 67

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

Class Method Details

.parse(args, out_stream, error_stream, options = {}) ⇒ Object


63
64
65
# File 'lib/cucumber/cli/options.rb', line 63

def self.parse(args, out_stream, error_stream, options = {})
  new(out_stream, error_stream, options).parse!(args)
end

Instance Method Details

#[](key) ⇒ Object


81
82
83
# File 'lib/cucumber/cli/options.rb', line 81

def [](key)
  @options[key]
end

#[]=(key, value) ⇒ Object


85
86
87
# File 'lib/cucumber/cli/options.rb', line 85

def []=(key, value)
  @options[key] = value
end

#check_formatter_stream_conflictsObject


175
176
177
178
179
# File 'lib/cucumber/cli/options.rb', line 175

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_profilesObject


167
168
169
# File 'lib/cucumber/cli/options.rb', line 167

def custom_profiles
  @profiles - [@default_profile]
end

#filtersObject


171
172
173
# File 'lib/cucumber/cli/options.rb', line 171

def filters
  @options[:filters] ||= []
end

#parse!(args) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/MethodLength


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/cucumber/cli/options.rb', line 89

def parse!(args) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  @args = args
  @expanded_args = @args.dup

  @args.extend(::OptionParser::Arguable)

  @args.options do |opts| # rubocop:disable Metrics/BlockLength
    opts.banner = banner
    opts.on('--publish', 'Publish a report to https://reports.cucumber.io') do
      set_option :publish_enabled, true
    end
    opts.on('--publish-quiet', 'Don\'t print information banner about publishing reports') { set_option :publish_quiet }
    opts.on('-r LIBRARY|DIR', '--require LIBRARY|DIR', *require_files_msg) { |lib| require_files(lib) }

    opts.on('-j DIR', '--jars DIR', 'Load all the jars under DIR') { |jars| load_jars(jars) } if Cucumber::JRUBY

    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|URL]', *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 --no-duration --publish-quiet.') { 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(':')
      raise "'#{@options[:order]}' is not a recognised order type. Please use one of #{ORDER_TYPES.join(', ')}." unless ORDER_TYPES.include?(@options[:order])
    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!

  process_publish_options

  @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_hashObject


181
182
183
# File 'lib/cucumber/cli/options.rb', line 181

def to_hash
  Hash(@options)
end