cucumber 7.1.0 → 9.2.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -27
  3. data/VERSION +1 -0
  4. data/lib/cucumber/cli/configuration.rb +4 -1
  5. data/lib/cucumber/cli/main.rb +5 -4
  6. data/lib/cucumber/cli/options.rb +73 -67
  7. data/lib/cucumber/cli/profile_loader.rb +6 -10
  8. data/lib/cucumber/cli/rerun_file.rb +1 -1
  9. data/lib/cucumber/configuration.rb +12 -6
  10. data/lib/cucumber/constantize.rb +1 -1
  11. data/lib/cucumber/deprecate.rb +6 -46
  12. data/lib/cucumber/errors.rb +3 -2
  13. data/lib/cucumber/events/envelope.rb +2 -0
  14. data/lib/cucumber/events/gherkin_source_parsed.rb +2 -0
  15. data/lib/cucumber/events/gherkin_source_read.rb +2 -0
  16. data/lib/cucumber/events/hook_test_step_created.rb +1 -2
  17. data/lib/cucumber/events/step_activated.rb +0 -6
  18. data/lib/cucumber/events/step_definition_registered.rb +0 -5
  19. data/lib/cucumber/events/test_case_created.rb +1 -2
  20. data/lib/cucumber/events/test_case_finished.rb +2 -0
  21. data/lib/cucumber/events/test_case_started.rb +2 -0
  22. data/lib/cucumber/events/test_run_finished.rb +2 -1
  23. data/lib/cucumber/events/test_step_created.rb +1 -2
  24. data/lib/cucumber/events/test_step_finished.rb +2 -0
  25. data/lib/cucumber/events/test_step_started.rb +2 -0
  26. data/lib/cucumber/events/undefined_parameter_type.rb +3 -2
  27. data/lib/cucumber/events.rb +1 -1
  28. data/lib/cucumber/file_specs.rb +2 -1
  29. data/lib/cucumber/filters/activate_steps.rb +1 -0
  30. data/lib/cucumber/filters/retry.rb +20 -1
  31. data/lib/cucumber/filters/tag_limits/verifier.rb +1 -3
  32. data/lib/cucumber/filters/tag_limits.rb +1 -3
  33. data/lib/cucumber/formatter/ansicolor.rb +70 -78
  34. data/lib/cucumber/formatter/ast_lookup.rb +16 -8
  35. data/lib/cucumber/formatter/backtrace_filter.rb +2 -1
  36. data/lib/cucumber/formatter/console.rb +26 -16
  37. data/lib/cucumber/formatter/console_counts.rb +3 -1
  38. data/lib/cucumber/formatter/console_issues.rb +10 -3
  39. data/lib/cucumber/formatter/curl_option_parser.rb +49 -0
  40. data/lib/cucumber/formatter/duration_extractor.rb +1 -0
  41. data/lib/cucumber/formatter/errors.rb +3 -0
  42. data/lib/cucumber/formatter/fail_fast.rb +1 -1
  43. data/lib/cucumber/formatter/fanout.rb +1 -1
  44. data/lib/cucumber/formatter/html.rb +2 -0
  45. data/lib/cucumber/formatter/http_io.rb +10 -137
  46. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
  47. data/lib/cucumber/formatter/io.rb +5 -3
  48. data/lib/cucumber/formatter/io_http_buffer.rb +88 -0
  49. data/lib/cucumber/formatter/json.rb +10 -12
  50. data/lib/cucumber/formatter/junit.rb +10 -7
  51. data/lib/cucumber/formatter/message_builder.rb +24 -8
  52. data/lib/cucumber/formatter/pretty.rb +24 -10
  53. data/lib/cucumber/formatter/progress.rb +1 -0
  54. data/lib/cucumber/formatter/publish_banner_printer.rb +0 -2
  55. data/lib/cucumber/formatter/query/hook_by_test_step.rb +3 -0
  56. data/lib/cucumber/formatter/query/pickle_by_test.rb +2 -0
  57. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +2 -0
  58. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +2 -0
  59. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +4 -0
  60. data/lib/cucumber/formatter/rerun.rb +5 -3
  61. data/lib/cucumber/formatter/summary.rb +1 -0
  62. data/lib/cucumber/formatter/unicode.rb +7 -7
  63. data/lib/cucumber/formatter/url_reporter.rb +3 -1
  64. data/lib/cucumber/formatter/usage.rb +3 -3
  65. data/lib/cucumber/gherkin/data_table_parser.rb +1 -0
  66. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +25 -27
  67. data/lib/cucumber/glue/dsl.rb +20 -25
  68. data/lib/cucumber/glue/hook.rb +6 -3
  69. data/lib/cucumber/glue/invoke_in_world.rb +5 -5
  70. data/lib/cucumber/glue/proto_world.rb +30 -34
  71. data/lib/cucumber/glue/registry_and_more.rb +15 -25
  72. data/lib/cucumber/glue/snippet.rb +4 -2
  73. data/lib/cucumber/glue/step_definition.rb +6 -3
  74. data/lib/cucumber/glue/world_factory.rb +2 -0
  75. data/lib/cucumber/hooks.rb +1 -0
  76. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +4 -1
  77. data/lib/cucumber/multiline_argument/data_table.rb +68 -80
  78. data/lib/cucumber/platform.rb +11 -16
  79. data/lib/cucumber/rake/task.rb +22 -15
  80. data/lib/cucumber/rspec/disable_option_parser.rb +6 -3
  81. data/lib/cucumber/running_test_case.rb +2 -1
  82. data/lib/cucumber/runtime/for_programming_languages.rb +1 -2
  83. data/lib/cucumber/runtime/meta_message_builder.rb +108 -0
  84. data/lib/cucumber/runtime/support_code.rb +3 -0
  85. data/lib/cucumber/runtime/user_interface.rb +7 -6
  86. data/lib/cucumber/runtime.rb +22 -38
  87. data/lib/cucumber/step_match.rb +6 -4
  88. data/lib/cucumber/step_match_search.rb +3 -2
  89. data/lib/cucumber/term/ansicolor.rb +74 -50
  90. data/lib/cucumber/term/banner.rb +3 -0
  91. data/lib/cucumber.rb +2 -1
  92. data/lib/simplecov_setup.rb +1 -1
  93. metadata +95 -244
  94. data/CHANGELOG.md +0 -3131
  95. data/CONTRIBUTING.md +0 -250
  96. data/lib/autotest/cucumber.rb +0 -8
  97. data/lib/autotest/cucumber_mixin.rb +0 -130
  98. data/lib/autotest/cucumber_rails.rb +0 -8
  99. data/lib/autotest/cucumber_rails_rspec.rb +0 -8
  100. data/lib/autotest/cucumber_rails_rspec2.rb +0 -8
  101. data/lib/autotest/cucumber_rspec.rb +0 -8
  102. data/lib/autotest/cucumber_rspec2.rb +0 -8
  103. data/lib/autotest/discover.rb +0 -13
  104. data/lib/cucumber/version +0 -1
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cucumber/messages'
4
+ require 'cucumber/ci_environment'
5
+
6
+ module Cucumber
7
+ class Runtime
8
+ # Builder to instantiate a Cucumber::Messages::Meta message filled-in with
9
+ # the runtime meta-data:
10
+ # - protocol version: the version of the Cucumber::Messages protocol
11
+ # - implementation: the name and version of the implementation (e.g. cucumber-ruby 8.0.0)
12
+ # - runtime: the name and version of the runtime (e.g. ruby 3.0.1)
13
+ # - os: the name and version of the operating system (e.g. linux 3.13.0-45-generic)
14
+ # - cpu: the name of the CPU (e.g. x86_64)
15
+ # - ci: information about the CI environment if any, including:
16
+ # - name: the name of the CI environment (e.g. Jenkins)
17
+ # - url: the URL of the CI environment (e.g. https://ci.example.com)
18
+ # - build_number: the build number of the CI environment (e.g. 123)
19
+ # - git: the git information of the CI environment if any
20
+ # - remote: the remote of the git repository (e.g. git@github.com:cucumber/cucumber-ruby.git)
21
+ # - revision: the revision of the git repository (e.g. abcdef)
22
+ # - branch: the name of the git branch (e.g. main)
23
+ # - tag: the name of the git tag (e.g. v1.0.0)
24
+ class MetaMessageBuilder
25
+ class << self
26
+ # Builds a Cucumber::Messages::Meta filled-in with the runtime meta-data
27
+ #
28
+ # @param [env] environment data from which the CI information will be
29
+ # retrieved (default ENV). Can be used to mock the environment for
30
+ # testing purpose.
31
+ #
32
+ # @return [Cucumber::Messages::Meta] the meta message
33
+ #
34
+ # @see Cucumber::Runtime::MetaMessageBuilder
35
+ #
36
+ # @example
37
+ # Cucumber::Runtime::MetaMessageBuilder.build_meta_message
38
+ #
39
+ def build_meta_message(env = ENV)
40
+ Cucumber::Messages::Meta.new(
41
+ protocol_version: protocol_version,
42
+ implementation: implementation,
43
+ runtime: runtime,
44
+ os: os,
45
+ cpu: cpu,
46
+ ci: ci(env)
47
+ )
48
+ end
49
+
50
+ private
51
+
52
+ def protocol_version
53
+ Cucumber::Messages::VERSION
54
+ end
55
+
56
+ def implementation
57
+ Cucumber::Messages::Product.new(
58
+ name: 'cucumber-ruby',
59
+ version: Cucumber::VERSION
60
+ )
61
+ end
62
+
63
+ def runtime
64
+ Cucumber::Messages::Product.new(
65
+ name: RUBY_ENGINE,
66
+ version: RUBY_VERSION
67
+ )
68
+ end
69
+
70
+ def os
71
+ Cucumber::Messages::Product.new(
72
+ name: RbConfig::CONFIG['target_os'],
73
+ version: Sys::Uname.uname.version
74
+ )
75
+ end
76
+
77
+ def cpu
78
+ Cucumber::Messages::Product.new(
79
+ name: RbConfig::CONFIG['target_cpu']
80
+ )
81
+ end
82
+
83
+ def ci(env)
84
+ ci_data = Cucumber::CiEnvironment.detect_ci_environment(env)
85
+ return nil unless ci_data
86
+
87
+ Cucumber::Messages::Ci.new(
88
+ name: ci_data[:name],
89
+ url: ci_data[:url],
90
+ build_number: ci_data[:buildNumber],
91
+ git: git_info(ci_data)
92
+ )
93
+ end
94
+
95
+ def git_info(ci_data)
96
+ return nil unless ci_data[:git]
97
+
98
+ Cucumber::Messages::Git.new(
99
+ remote: ci_data[:git][:remote],
100
+ revision: ci_data[:git][:revision],
101
+ branch: ci_data[:git][:branch],
102
+ tag: ci_data[:git][:tag]
103
+ )
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -72,6 +72,7 @@ module Cucumber
72
72
  def invoke_dynamic_step(step_name, multiline_argument, _location = nil)
