cucumber 3.2.0 → 4.0.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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