cucumber 3.1.2 → 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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -13
  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 +53 -62
  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 +3 -3
  33. data/lib/cucumber/formatter/json.rb +92 -110
  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 +36 -29
  77. data/lib/cucumber/events/gherkin_source_parsed.rb~ +0 -14
  78. data/lib/cucumber/formatter/ast_lookup.rb~ +0 -9
  79. data/lib/cucumber/formatter/cucumber.css +0 -286
  80. data/lib/cucumber/formatter/cucumber.sass +0 -247
  81. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  82. data/lib/cucumber/formatter/html.rb +0 -611
  83. data/lib/cucumber/formatter/html_builder.rb +0 -121
  84. data/lib/cucumber/formatter/inline-js.js +0 -30
  85. data/lib/cucumber/formatter/jquery-min.js +0 -154
  86. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  87. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  88. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  89. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  90. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  91. data/lib/cucumber/step_argument.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fef34be35b9337e5d78fe68a0b9e642e96a5bc8e
4
- data.tar.gz: 5331fac4008b678c3bdc18ec18f4df77e3e67bfb
3
+ metadata.gz: 272094a2efb99945d2d0e3e6a91bae0b855428d0
4
+ data.tar.gz: 400106f2e8a065a57bb9d85171b5fa7e98999d3a
5
5
  SHA512:
6
- metadata.gz: 560857486693d265017f21421942be4bc737f852d2972cd5a76c93f678ffe4ac06a0fd58e91f52b7ccb2d5c63156c2af13cb2e11e2bdaf9e194e516ddd663387
7
- data.tar.gz: e3ecdbb8d5a93e5e20d0e72a46be9ccb10021b12caa7d023cd3f16e845882331231764fb772cf7d1935c4db724166dbbe3eb40bbda33a4a84760ff7bd296e54a
6
+ metadata.gz: 7e4c314d1e1b30f1d8e5ef171a7fb5ca1120bd9cd9c2ec2f1e353f7ee38d74ddc04771a8506c62ef4e71c9b58aeb6f28dccd3d2d979f2119dcc10b30c2ca7d2e
7
+ data.tar.gz: 854f93e0396ebc737e6f5f525028654042b96387b90c12ae7b41f65cd76e03668cf50c9a0a9517455f080a76b5c21a4825b3fe2f51b353471a91e45f47cb5139
@@ -10,6 +10,74 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
10
10
 
11
11
  ----
12
12
 
13
+ ## [In Git](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.1...master) (Not released)
14
+
15
+ ### Added
16
+
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))
68
+
69
+ ### Fixed
70
+
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))
80
+
13
81
  ## [3.1.2](https://github.com/cucumber/cucumber-ruby/compare/v3.1.1...v3.1.2) (2018-07-13)
14
82
 
15
83
  ### Changed