73
73
  matches = step_matches(step_name)
74
74
  raise UndefinedDynamicStep, step_name if matches.empty?
75
+
75
76
  matches.first.invoke(multiline_argument)
76
77
  end
77
78
 
@@ -109,6 +110,7 @@ module Cucumber
109
110
 
110
111
  def apply_before_hooks(test_case)
111
112
  return test_case if test_case.test_steps.empty?
113
+
112
114
  scenario = RunningTestCase.new(test_case)
113
115
  hooks = registry.hooks_for(:before, scenario)
114
116
  BeforeHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
@@ -116,6 +118,7 @@ module Cucumber
116
118
 
117
119
  def apply_after_hooks(test_case)
118
120
  return test_case if test_case.test_steps.empty?
121
+
119
122
  scenario = RunningTestCase.new(test_case)
120
123
  hooks = registry.hooks_for(:after, scenario)
121
124
  AfterHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
@@ -21,8 +21,8 @@ module Cucumber
21
21
  # that makes a sound before invoking #ask.
22
22
  #
23
23
  def ask(question, timeout_seconds)
24
- STDOUT.puts(question)
25
- STDOUT.flush
24
+ $stdout.puts(question)
25
+ $stdout.flush
26
26
  puts(question)
27
27
 
28
28
  answer = if Cucumber::JRUBY
