cucumber 3.2.0 → 4.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +61 -18
  3. data/CONTRIBUTING.md +1 -0
  4. data/bin/cucumber +1 -1
  5. data/lib/autotest/cucumber_mixin.rb +42 -39
  6. data/lib/cucumber/cli/configuration.rb +4 -4
  7. data/lib/cucumber/cli/main.rb +11 -12
  8. data/lib/cucumber/cli/options.rb +56 -69
  9. data/lib/cucumber/cli/profile_loader.rb +32 -20
  10. data/lib/cucumber/configuration.rb +20 -21
  11. data/lib/cucumber/constantize.rb +2 -5
  12. data/lib/cucumber/deprecate.rb +5 -5
  13. data/lib/cucumber/errors.rb +4 -6
  14. data/lib/cucumber/events.rb +1 -0
  15. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  16. data/lib/cucumber/events/step_activated.rb +2 -1
  17. data/lib/cucumber/file_specs.rb +6 -6
  18. data/lib/cucumber/filters/activate_steps.rb +5 -3
  19. data/lib/cucumber/filters/prepare_world.rb +5 -9
  20. data/lib/cucumber/filters/quit.rb +1 -3
  21. data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
  22. data/lib/cucumber/formatter/ansicolor.rb +40 -45
  23. data/lib/cucumber/formatter/ast_lookup.rb +160 -0
  24. data/lib/cucumber/formatter/backtrace_filter.rb +5 -7
  25. data/lib/cucumber/formatter/console.rb +28 -59
  26. data/lib/cucumber/formatter/console_counts.rb +4 -9
  27. data/lib/cucumber/formatter/console_issues.rb +6 -3
  28. data/lib/cucumber/formatter/duration_extractor.rb +1 -1
  29. data/lib/cucumber/formatter/fanout.rb +2 -0
  30. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
  31. data/lib/cucumber/formatter/interceptor.rb +5 -7
  32. data/lib/cucumber/formatter/io.rb +8 -14
  33. data/lib/cucumber/formatter/json.rb +93 -117
  34. data/lib/cucumber/formatter/junit.rb +55 -57
  35. data/lib/cucumber/formatter/pretty.rb +346 -152
  36. data/lib/cucumber/formatter/progress.rb +28 -32
  37. data/lib/cucumber/formatter/rerun.rb +22 -4
  38. data/lib/cucumber/formatter/stepdefs.rb +1 -2
  39. data/lib/cucumber/formatter/steps.rb +2 -3
  40. data/lib/cucumber/formatter/summary.rb +16 -8
  41. data/lib/cucumber/formatter/unicode.rb +15 -17
  42. data/lib/cucumber/formatter/usage.rb +9 -8
  43. data/lib/cucumber/gherkin/data_table_parser.rb +8 -6
  44. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
  45. data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
  46. data/lib/cucumber/gherkin/steps_parser.rb +7 -8
  47. data/lib/cucumber/glue/dsl.rb +1 -1
  48. data/lib/cucumber/glue/hook.rb +16 -9
  49. data/lib/cucumber/glue/invoke_in_world.rb +13 -18
  50. data/lib/cucumber/glue/proto_world.rb +14 -16
  51. data/lib/cucumber/glue/registry_and_more.rb +7 -9
  52. data/lib/cucumber/glue/snippet.rb +21 -20
  53. data/lib/cucumber/glue/step_definition.rb +14 -15
  54. data/lib/cucumber/glue/world_factory.rb +1 -1
  55. data/lib/cucumber/hooks.rb +11 -11
  56. data/lib/cucumber/multiline_argument.rb +4 -6
  57. data/lib/cucumber/multiline_argument/data_table.rb +88 -59
  58. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +1 -1
  59. data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
  60. data/lib/cucumber/platform.rb +3 -3
  61. data/lib/cucumber/rake/task.rb +13 -16
  62. data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
  63. data/lib/cucumber/running_test_case.rb +2 -53
  64. data/lib/cucumber/runtime.rb +27 -57
  65. data/lib/cucumber/runtime/after_hooks.rb +3 -3
  66. data/lib/cucumber/runtime/before_hooks.rb +3 -3
  67. data/lib/cucumber/runtime/for_programming_languages.rb +3 -2
  68. data/lib/cucumber/runtime/step_hooks.rb +1 -1
  69. data/lib/cucumber/runtime/support_code.rb +10 -12
  70. data/lib/cucumber/runtime/user_interface.rb +4 -6
  71. data/lib/cucumber/step_definition_light.rb +4 -3
  72. data/lib/cucumber/step_match.rb +12 -11
  73. data/lib/cucumber/step_match_search.rb +2 -1
  74. data/lib/cucumber/term/ansicolor.rb +9 -9
  75. data/lib/cucumber/version +1 -1
  76. metadata +37 -28
  77. data/lib/cucumber/formatter/cucumber.css +0 -286
  78. data/lib/cucumber/formatter/cucumber.sass +0 -247
  79. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  80. data/lib/cucumber/formatter/html.rb +0 -611
  81. data/lib/cucumber/formatter/html_builder.rb +0 -121
  82. data/lib/cucumber/formatter/http_io.rb +0 -146
  83. data/lib/cucumber/formatter/inline-js.js +0 -30
  84. data/lib/cucumber/formatter/jquery-min.js +0 -154
  85. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  86. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  87. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  88. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  89. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  90. data/lib/cucumber/step_argument.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 6a9339e408c80955872fc7386ee99fc26b6519458369e06f0a65be76b27b6129