@@ -89,13 +157,6 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
89
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))
90
158
  * Handle the `--retry` option in profiles ([#1050](https://github.com/cucumber/cucumber-ruby/issues/1050) [@brasmusson](https://github.com/brasmusson))
91
159
 
92
- ### Improved
93
-
94
- * Exclude the legacy_api from rubocop, regenerate Rubocop Todo ([@jaysonesmith](https://github.com/jaysonesmith), [@brasmusson](https://github.com/brasmusson))
95
- * Review and handle excluded/ignored cops ([#1208](https://github.com/cucumber/cucumber-ruby/pull/1208) [@jaysonesmith](https://github.com/jaysonesmith))
96
- * Fix SymbolProc issues ([#1212](https://github.com/cucumber/cucumber-ruby/pull/1212) [@jaysonesmith](https://github.com/jaysonesmith))
97
- * Fix TrailingBlankLines ([#1211](https://github.com/cucumber/cucumber-ruby/pull/1211) [@jaysonesmith](https://github.com/jaysonesmith))
98
-
99
160
  ## [3.0.1](https://github.com/cucumber/cucumber-ruby/compare/v3.0.0...3.0.1) (2017-09-29)
100
161
 
101
162
  ### Fixed
@@ -131,12 +192,6 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
131
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))
132
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))
133
194
  * Use past tense in event names (`xStarting` -> `xStarted`) ([#1166](https://github.com/cucumber/cucumber-ruby/issues/1166) @brasmusson).
134
- * Fix Lint/DeprecatedClassMethods ([#1172](https://github.com/cucumber/cucumber-ruby/issues/1172) [jaysonesmith](https://github.com/jaysonesmith))
135
- * Fix Lint/DuplicateMethods ([#1173](https://github.com/cucumber/cucumber-ruby/issues/1173) [jaysonesmith](https://github.com/jaysonesmith))
136
- * 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))
137
- * Fix Style/AlignArray ([#1177](https://github.com/cucumber/cucumber-ruby/issues/1177) [jaysonesmith](https://github.com/jaysonesmith))
138
- * Fix Style/AndOr ([#1178](https://github.com/cucumber/cucumber-ruby/issues/1178) [jaysonesmith](https://github.com/jaysonesmith))
139
- * Fix Multiple Cops ([#1179](https://github.com/cucumber/cucumber-ruby/issues/1179) [jaysonesmith](https://github.com/jaysonesmith))
140
195
 
141
196
  ## [3.0.0.pre.2](https://github.com/cucumber/cucumber-ruby/compare/v2.4.0...v3.0.0.pre.2)
142
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 }
106
+ opts.on('--init', *init_msg) { |_v| initialize_project }
112
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
 
@@ -357,7 +350,7 @@ TEXT
357
350
  def language(lang)
358
351
  require 'gherkin/dialect'
359
352
 
360
- 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)
361
354
  list_keywords_and_exit(lang)
362
355
  end
363
356
 
@@ -366,7 +359,7 @@ TEXT
366
359
  end
367
360
 
368
361
  def non_stdout_formats
369
- @options[:formats].select { |_, _, output| output != @out_stream }
362
+ @options[:formats].reject { |_, _, output| output == @out_stream }
370
363
  end
371
364
 
372
365
  def add_option(option, value)
@@ -374,8 +367,8 @@ TEXT
374
367
  end
375
368
 
376
369
  def add_tag(value)
377
- 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?('~')
378
- 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?(',')
379
372
  @options[:tag_expressions] << value.gsub(/(@\w+)(:\d+)?/, '\1')
380
373
  add_tag_limits(value)
381
374
  end
@@ -387,9 +380,7 @@ TEXT
387
380
  end
388
381
 
389
382
  def add_tag_limit(tag_limits, tag_name, limit)
390
- if tag_limits[tag_name] && tag_limits[tag_name] != limit
391
- raise "Inconsistent tag limits for #{tag_name}: #{tag_limits[tag_name]} and #{limit}"
392
- 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
393
384
  tag_limits[tag_name] = limit
394
385
  end
395
386
 
@@ -436,7 +427,7 @@ TEXT
436
427
  def extract_environment_variables
437
428
  @args.delete_if do |arg|
438
429
  if arg =~ /^(\w+)=(.*)$/
439
- @options[:env_vars][$1] = $2
430
+ @options[:env_vars][Regexp.last_match(1)] = Regexp.last_match(2)
440
431
  true
441
432
  end
442
433
  end
@@ -465,8 +456,8 @@ TEXT
465
456
  profile_args = profile_loader.args_from(profile)
466
457
  profile_options = Options.parse(
467
458
  profile_args, @out_stream, @error_stream,
468
- :skip_profile_information => true,
469
- :profile_loader => profile_loader
459
+ skip_profile_information: true,
460
+ profile_loader: profile_loader
470
461
  )
471
462
  reverse_merge(profile_options)
472
463
  end
@@ -474,14 +465,14 @@ TEXT
474
465
  def default_profile_should_be_used?
475
466
  @profiles.empty? &&
476
467
  profile_loader.cucumber_yml_defined? &&
477
- profile_loader.has_profile?(@default_profile)
468
+ profile_loader.profile?(@default_profile)
478
469
  end
479
470
 
480
471
  def profile_loader
481
472
  @profile_loader ||= ProfileLoader.new
482
473
  end
483
474
 
484
- def reverse_merge(other_options)
475
+ def reverse_merge(other_options) # rubocop:disable Metrics/AbcSize
485
476
  @options = other_options.options.merge(@options)
486
477
  @options[:require] += other_options[:require]
487
478
  @options[:excludes] += other_options[:excludes]
@@ -510,7 +501,7 @@ TEXT
510
501
  @options[:formats] = stdout_formats[0..0] + non_stdout_formats
511
502
  end
512
503
 
513
- @options[:retry] = other_options[:retry] if @options[:retry] == 0
504
+ @options[:retry] = other_options[:retry] if @options[:retry].zero?
514
505
 
515
506
  self
516
507
  end
@@ -546,7 +537,7 @@ TEXT
546
537
  ['but (code)', to_code_keywords_string(language.but_keywords)]
547
538
  ]
548
539
  )
549
- @out_stream.write(data.to_s({ color: false, prefixes: Hash.new('') }))
540
+ @out_stream.write(data.to_s(color: false, prefixes: Hash.new('')))
550
541
  Kernel.exit(0)
551
542
  end
552
543
 
@@ -557,7 +548,7 @@ TEXT
557
548
  [key, ::Gherkin::DIALECTS[key].fetch('name'), ::Gherkin::DIALECTS[key].fetch('native')]
558
549
  end
559
550
  )
560
- @out_stream.write(data.to_s({ color: false, prefixes: Hash.new('') }))
551
+ @out_stream.write(data.to_s(color: false, prefixes: Hash.new('')))
561
552
  Kernel.exit(0)
562
553
  end
563
554
 
@@ -571,20 +562,20 @@ TEXT
571
562
 
572
563
  def default_options
573
564
  {
574
- :strict => Cucumber::Core::Test::Result::StrictConfiguration.new,
575
- :require => [],
576
- :dry_run => false,
577
- :formats => [],
578
- :excludes => [],
579
- :tag_expressions => [],
580
- :tag_limits => {},
581
- :name_regexps => [],
582
- :env_vars => {},
583
- :diff_enabled => true,
584
- :snippets => true,
585
- :source => true,
586
- :duration => true,
587
- :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
588
579
  }
589
580
  end
590
581
  end