@@ -32,6 +32,7 @@ module Cucumber
32
32
  end
33
33
 
34
34
  raise("Waited for input for #{timeout_seconds} seconds, then timed out.") unless answer
35
+
35
36
  puts(answer)
36
37
  answer
37
38
  end
@@ -40,15 +41,15 @@ module Cucumber
40
41
  # be a path to a file, or if it's an image it may also be a Base64 encoded image.
41
42
  # The embedded data may or may not be ignored, depending on what kind of formatter(s) are active.
42
43
  #
43
- def attach(src, media_type)
44
- @visitor.attach(src, media_type)
44
+ def attach(src, media_type, filename)
45
+ @visitor.attach(src, media_type, filename)
45
46
  end
46
47
 
47
48
  private
48
49
 
49
50
  def mri_gets(timeout_seconds)
50
51
  Timeout.timeout(timeout_seconds) do
51
- STDIN.gets
52
+ $stdin.gets
52
53
  end
53
54
  rescue Timeout::Error
54
55
  nil
@@ -57,7 +58,7 @@ module Cucumber
57
58
  def jruby_gets(timeout_seconds)
58
59
  answer = nil
59
60
  t = java.lang.Thread.new do
60
- answer = STDIN.gets
61
+ answer = $stdin.gets
61
62
  end