4
- data.tar.gz: 10667fb8062a67fbf034a80a35a0d6ad53ca087bbe9cef9a9019d3343fddae94
2
+ SHA1:
3
+ metadata.gz: 272094a2efb99945d2d0e3e6a91bae0b855428d0
4
+ data.tar.gz: 400106f2e8a065a57bb9d85171b5fa7e98999d3a
5
5
  SHA512:
6
- metadata.gz: 4e9417b90d33b309f6a90845de1e66aeea91767146ca534b80f09989600ff50c1cc868f1c46696dccd48767d0cc78794df29cbe97cc227178db27c05bf510687
7
- data.tar.gz: 2b2cdf34b49f79ec6bbb4d8b484d211c4afb82f0572baa75463b0bc8f9c614e02d1acb303fc623730b42a61e37343c1d882ffb817a1fd9eebdf7c59da7bf8813
6
+ metadata.gz: 7e4c314d1e1b30f1d8e5ef171a7fb5ca1120bd9cd9c2ec2f1e353f7ee38d74ddc04771a8506c62ef4e71c9b58aeb6f28dccd3d2d979f2119dcc10b30c2ca7d2e
7
+ data.tar.gz: 854f93e0396ebc737e6f5f525028654042b96387b90c12ae7b41f65cd76e03668cf50c9a0a9517455f080a76b5c21a4825b3fe2f51b353471a91e45f47cb5139
@@ -10,17 +10,73 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
10
10
 
11
11
  ----
12
12
 
13
- ## [3.2.0](https://github.com/cucumber/cucumber-ruby/compare/v3.1.2...v3.2.0) (2020-07-02)
13
+ ## [In Git](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.1...master) (Not released)
14
14
 
15
15
  ### Added
16
16
 