62
63
  t.start
63
64
  t.join(timeout_seconds * 1000)
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'cucumber/configuration'
5
- require 'cucumber/create_meta'
6
5
  require 'cucumber/deprecate'
7
6
  require 'cucumber/load_path'
8
7
  require 'cucumber/formatter/duration'
@@ -13,6 +12,7 @@ require 'cucumber/gherkin/i18n'
13
12
  require 'cucumber/glue/registry_wrapper'
14
13
  require 'cucumber/step_match_search'
15
14
  require 'cucumber/messages'
15
+ require 'cucumber/runtime/meta_message_builder'
16
16
  require 'sys/uname'
17
17
 
18
18
  module Cucumber
@@ -26,8 +26,8 @@ module Cucumber
26
26
  attr_reader :path
27
27
 
28
28
  def initialize(original_exception, path)
29
- super(original_exception)
30
29
  @path = path
30
+ super(original_exception)
31
31
  end
32
32
  end
33
33
 
@@ -37,6 +37,7 @@ module Cucumber
37
37
  class FeatureFolderNotFoundException < RuntimeError
38
38
  def initialize(path)
39
39
  @path = path
40
+ super
40
41
  end
41
42
 
42
43
  def message
@@ -65,23 +66,20 @@ module Cucumber
65
66
  @support_code.configure(@configuration)
66
67
  end
67
68
 
68
- require 'cucumber/wire/plugin'
69
69
  def run!
70
70
  @configuration.notify :envelope, Cucumber::Messages::Envelope.new(
71
- meta: Cucumber::CreateMeta.create_meta('cucumber-ruby', Cucumber::VERSION)
71
+ meta: MetaMessageBuilder.build_meta_message
72
72
  )
73
73
 
74
74
  load_step_definitions
75
- fire_after_configuration_hook
76
75
  fire_install_plugin_hook
77
- install_wire_plugin
78
76
  fire_before_all_hook unless dry_run?
79
77
  # TODO: can we remove this state?
80
78
  self.visitor = report
81
79
 
82
80
  receiver = Test::Runner.new(@configuration.event_bus)
83
81
  compile features, receiver, filters, @configuration.event_bus
84
- @configuration.notify :test_run_finished
82
+ @configuration.notify :test_run_finished, !failure?
85
83
 
86
84
  fire_after_all_hook unless dry_run?
87
85
  end
@@ -112,21 +110,25 @@ module Cucumber
112
110
  Core::Test::DocString.new(string_without_triple_quotes, content_type)
113
111
  end
114
112
 
115
- private
116
-
117
- def fire_after_configuration_hook #:nodoc:
118
- @support_code.fire_hook(:after_configuration, @configuration)
113
+ def failure?
114
+ if @configuration.wip?
115
+ summary_report.test_cases.total_passed.positive?
116
+ else
117
+ !summary_report.ok?(strict: @configuration.strict)
118
+ end
119
119
  end
120
120
 
121
- def fire_install_plugin_hook #:nodoc:
121
+ private
122
+
123
+ def fire_install_plugin_hook # :nodoc:
122
124
  @support_code.fire_hook(:install_plugin, @configuration, registry_wrapper)
123
125
  end
124
126
 
125
- def fire_before_all_hook #:nodoc:
127
+ def fire_before_all_hook # :nodoc:
126
128
  @support_code.fire_hook(:before_all)
127
129
  end
128
130
 
129
- def fire_after_all_hook #:nodoc:
131
+ def fire_after_all_hook # :nodoc:
130
132
  @support_code.fire_hook(:after_all)
131
133
  end
132
134
 
@@ -148,8 +150,8 @@ module Cucumber
148
150
  end
149
151
 
150
152
  class NormalisedEncodingFile
151
- COMMENT_OR_EMPTY_LINE_PATTERN = /^\s*#|^\s*$/ #:nodoc:
152
- ENCODING_PATTERN = /^\s*#\s*encoding\s*:\s*([^\s]+)/ #:nodoc:
153
+ COMMENT_OR_EMPTY_LINE_PATTERN = /^\s*#|^\s*$/.freeze # :nodoc:
154
+ ENCODING_PATTERN = /^\s*#\s*encoding\s*:\s*([^\s]+)/.freeze # :nodoc:
153
155
 
154
156
  def self.read(path)
155
157
  new(path).read
@@ -189,6 +191,7 @@ module Cucumber
189
191
 
190
192
  def report
191
193
  return @report if @report
194
+
192
195
  reports = [summary_report] + formatters
193
196
  reports << fail_fast_report if @configuration.fail_fast?
194
197
  reports << publish_banner_printer unless @configuration.publish_quiet?
@@ -217,10 +220,12 @@ module Cucumber
217
220
  def create_formatter(factory, formatter_options, path_or_io)
218
221
  if accept_options?(factory)
219
222
  return factory.new(@configuration, formatter_options) if path_or_io.nil?
223
+
220
224
  factory.new(@configuration.with_options(out_stream: path_or_io),
221
225
  formatter_options)
222
226
  else
223
227
  return factory.new(@configuration) if path_or_io.nil?
228
+
224
229
  factory.new(@configuration.with_options(out_stream: path_or_io))
225
230
  end
226
231
  end
@@ -229,17 +234,8 @@ module Cucumber
229
234
  factory.instance_method(:initialize).arity > 1
230
235
  end
231
236
 
232
- def failure?
233
- if @configuration.wip?
234
- summary_report.test_cases.total_passed > 0
235
- else
236
- !summary_report.ok?(@configuration.strict)
237
- end
238
- end
239
- public :failure?
240
-
241
237
  require 'cucumber/core/test/filters'
242
- def filters # rubocop:disable Metrics/AbcSize
238
+ def filters
243
239
  tag_expressions = @configuration.tag_expressions
244
240
  name_regexps = @configuration.name_regexps
245
241
  tag_limits = @configuration.tag_limits
@@ -278,18 +274,6 @@ module Cucumber
278
274
  @support_code.load_files!(files)
279
275
  end
280
276
 
281
- def install_wire_plugin
282
- return if Cucumber::Wire::Plugin.installed?
283
- return unless @configuration.all_files_to_load.any? { |f| f =~ /\.wire$/ }
284
-
285
- Cucumber::Wire::Plugin.new(@configuration, registry_wrapper).install
286
- Cucumber.deprecate(
287
- 'See https://github.com/cucumber/cucumber-ruby/blob/main/UPGRADING.md#upgrading-to-710 for more info',
288
- ' built-in usage of the wire protocol',
289
- '8.0.0'
290
- )
291
- end
292
-
293
277
  def registry_wrapper
294
278
  Cucumber::Glue::RegistryWrapper.new(@support_code.registry)
295
279
  end
@@ -4,11 +4,12 @@ require 'cucumber/multiline_argument'
4
4
 
5
5
  module Cucumber
6
6
  # Represents the match found between a Test Step and its activation
7
- class StepMatch #:nodoc:
7
+ class StepMatch # :nodoc:
8
8
  attr_reader :step_definition, :step_arguments
9
9
 
10
10
  def initialize(step_definition, step_name, step_arguments)
11
11
  raise "step_arguments can't be nil (but it can be an empty array)" if step_arguments.nil?
12
+
12
13
  @step_definition = step_definition
13
14
  @name_to_match = step_name
14
15
  @step_arguments = step_arguments
@@ -77,7 +78,7 @@ module Cucumber
77
78
 
78
79
  replacement = if block_given?
79
80
  yield(group.value)
80
- elsif Proc == format.class
81
+ elsif format.instance_of?(Proc)
81
82
  format.call(group.value)
82
83
  else
83
84
  format % group.value
@@ -90,7 +91,7 @@ module Cucumber
90
91
  s
91
92
  end
92
93
 
93
- def inspect #:nodoc:
94
+ def inspect # :nodoc:
94
95
  "#<#{self.class}: #{location}>"
95
96
  end
96
97
  end
@@ -101,7 +102,7 @@ module Cucumber
101
102
  end