17
- * `--out` option now supports URL:
18
- * default method is `PUT`
19
- * you can ussed cURL like options, for example: `--out "http://example.com -X POST -H Content-Type:text/json"` (Backport of [#1395](https://github.com/cucumber/cucumber-ruby/pull/1395) and [#1406](https://github.com/cucumber/cucumber-ruby/pull/1406))
17
+ ### Changed
18
+
19
+ ### Deprecated
20
+
21
+ ### Removed
22
+
23
+ ### Fixed
24
+
25
+ ### Added
26
+
27
+ ### Improved
28
+
29
+ ## [4.0.0.rc.1](https://github.com/cucumber/cucumber-ruby/compare/v3.1.2...v4.0.0.rc.1) (2018-09-29)
30
+
31
+ ### Added
32
+
33
+ * Added support for new `Rule` keyword. [Read more here.](https://github.com/cucumber/cucumber/blob/master/gherkin/CHANGELOG.md#6013---2018-09-25)
34
+ * Added new `dots` formatter. This is the first step of a larger strategy to move the formatters to a new architecture where they delegate to shared executables via messages.
35
+
36
+ ### Changed
37
+
38
+ * Use Gherkin v6.
39
+ ([#1313](https://github.com/cucumber/cucumber-ruby/pull/1313)
40
+ [brasmusson](https://github.com/brasmusson))
41
+ * Do not apply Before and After Hooks to Test Cases with no Test Steps.
42
+ ([#1311](https://github.com/cucumber/cucumber-ruby/pull/1311)
43
+ [brasmusson](https://github.com/brasmusson))
44
+ * Pass the registry to the Wire plugin.
45
+ ([#1309](https://github.com/cucumber/cucumber-ruby/pull/1309)
46
+ [brasmusson](https://github.com/brasmusson))
47
+ * Adapt to using the Gherkin compiler and Pickles in the core.
48
+ ([#1309](https://github.com/cucumber/cucumber-ruby/pull/1309)
49
+ [brasmusson](https://github.com/brasmusson))
50
+ * Let the Pretty Formatter use events.
51
+ ([#1305](https://github.com/cucumber/cucumber-ruby/pull/1305)
52
+ [brasmusson](https://github.com/brasmusson))
53
+
54
+ ### Removed
55
+
56
+ * Remove the support of old style tag expressions.
57
+ ([#1314](https://github.com/cucumber/cucumber-ruby/pull/1314),
58
+ [brasmusson](https://github.com/brasmusson))
59
+ * Remove the Legacy API for Formatters.
60
+ ([#1230](https://github.com/cucumber/cucumber-ruby/pull/1230),
61
+ [#839](https://github.com/cucumber/cucumber-ruby/issues/839)
62
+ [brasmusson](https://github.com/brasmusson))
63
+ * Remove the JSON Pretty Formatter (which was the same as the JSON formatter).
64
+ ([brasmusson](https://github.com/brasmusson))
65
+ * Remove the HTML Formatter.
66
+ ([#1306](https://github.com/cucumber/cucumber-ruby/pull/1306)
67
+ [brasmusson](https://github.com/brasmusson))
20
68
 
21
69
  ### Fixed
22
70
 
23
- * JSON report: Do not fail when trying to embed bytes [#1388](https://github.com/cucumber/cucumber-ruby/issues/1388)
71
+ * Wire protocol compatibility for docstrings.
72
+ ([#1183](https://github.com/cucumber/cucumber-ruby/issues/1183))
73
+ * Let the Rerun Formatter handle flaky scenarios.
74
+ ([#1310](https://github.com/cucumber/cucumber-ruby/pull/1310)
75
+ [brasmusson](https://github.com/brasmusson))
76
+
77
+ ### Improved
78
+
79
+ * Code style changes completed as per backlog of Rubocop TODO file. ([#1021](https://github.com/cucumber/cucumber-ruby/issues/1021) [@jaysonesmith](https://github.com/jaysonesmith))
24
80
 
25
81
  ## [3.1.2](https://github.com/cucumber/cucumber-ruby/compare/v3.1.1...v3.1.2) (2018-07-13)
26
82
 
@@ -101,13 +157,6 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
101
157
  * Fix the printing of newlines in the rerun formatter - a problem introduced in [#1162](https://github.com/cucumber/cucumber-ruby/issues/1162) ([#1207](https://github.com/cucumber/cucumber-ruby/issues/1207) [@brasmusson](https://github.com/brasmusson))
102
158
  * Handle the `--retry` option in profiles ([#1050](https://github.com/cucumber/cucumber-ruby/issues/1050) [@brasmusson](https://github.com/brasmusson))
103
159
 
104
- ### Improved
105
-
106
- * Exclude the legacy_api from rubocop, regenerate Rubocop Todo ([@jaysonesmith](https://github.com/jaysonesmith), [@brasmusson](https://github.com/brasmusson))
107
- * Review and handle excluded/ignored cops ([#1208](https://github.com/cucumber/cucumber-ruby/pull/1208) [@jaysonesmith](https://github.com/jaysonesmith))
108
- * Fix SymbolProc issues ([#1212](https://github.com/cucumber/cucumber-ruby/pull/1212) [@jaysonesmith](https://github.com/jaysonesmith))
109
- * Fix TrailingBlankLines ([#1211](https://github.com/cucumber/cucumber-ruby/pull/1211) [@jaysonesmith](https://github.com/jaysonesmith))
110
-
111
160
  ## [3.0.1](https://github.com/cucumber/cucumber-ruby/compare/v3.0.0...3.0.1) (2017-09-29)
112
161
 
113
162
  ### Fixed
@@ -143,12 +192,6 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
143
192
  * Refactor: Extract HTMLBuilder#string_to_embed method to DRY up code ([#1187](https://github.com/cucumber/cucumber-ruby/pulls/1187) [@danascheider](https://github.com/danascheider))
144
193
  * As per [#251](https://github.com/cucumber/cucumber/issues/251): renamed History.md to CHANGELOG.md, added contributing message at beginning, and misc formatting. ([#1185](https://github.com/cucumber/cucumber-ruby/issues/1185) [jaysonesmith](https://github.com/jaysonesmith))
145
194
  * Use past tense in event names (`xStarting` -> `xStarted`) ([#1166](https://github.com/cucumber/cucumber-ruby/issues/1166) @brasmusson).
146
- * Fix Lint/DeprecatedClassMethods ([#1172](https://github.com/cucumber/cucumber-ruby/issues/1172) [jaysonesmith](https://github.com/jaysonesmith))
147
- * Fix Lint/DuplicateMethods ([#1173](https://github.com/cucumber/cucumber-ruby/issues/1173) [jaysonesmith](https://github.com/jaysonesmith))
148
- * Fix Metrics/LineLength ([#1175](https://github.com/cucumber/cucumber-ruby/issues/1175), [#1175](https://github.com/cucumber/cucumber-ruby/issues/1175), [#1176](https://github.com/cucumber/cucumber-ruby/issues/1176) [jaysonesmith](https://github.com/jaysonesmith))
149
- * Fix Style/AlignArray ([#1177](https://github.com/cucumber/cucumber-ruby/issues/1177) [jaysonesmith](https://github.com/jaysonesmith))
150
- * Fix Style/AndOr ([#1178](https://github.com/cucumber/cucumber-ruby/issues/1178) [jaysonesmith](https://github.com/jaysonesmith))
151
- * Fix Multiple Cops ([#1179](https://github.com/cucumber/cucumber-ruby/issues/1179) [jaysonesmith](https://github.com/jaysonesmith))
152
195
 
153
196
  ## [3.0.0.pre.2](https://github.com/cucumber/cucumber-ruby/compare/v2.4.0...v3.0.0.pre.2)
154
197
 
@@ -67,6 +67,7 @@ Now release it
67
67
  bundle update
68
68
  bundle exec rake
69
69
  git commit -m "Release X.Y.Z"
70
+ # Make sure you run gem signin as the cukebot@cucumber.io user before running the following step. Credentials can be found in 1Password
70
71
  rake release
71
72
 
72
73
  ## Gaining Release Karma
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  file_name = File.dirname(__FILE__) + '/../lib'
3
- $:.unshift(file_name) unless $:.include?(file_name)
3
+ $LOAD_PATH.unshift(file_name) unless $LOAD_PATH.include?(file_name)
4
4
 
5
5
  require 'simplecov_setup'
6
6
  require 'cucumber/rspec/disable_option_parser'
@@ -7,7 +7,7 @@ require 'cucumber/cli/profile_loader'
7
7
 
8
8
  module Autotest::CucumberMixin
9
9
  def self.included(receiver)
10
- receiver::ALL_HOOKS << [:run_features, :ran_features]
10
+ receiver::ALL_HOOKS << %i[run_features ran_features]
11
11
  end
12
12
 
13
13
  attr_accessor :features_to_run
@@ -23,12 +23,10 @@ module Autotest::CucumberMixin
23
23
  reset_features
24
24
  add_sigint_handler
25
25
 
26
- self.last_mtime = Time.now if $f
27
-
28
26
  loop do # ^c handler
29
27
  begin
30
28
  get_to_green
31
- if self.tainted then
29
+ if tainted
32
30
  rerun_all_tests
33
31
  rerun_all_features if all_good
34
32
  else
@@ -39,7 +37,7 @@ module Autotest::CucumberMixin
39
37
  # time a file is changed to see if anything breaks.
40
38
  reset_features
41
39
  rescue Interrupt
42
- break if self.wants_to_quit
40
+ break if wants_to_quit
43
41
  reset
44
42
  reset_features
45
43
  end
@@ -51,12 +49,13 @@ module Autotest::CucumberMixin
51
49
  features_to_run == ''
52
50
  end
53
51
 
54
- def get_to_green
55
- begin
52
+ def get_to_green # rubocop:disable Naming/AccessorMethodName
53
+ loop do
56
54
  super
57
55
  run_features
58
56
  wait_for_changes unless all_features_good
59
- end until all_features_good
57
+ break if all_features_good
58
+ end
60
59
  end
61
60
 
62
61
  def rerun_all_features
@@ -71,67 +70,71 @@ module Autotest::CucumberMixin
71
70
  def run_features
72
71
  hook :run_features
73
72
  Tempfile.open('autotest-cucumber') do |dirty_features_file|
74
- cmd = self.make_cucumber_cmd(self.features_to_run, dirty_features_file.path)
73
+ cmd = make_cucumber_cmd(features_to_run, dirty_features_file.path)
75
74
  break if cmd.empty?
76
- puts cmd unless $q
77
75
  old_sync = $stdout.sync
78
76
  $stdout.sync = true
79
77
  self.results = []
80
78
  line = []
81
79
  begin
82
- open("| #{cmd}", 'r') do |f|
80
+ open("| #{cmd}", 'r') do |f| # rubocop:disable Security/Open
83
81
  until f.eof?
84
82
  c = f.getc || break
85
- if RUBY_VERSION >= '1.9' then
86
- print c
87
- else
88
- putc c
89
- end
83
+ put_command(c)
90
84
  line << c
91
- if c == ?\n then
92
- self.results << if RUBY_VERSION >= '1.9' then
93
- line.join
94
- else
95
- line.pack 'c*'
96
- end
97
- line.clear
98
- end
85
+ next unless c == "\n"
86
+ results << join_line
87
+ line.clear
99
88
  end
100
89
  end
101
90
  ensure
102
91
  $stdout.sync = old_sync
103
92
  end
104
93
  self.features_to_run = dirty_features_file.read.strip
105
- self.tainted = true unless self.features_to_run == ''
94
+ self.tainted = true unless features_to_run == ''
106
95
  end
107
96
  hook :ran_features
108
97
  end
109
98
 
110
- def make_cucumber_cmd(features_to_run, dirty_features_filename)
111
- return '' if features_to_run == ''
99
+ def put_command(cmd)
100
+ RUBY_VERSION >= '1.9' ? print(cmd) : putcmd(c)
101
+ end
102
+
103
+ def join_line
104
+ RUBY_VERSION >= '1.9' ? line.join : line.pack('c*')
105
+ end
106
+
107
+ def make_cucumber_cmd(features_to_run, _dirty_features_filename)
108
+ return '' if features_to_run.empty?
112
109
 
113
110
  profile_loader = Cucumber::Cli::ProfileLoader.new
114
111
 
115
- profile ||= 'autotest-all' if profile_loader.has_profile?('autotest-all') && features_to_run == :all
116
- profile ||= 'autotest' if profile_loader.has_profile?('autotest')
117
- profile ||= nil
112
+ profile = profile(profile_loader)
113
+
114
+ args = created_args(features_to_run, profile)
118
115
 
116
+ "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} #{args}"
117
+ end
118
+
119
+ def profile(profile_loader)
120
+ profile ||= 'autotest-all' if profile_loader.profile?('autotest-all') && features_to_run == :all
121
+ profile ||= 'autotest' if profile_loader.profile?('autotest')
122
+ profile || nil
123
+ end
124
+
125
+ def created_args(features_to_run, profile)
119
126
  args = if profile
120
127
  ['--profile', profile]
121
128
  else
122
- %w{--format} << (features_to_run == :all ? 'progress' : 'pretty')
129
+ %w[--format] << (features_to_run == :all ? 'progress' : 'pretty')
123
130
  end
124
131
  # No --color option as some IDEs (Netbeans) don't output them very well (1 failed step)
125
- args += %w{--format rerun --out} << dirty_features_filename
132
+ args += %w[--format rerun --out] << dirty_features_filename
126
133
  args << (features_to_run == :all ? '' : features_to_run)
127
134
 
128
- # Unless I do this, all the steps turn up undefined during the rerun...
129
- unless features_to_run == :all
130
- args << 'features/step_definitions' << 'features/support'
131
- end
132
-
133
- args = args.join(' ')
135
+ # All steps becom undefined during rerun unless the following is run.
136
+ args << 'features/step_definitions' << 'features/support' unless features_to_run == :all
134
137
 
135
- return "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} #{args}"
138
+ args.join(' ')
136
139
  end
137
140
  end
@@ -20,7 +20,7 @@ module Cucumber
20
20
  def initialize(out_stream = STDOUT, error_stream = STDERR)
21
21
  @out_stream = out_stream
22
22
  @error_stream = error_stream
23
- @options = Options.new(@out_stream, @error_stream, :default_profile => 'default')
23
+ @options = Options.new(@out_stream, @error_stream, default_profile: 'default')
24
24
  end
25
25
 
26
26
  def parse!(args)
@@ -64,7 +64,7 @@ module Cucumber
64
64
  end
65
65
 
66
66
  def fail_fast?
67
- !!@options[:fail_fast]
67
+ @options[:fail_fast]
68
68
  end
69
69
 
70
70
  def retry_attempts
@@ -79,7 +79,7 @@ module Cucumber
79
79
  logger = Logger.new(@out_stream)
80
80
  logger.formatter = LogFormatter.new
81
81
  logger.level = Logger::INFO
82
- logger.level = Logger::DEBUG if self.verbose?
82
+ logger.level = Logger::DEBUG if verbose?
83
83
  logger
84
84
  end
85
85
 
@@ -131,7 +131,7 @@ module Cucumber
131
131
  f[2] == @out_stream ? -1 : 1
132
132
  end
133
133
  @options[:formats].uniq!
134
- @options.check_formatter_stream_conflicts()
134
+ @options.check_formatter_stream_conflicts
135
135
  end
136
136
  end
137
137
  end
@@ -24,22 +24,15 @@ module Cucumber
24
24
  def execute!(existing_runtime = nil)
25
25
  trap_interrupt
26
26
 
27
- runtime = if existing_runtime
28
- existing_runtime.configure(configuration)
29
- existing_runtime
30
- else
31
- Runtime.new(configuration)
32
- end
27
+ runtime = runtime(existing_runtime)
33
28
 
34
29
  runtime.run!
35
30
  if Cucumber.wants_to_quit
36
31
  exit_unable_to_finish
32
+ elsif runtime.failure?
33
+ exit_tests_failed
37
34
  else
38
- if runtime.failure?
39
- exit_tests_failed
40
- else
41
- exit_ok
42
- end
35
+ exit_ok
43
36
  end
44
37
  rescue SystemExit => e
45
38
  @kernel.exit(e.status)
@@ -56,7 +49,7 @@ module Cucumber
56
49
  rescue Errno::EACCES, Errno::ENOENT => e
57
50
  @err.puts("#{e.message} (#{e.class})")
58
51
  exit_unable_to_finish
59
- rescue Exception => e
52
+ rescue Exception => e # rubocop:disable Lint/RescueException
60
53
  @err.puts("#{e.message} (#{e.class})")
61
54
  @err.puts(e.backtrace.join("\n"))
62
55
  exit_unable_to_finish
@@ -95,6 +88,12 @@ module Cucumber
95
88
  STDERR.puts "\nExiting... Interrupt again to exit immediately."
96
89
  end
97
90
  end
91
+
92
+ def runtime(existing_runtime)
93
+ return Runtime.new(configuration) unless existing_runtime
94
+ existing_runtime.configure(configuration)
95
+ existing_runtime
96
+ end
98
97
  end
99
98
  end
100
99
  end
@@ -10,25 +10,22 @@ module Cucumber
10
10
  module Cli
11
11
  class Options
12
12
  INDENT = ' ' * 53
13
- # rubocop:disable Layout/MultilineOperationIndentation
14
13
  BUILTIN_FORMATS = {
15
- 'html' => ['Cucumber::Formatter::Html', 'Generates a nice looking HTML report.'],
16
14
  'pretty' => ['Cucumber::Formatter::Pretty', 'Prints the feature as is - in colours.'],
17
15
  'progress' => ['Cucumber::Formatter::Progress', 'Prints one character per scenario.'],
16
+ 'dots' => ['Cucumber::Formatter::Dots', 'Simple progress output to console'],
18
17
  'rerun' => ['Cucumber::Formatter::Rerun', 'Prints failing files with line numbers.'],
19
- 'usage' => ['Cucumber::Formatter::Usage', "Prints where step definitions are used.\n" +
20
- "#{INDENT}The slowest step definitions (with duration) are\n" +
21
- "#{INDENT}listed first. If --dry-run is used the duration\n" +
22
- "#{INDENT}is not shown, and step definitions are sorted by\n" +
18
+ 'usage' => ['Cucumber::Formatter::Usage', "Prints where step definitions are used.\n" \
19
+ "#{INDENT}The slowest step definitions (with duration) are\n" \
20
+ "#{INDENT}listed first. If --dry-run is used the duration\n" \
21
+ "#{INDENT}is not shown, and step definitions are sorted by\n" \
23
22
  "#{INDENT}filename instead."],
24
- 'stepdefs' => ['Cucumber::Formatter::Stepdefs', "Prints All step definitions with their locations. Same as\n" +
23
+ 'stepdefs' => ['Cucumber::Formatter::Stepdefs', "Prints All step definitions with their locations. Same as\n" \
25
24
  "#{INDENT}the usage formatter, except that steps are not printed."],
26
25
  'junit' => ['Cucumber::Formatter::Junit', 'Generates a report similar to Ant+JUnit.'],
27
26
  'json' => ['Cucumber::Formatter::Json', 'Prints the feature as JSON'],
28
- 'json_pretty' => ['Cucumber::Formatter::JsonPretty', 'Prints the feature as prettified JSON'],
29
27
  'summary' => ['Cucumber::Formatter::Summary', 'Summary output of feature and scenarios']
30
- }
31
- # rubocop:enable Layout/MultilineOperationIndentation
28
+ }.freeze
32
29
  max = BUILTIN_FORMATS.keys.map(&:length).max
33
30
  FORMAT_HELP_MSG = [
34
31
  'Use --format rerun --out rerun.txt to write out failing',
@@ -41,24 +38,24 @@ module Cucumber
41
38
  'foo/bar_zap.rb. You can place the file with this relative',
42
39
  'path underneath your features/support directory or anywhere',
43
40
  "on Ruby's LOAD_PATH, for example in a Ruby gem."
44
- ]
41
+ ].freeze
45
42
 
46
43
  FORMAT_HELP = (BUILTIN_FORMATS.keys.sort.map do |key|
47
44
  " #{key}#{' ' * (max - key.length)} : #{BUILTIN_FORMATS[key][1]}"
48
45
  end) + FORMAT_HELP_MSG
49
- PROFILE_SHORT_FLAG = '-p'
50
- NO_PROFILE_SHORT_FLAG = '-P'
51
- PROFILE_LONG_FLAG = '--profile'
52
- NO_PROFILE_LONG_FLAG = '--no-profile'
53
- FAIL_FAST_FLAG = '--fail-fast'
54
- RETRY_FLAG = '--retry'
46
+ PROFILE_SHORT_FLAG = '-p'.freeze
47
+ NO_PROFILE_SHORT_FLAG = '-P'.freeze
48
+ PROFILE_LONG_FLAG = '--profile'.freeze
49
+ NO_PROFILE_LONG_FLAG = '--no-profile'.freeze
50
+ FAIL_FAST_FLAG = '--fail-fast'.freeze
51
+ RETRY_FLAG = '--retry'.freeze
55
52
  OPTIONS_WITH_ARGS = [
56
53
  '-r', '--require', '--i18n-keywords', '-f', '--format', '-o',
57
54
  '--out', '-t', '--tags', '-n', '--name', '-e', '--exclude',
58
55
  PROFILE_SHORT_FLAG, PROFILE_LONG_FLAG, RETRY_FLAG, '-l',
59
56
  '--lines', '--port', '-I', '--snippet-type'
60
- ]
61
- ORDER_TYPES = %w{defined random}
57
+ ].freeze
58
+ ORDER_TYPES = %w[defined random].freeze
62
59
  TAG_LIMIT_MATCHER = /(?<tag_name>\@\w+):(?<limit>\d+)/x
63
60
 
64
61
  def self.parse(args, out_stream, error_stream, options = {})
@@ -87,19 +84,17 @@ module Cucumber
87
84
  @options[key] = value
88
85
  end
89
86
 
90
- def parse!(args) # rubocop:disable Metrics/AbcSize
87
+ def parse!(args) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
91
88
  @args = args
92
89
  @expanded_args = @args.dup
93
90
 
94
91
  @args.extend(::OptionParser::Arguable)
95
92
 
96
- @args.options do |opts|
93
+ @args.options do |opts| # rubocop:disable Metrics/BlockLength
97
94
  opts.banner = banner
98
95
  opts.on('-r LIBRARY|DIR', '--require LIBRARY|DIR', *require_files_msg) { |lib| require_files(lib) }
99
96
 
100
- if Cucumber::JRUBY
101
- opts.on('-j DIR', '--jars DIR', 'Load all the jars under DIR') { |jars| load_jars(jars) }
102
- end
97
+ opts.on('-j DIR', '--jars DIR', 'Load all the jars under DIR') { |jars| load_jars(jars) } if Cucumber::JRUBY
103
98
 
104
99
  opts.on("#{RETRY_FLAG} ATTEMPTS", *retry_msg) { |v| set_option :retry, v.to_i }
105
100
  opts.on('--i18n-languages', *i18n_languages_msg) { list_languages_and_exit }
@@ -108,13 +103,13 @@ module Cucumber
108
103
  opts.on('-f FORMAT', '--format FORMAT', *format_msg, *FORMAT_HELP) do |v|
109
104
  add_option :formats, [*parse_formats(v), @out_stream]
110
105
  end
111
- opts.on('--init', *init_msg) { |v| initialize_project }
112
- opts.on('-o', '--out [FILE|DIR|URL]', *out_msg) { |v| out_stream v }
106
+ opts.on('--init', *init_msg) { |_v| initialize_project }
107
+ opts.on('-o', '--out [FILE|DIR]', *out_msg) { |v| out_stream v }
113
108
  opts.on('-t TAG_EXPRESSION', '--tags TAG_EXPRESSION', *tags_msg) { |v| add_tag v }
114
109
  opts.on('-n NAME', '--name NAME', *name_msg) { |v| add_option :name_regexps, /#{v}/ }
115
110
  opts.on('-e', '--exclude PATTERN', *exclude_msg) { |v| add_option :excludes, Regexp.new(v) }
116
111
  opts.on(PROFILE_SHORT_FLAG, "#{PROFILE_LONG_FLAG} PROFILE", *profile_short_flag_msg) { |v| add_profile v }
117
- opts.on(NO_PROFILE_SHORT_FLAG, NO_PROFILE_LONG_FLAG, *no_profile_short_flag_msg) { |v| disable_profile_loading }
112
+ opts.on(NO_PROFILE_SHORT_FLAG, NO_PROFILE_LONG_FLAG, *no_profile_short_flag_msg) { |_v| disable_profile_loading }
118
113
  opts.on('-c', '--[no-]color', *color_msg) { |v| color v }
119
114
  opts.on('-d', '--dry-run', *dry_run_msg) { set_dry_run_and_duration }
120
115
  opts.on('-m', '--no-multiline', "Don't print multiline strings and tables under steps.") { set_option :no_multiline }
@@ -140,11 +135,9 @@ module Cucumber
140
135
  [random] Shuffle scenarios before running.
141
136
  Specify SEED to reproduce the shuffling from a previous run.
142
137
  e.g. --order random:5738
143
- TEXT
138
+ TEXT
144
139
  @options[:order], @options[:seed] = *order.split(':')
145
- unless ORDER_TYPES.include?(@options[:order])
146
- fail "'#{@options[:order]}' is not a recognised order type. Please use one of #{ORDER_TYPES.join(", ")}."
147
- end
140
+ raise "'#{@options[:order]}' is not a recognised order type. Please use one of #{ORDER_TYPES.join(', ')}." unless ORDER_TYPES.include?(@options[:order])
148
141
  end
149
142
 
150
143
  opts.on_tail('--version', 'Show version.') { exit_ok(Cucumber::VERSION) }
@@ -156,7 +149,7 @@ TEXT
156
149
  extract_environment_variables
157
150
  @options[:paths] = @args.dup # whatver is left over
158
151
 
159
- check_formatter_stream_conflicts()
152
+ check_formatter_stream_conflicts
160
153
 
161
154
  merge_profiles
162
155
 
@@ -171,7 +164,7 @@ TEXT
171
164
  @options[:filters] ||= []
172
165
  end
173
166
 
174
- def check_formatter_stream_conflicts()
167
+ def check_formatter_stream_conflicts
175
168
  streams = @options[:formats].uniq.map { |(_, _, stream)| stream }
176
169
  return if streams == streams.uniq
177
170
  raise 'All but one formatter must use --out, only one can print to each stream (or STDOUT)'
@@ -219,7 +212,7 @@ TEXT
219
212
  def i18n_keywords_msg
220
213
  [
221
214
  'List keywords for in a particular language',
222
- %{Run with "--i18n help" to see all languages}
215
+ %(Run with "--i18n help" to see all languages)
223
216
  ]
224
217
  end
225
218
 
@@ -305,14 +298,10 @@ TEXT
305
298
 
306
299
  def out_msg
307
300
  [
308
- 'Write output to a file/directory/URL instead of STDOUT. This option',
301
+ 'Write output to a file/directory instead of STDOUT. This option',
309
302
  'applies to the previously specified --format, or the',
310
303
  'default format if no format is specified. Check the specific',
311
- "formatter's docs to see whether to pass a file, dir or URL.",
312
- "\n",
313
- 'When using a URL, the output of the formatter will be sent as the HTTP request body.',
314
- 'HTTP headers and request method can be set with cURL like options.',
315
- 'Example: --out "http://example.com -X POST -H Content-Type:text/json"'
304
+ "formatter's docs to see whether to pass a file or a dir."
316
305
  ]
317
306
  end
318
307
 
@@ -361,7 +350,7 @@ TEXT
361
350
  def language(lang)
362
351
  require 'gherkin/dialect'
363
352
 
364
- return indicate_invalid_language_and_exit(lang) unless ::Gherkin::DIALECTS.keys.include? lang
353
+ return indicate_invalid_language_and_exit(lang) unless ::Gherkin::DIALECTS.key?(lang)
365
354
  list_keywords_and_exit(lang)
366
355
  end
367
356
 
@@ -370,7 +359,7 @@ TEXT
370
359
  end
371
360
 
372
361
  def non_stdout_formats
373
- @options[:formats].select { |_, _, output| output != @out_stream }
362
+ @options[:formats].reject { |_, _, output| output == @out_stream }
374
363
  end
375
364
 
376
365
  def add_option(option, value)
@@ -378,8 +367,8 @@ TEXT
378
367
  end
379
368
 
380
369
  def add_tag(value)
381
- 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?('~')
382
- 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?(',')
370
+ raise("Found tags option '#{value}'. '~@tag' is no longer supported, use 'not @tag' instead.") if value.include?('~')
371
+ raise("Found tags option '#{value}'. '@tag1,@tag2' is no longer supported, use '@tag or @tag2' instead.") if value.include?(',')
383
372
  @options[:tag_expressions] << value.gsub(/(@\w+)(:\d+)?/, '\1')
384
373
  add_tag_limits(value)
385
374
  end
@@ -391,9 +380,7 @@ TEXT
391
380
  end
392
381
 
393
382
  def add_tag_limit(tag_limits, tag_name, limit)
394
- if tag_limits[tag_name] && tag_limits[tag_name] != limit
395
- raise "Inconsistent tag limits for #{tag_name}: #{tag_limits[tag_name]} and #{limit}"
396
- end
383
+ raise "Inconsistent tag limits for #{tag_name}: #{tag_limits[tag_name]} and #{limit}" if tag_limits[tag_name] && tag_limits[tag_name] != limit
397
384
  tag_limits[tag_name] = limit
398
385
  end
399
386
 
@@ -440,7 +427,7 @@ TEXT
440
427
  def extract_environment_variables
441
428
  @args.delete_if do |arg|
442
429
  if arg =~ /^(\w+)=(.*)$/
443
- @options[:env_vars][$1] = $2
430
+ @options[:env_vars][Regexp.last_match(1)] = Regexp.last_match(2)
444
431
  true
445
432
  end
446
433
  end
@@ -469,8 +456,8 @@ TEXT
469
456
  profile_args = profile_loader.args_from(profile)
470
457
  profile_options = Options.parse(
471
458
  profile_args, @out_stream, @error_stream,
472
- :skip_profile_information => true,
473
- :profile_loader => profile_loader
459
+ skip_profile_information: true,
460
+ profile_loader: profile_loader
474
461
  )
475
462
  reverse_merge(profile_options)
476
463
  end
@@ -478,14 +465,14 @@ TEXT
478
465
  def default_profile_should_be_used?
479
466
  @profiles.empty? &&
480
467
  profile_loader.cucumber_yml_defined? &&
481
- profile_loader.has_profile?(@default_profile)
468
+ profile_loader.profile?(@default_profile)
482
469
  end
483
470
 
484
471
  def profile_loader
485
472
  @profile_loader ||= ProfileLoader.new
486
473
  end
487
474
 
488
- def reverse_merge(other_options)
475
+ def reverse_merge(other_options) # rubocop:disable Metrics/AbcSize
489
476
  @options = other_options.options.merge(@options)
490
477
  @options[:require] += other_options[:require]
491
478
  @options[:excludes] += other_options[:excludes]
@@ -514,7 +501,7 @@ TEXT
514
501
  @options[:formats] = stdout_formats[0..0] + non_stdout_formats
515
502
  end
516
503
 
517
- @options[:retry] = other_options[:retry] if @options[:retry] == 0
504
+ @options[:retry] = other_options[:retry] if @options[:retry].zero?
518
505
 
519
506
  self
520
507
  end
@@ -550,7 +537,7 @@ TEXT
550
537
  ['but (code)', to_code_keywords_string(language.but_keywords)]
551
538
  ]
552
539
  )
553
- @out_stream.write(data.to_s({ color: false, prefixes: Hash.new('') }))
540
+ @out_stream.write(data.to_s(color: false, prefixes: Hash.new('')))
554
541
  Kernel.exit(0)
555
542
  end
556
543
 
@@ -561,7 +548,7 @@ TEXT
561
548
  [key, ::Gherkin::DIALECTS[key].fetch('name'), ::Gherkin::DIALECTS[key].fetch('native')]
562
549
  end
563
550
  )
564
- @out_stream.write(data.to_s({ color: false, prefixes: Hash.new('') }))
551
+ @out_stream.write(data.to_s(color: false, prefixes: Hash.new('')))
565
552
  Kernel.exit(0)
566
553
  end
567
554
 
@@ -575,20 +562,20 @@ TEXT
575
562
 
576
563
  def default_options
577
564
  {
578
- :strict => Cucumber::Core::Test::Result::StrictConfiguration.new,
579
- :require => [],
580
- :dry_run => false,
581
- :formats => [],
582
- :excludes => [],
583
- :tag_expressions => [],
584
- :tag_limits => {},
585
- :name_regexps => [],
586
- :env_vars => {},
587
- :diff_enabled => true,
588
- :snippets => true,
589
- :source => true,
590
- :duration => true,
591
- :retry => 0
565
+ strict: Cucumber::Core::Test::Result::StrictConfiguration.new,
566
+ require: [],
567
+ dry_run: false,
568
+ formats: [],
569
+ excludes: [],
570
+ tag_expressions: [],
571
+ tag_limits: {},
572
+ name_regexps: [],
573
+ env_vars: {},
574
+ diff_enabled: true,
575
+ snippets: true,
576
+ source: true,
577
+ duration: true,
578
+ retry: 0
592
579
  }
593
580
  end
594
581
  end