102
103
  end
103
104
 
104
- class NoStepMatch #:nodoc:
105
+ class NoStepMatch # :nodoc:
105
106
  attr_reader :step_definition, :name
106
107
 
107
108
  def initialize(step, name)
@@ -115,6 +116,7 @@ module Cucumber
115
116
 
116
117
  def location
117
118
  raise "No location for #{@step}" unless @step.location
119
+
118
120
  @step.location
119
121
  end
120
122
 
@@ -20,6 +20,7 @@ module Cucumber
20
20
  def call(step_name)
21
21
  result = @search.call(step_name)
22
22
  raise Cucumber::Ambiguous.new(step_name, result, @configuration.guess?) if result.length > 1
23
+
23
24
  result
24
25
  end
25
26
  end
@@ -35,7 +36,7 @@ module Cucumber
35
36
 
36
37
  private
37
38
 
38
- def best_matches(_step_name, step_matches) #:nodoc:
39
+ def best_matches(_step_name, step_matches) # :nodoc:
39
40
  no_groups = step_matches.select { |step_match| step_match.args.empty? }
40
41
  max_arg_length = step_matches.map { |step_match| step_match.args.length }.max
41
42
  top_groups = step_matches.select { |step_match| step_match.args.length == max_arg_length }
@@ -54,7 +55,7 @@ module Cucumber
54
55
 
55
56
  require 'delegate'
56
57
  class CachesStepMatch < SimpleDelegator
57
- def call(step_name) #:nodoc:
58
+ def call(step_name) # :nodoc:
58
59
  @match_cache ||= {}
59
60
 
60
61
  matches = @match_cache[step_name]
@@ -2,8 +2,28 @@
2
2
 
3
3
  module Cucumber
4
4
  module Term
5
- # The ANSIColor module can be used for namespacing and mixed into your own
6
- # classes.
5
+ # This module allows to colorize text using ANSI escape sequences.
6
+ #
7
+ # Include the module in your class and use its methods to colorize text.
8
+ #
9
+ # Example:
10
+ #
11
+ # require 'cucumber/term/ansicolor'
12
+ #
13
+ # class MyFormatter
14
+ # include Cucumber::Term::ANSIColor
15
+ #
16
+ # def initialize(config)
17
+ # $stdout.puts yellow("Initializing formatter")
18
+ # $stdout.puts green("Coloring is active \o/") if Cucumber::Term::ANSIColor.coloring?
19
+ # $stdout.puts grey("Feature path:") + blue(bold(config.feature_dirs))
20
+ # end
21
+ # end
22
+ #
23
+ # To see what colours and effects are available, just run this in your shell:
24
+ #
25
+ # ruby -e "require 'rubygems'; require 'cucumber/term/ansicolor'; puts Cucumber::Term::ANSIColor.attributes"
26
+ #
7
27
  module ANSIColor
8
28
  # :stopdoc:
9
29
  ATTRIBUTES = [
@@ -27,6 +47,7 @@ module Cucumber
27
47
  [:magenta, 35],
28
48
  [:cyan, 36],
29
49
  [:white, 37],
50
+ [:grey, 90],
30
51
  [:on_black, 40],
31
52
  [:on_red, 41],
32
53
  [:on_green, 42],
@@ -40,72 +61,75 @@ module Cucumber
40
61
  ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
41
62
  # :startdoc:
42
63
 
43
- # Returns true, if the coloring function of this module
44
- # is switched on, false otherwise.
45
- def self.coloring?
46
- @coloring
47
- end
64
+ # Regular expression that is used to scan for ANSI-sequences while
65
+ # uncoloring strings.
66
+ COLORED_REGEXP = /\e\[(?:[34][0-7]|[0-9])?m/.freeze
48
67
 
49
- # Turns the coloring on or off globally, so you can easily do
50
- # this for example:
51
- # Cucumber::Term::ANSIColor::coloring = STDOUT.isatty
52
- def self.coloring=(val)
53
- @coloring = val
54
- end
55
- self.coloring = true
68
+ @coloring = true
56
69
 
57
- # rubocop:disable Security/Eval
58
- ATTRIBUTES.each do |c, v|
59
- eval <<-END_EVAL, binding, __FILE__, __LINE__ + 1
60
- def #{c}(string = nil)
61
- result = String.new
62
- result << "\e[#{v}m" if Cucumber::Term::ANSIColor.coloring?
63
- if block_given?
64
- result << yield
65
- elsif string
66
- result << string
67
- elsif respond_to?(:to_str)
68
- result << to_str
69
- else
70
- return result #only switch on
71
- end
72
- result << "\e[0m" if Cucumber::Term::ANSIColor.coloring?
73
- result
74
- end
75
- END_EVAL
76
- end
77
- # rubocop:enable Security/Eval
70
+ class << self
71
+ # Turns the coloring on or off globally, so you can easily do
72
+ # this for example:
73
+ # Cucumber::Term::ANSIColor::coloring = $stdout.isatty
74
+ attr_accessor :coloring
78
75
 
79
- # Regular expression that is used to scan for ANSI-sequences while
80
- # uncoloring strings.
81
- COLORED_REGEXP = /\e\[(?:[34][0-7]|[0-9])?m/
76
+ # Returns true, if the coloring function of this module
77
+ # is switched on, false otherwise.
78
+ alias coloring? :coloring
79
+
80
+ def included(klass)
81
+ return unless klass == String
82
82
 
83
- def self.included(klass)
84
- return unless klass == String
85
- ATTRIBUTES.delete(:clear)
86
- ATTRIBUTE_NAMES.delete(:clear)
83
+ ATTRIBUTES.delete(:clear)
84
+ ATTRIBUTE_NAMES.delete(:clear)
85
+ end
87
86
  end
88
87
 
89
- # Returns an uncolored version of the string, that is all
88
+ ATTRIBUTES.each do |color_name, color_code|
89
+ define_method(color_name) do |text = nil, &block|
90
+ if block
91
+ colorize(block.call, color_code)
92
+ elsif text
93
+ colorize(text, color_code)
94
+ elsif respond_to?(:to_str)
95
+ colorize(to_str, color_code)
96
+ else
97
+ colorize(nil, color_code) # switch coloration on
98
+ end
99
+ end
100
+ end
101
+
102
+ # Returns an uncolored version of the string
90
103
  # ANSI-sequences are stripped from the string.
91
- def uncolored(string = nil)
104
+ def uncolored(text = nil)
92
105
  if block_given?
93
- yield.gsub(COLORED_REGEXP, '')
94
- elsif string
95
- string.gsub(COLORED_REGEXP, '')
106
+ uncolorize(yield)
107
+ elsif text
108
+ uncolorize(text)
96
109
  elsif respond_to?(:to_str)
97
- to_str.gsub(COLORED_REGEXP, '')
110
+ uncolorize(to_str)
98
111
  else
99
112
  ''
100
113
  end
101
114
  end
102
115
 
103
- module_function
104
-
105
116
  # Returns an array of all Cucumber::Term::ANSIColor attributes as symbols.
106
117
  def attributes
107
118
  ATTRIBUTE_NAMES
108
119
  end
120
+
121
+ private
122
+
123
+ def colorize(text, color_code)
124
+ return String.new(text || '') unless Cucumber::Term::ANSIColor.coloring?
125
+ return "\e[#{color_code}m" unless text
126
+
127
+ "\e[#{color_code}m#{text}\e[0m"
128
+ end
129
+
130
+ def uncolorize(string)
131
+ string.gsub(COLORED_REGEXP, '')
132
+ end
109
133
  end
110
134
  end
111
135
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/term/ansicolor'
2
4
 
3
5
  module Cucumber
@@ -30,6 +32,7 @@ module Cucumber
30
32
 
31
33
  def display_span(span)
32
34
  return apply_modifiers(span.shift, span) if span.is_a?(Array)
35
+
33
36
  span
34
37
  end
35
38
 
data/lib/cucumber.rb CHANGED
@@ -14,7 +14,8 @@ module Cucumber
14
14
 
15
15
  def logger
16
16
  return @log if @log
17
- @log = Logger.new(STDOUT)
17
+
18
+ @log = Logger.new($stdout)
18
19
  @log.level = Logger::INFO
19
20
  @log
20
21
  end
@@ -7,7 +7,7 @@ if ENV['SIMPLECOV']
7
7
 
8
8
  require 'simplecov'
9
9
 
10
- SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/..'))
10
+ SimpleCov.root(File.expand_path("#{File.dirname(__FILE__)}/.."))
11
11
  SimpleCov.start do
12
12
  add_filter 'iso-8859-1_steps.rb'
13
13
  add_filter '.-ruby-core/'