cucumber 4.1.0 → 5.3.0

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.
@@ -19,10 +19,10 @@ module Cucumber
19
19
  '--format=json',
20
20
  "Please use --format=message and stand-alone json-formatter.\n" \
21
21
  'json-formatter homepage: https://github.com/cucumber/cucumber/tree/master/json-formatter#cucumber-json-formatter',
22
- '5.0.0'
22
+ '6.0.0'
23
23
  )
24
24
 
25
- @io = ensure_io(config.out_stream)
25
+ @io = ensure_io(config.out_stream, config.error_stream)
26
26
  @ast_lookup = AstLookup.new(config)
27
27
  @feature_hashes = []
28
28
  @step_or_hook_hash = {}
@@ -106,7 +106,7 @@ module Cucumber
106
106
  write_file(feature_result_filename(feature_data[:uri]), @testsuite.target!)
107
107
  end
108
108
 
109
- def create_output_string(test_case, scenario, result, row_name) # rubocop:disable Metrics/PerceivedComplexity
109
+ def create_output_string(test_case, scenario, result, row_name)
110
110
  scenario_source = @ast_lookup.scenario_source(test_case)
111
111
  keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
112
112
  output = "#{keyword}: #{scenario}\n\n"
@@ -132,9 +132,12 @@ module Cucumber
132
132
  duration = ResultBuilder.new(result).test_case_duration
133
133
  @current_feature_data[:time] += duration
134
134
  classname = @current_feature_data[:feature].name
135
+ filename = @current_feature_data[:uri]
135
136
  name = scenario_designation
136
137
 
137
- @current_feature_data[:builder].testcase(classname: classname, name: name, time: format('%<duration>.6f', duration: duration)) do
138
+ testcase_attributes = get_testcase_attributes(classname, name, duration, filename)
139
+
140
+ @current_feature_data[:builder].testcase(testcase_attributes) do
138
141
  if !result.passed? && result.ok?(@config.strict)
139
142
  @current_feature_data[:builder].skipped
140
143
  @current_feature_data[:skipped] += 1
@@ -157,6 +160,20 @@ module Cucumber
157
160
  @current_feature_data[:tests] += 1
158
161
  end
159
162
 
163
+ def get_testcase_attributes(classname, name, duration, filename)
164
+ { classname: classname, name: name, time: format('%<duration>.6f', duration: duration) }.tap do |attributes|
165
+ attributes[:file] = filename if add_fileattribute?
166
+ end
167
+ end
168
+
169
+ def add_fileattribute?
170
+ return false if @config.formats.nil? || @config.formats.empty?
171
+
172
+ !!@config.formats.find do |format|
173
+ format.first == 'junit' && format.dig(1, 'fileattribute') == 'true'
174
+ end
175
+ end
176
+
160
177
  def get_backtrace_object(result)
161
178
  if result.failed?
162
179
  result.exception
@@ -10,7 +10,7 @@ module Cucumber
10
10
  include Io
11
11
 
12
12
  def initialize(config)
13
- @io = ensure_io(config.out_stream)
13
+ @io = ensure_io(config.out_stream, config.error_stream)
14
14
  super(config)
15
15
  end
16
16
 
@@ -32,7 +32,7 @@ module Cucumber
32
32
  private :in_scenario_outline, :print_background_steps
33
33
 
34
34
  def initialize(config)
35
- @io = ensure_io(config.out_stream)
35
+ @io = ensure_io(config.out_stream, config.error_stream)
36
36
  @config = config
37
37
  @options = config.to_hash
38
38
  @snippets_input = []
@@ -19,7 +19,7 @@ module Cucumber
19
19
 
20
20
  def initialize(config)
21
21
  @config = config
22
- @io = ensure_io(config.out_stream)
22
+ @io = ensure_io(config.out_stream, config.error_stream)
23
23
  @snippets_input = []
24
24
  @undefined_parameter_types = []
25
25
  @total_duration = 0
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cucumber/term/banner'
4
+
5
+ module Cucumber
6
+ module Formatter
7
+ class PublishBannerPrinter
8
+ include Term::Banner
9
+
10
+ def initialize(configuration)
11
+ return if configuration.publish_enabled?
12
+
13
+ configuration.on_event :test_run_finished do |_event|
14
+ display_publish_ad(configuration.error_stream)
15
+ end
16
+ end
17
+
18
+ # rubocop:disable Metrics/MethodLength
19
+ def display_publish_ad(io)
20
+ display_banner(
21
+ [
22
+ [
23
+ 'Share your Cucumber Report with your team at ',
24
+ link('https://reports.cucumber.io')
25
+ ],
26
+ '',
27
+ [
28
+ 'Command line option: ',
29
+ highlight('--publish')
30
+ ],
31
+ [
32
+ 'Environment variable: ',
33
+ highlight('CUCUMBER_PUBLISH_ENABLED'),
34
+ '=',
35
+ highlight('true')
36
+ ],
37
+ [
38
+ 'cucumber.yml: ',
39
+ highlight('default: --publish')
40
+ ],
41
+ '',
42
+ [
43
+ 'More information at ',
44
+ link('https://reports.cucumber.io/docs/cucumber-ruby')
45
+ ],
46
+ '',
47
+ [
48
+ 'To disable this message, specify ',
49
+ pre('CUCUMBER_PUBLISH_QUIET=true'),
50
+ ' or use the '
51
+ ],
52
+ [
53
+ pre('--publish-quiet'),
54
+ ' option. You can also add this to your ',
55
+ pre('cucumber.yml:')
56
+ ],
57
+ [pre('default: --publish-quiet')]
58
+ ],
59
+ io
60
+ )
61
+ end
62
+ # rubocop:enable Metrics/MethodLength
63
+
64
+ def highlight(text)
65
+ [text, :cyan]
66
+ end
67
+
68
+ def link(text)
69
+ [text, :cyan, :bold, :underline]
70
+ end
71
+
72
+ def pre(text)
73
+ [text, :bold]
74
+ end
75
+ end
76
+ end
77
+ end
@@ -7,8 +7,8 @@ module Cucumber
7
7
  class Rerun
8
8
  include Formatter::Io
9
9
 
10
- def initialize(config) # rubocop:disable Metrics/PerceivedComplexity
11
- @io = ensure_io(config.out_stream)
10
+ def initialize(config)
11
+ @io = ensure_io(config.out_stream, config.error_stream)
12
12
  @config = config
13
13
  @failures = {}
14
14
  config.on_event :test_case_finished do |event|
@@ -5,7 +5,7 @@ module Cucumber
5
5
  # The formatter used for <tt>--format steps</tt>
6
6
  class Steps
7
7
  def initialize(runtime, path_or_io, options)
8
- @io = ensure_io(path_or_io)
8
+ @io = ensure_io(path_or_io, nil)
9
9
  @options = options
10
10
  @step_definition_files = collect_steps(runtime)
11
11
  end
@@ -16,7 +16,7 @@ module Cucumber
16
16
 
17
17
  def initialize(config)
18
18
  @config = config
19
- @io = ensure_io(config.out_stream)
19
+ @io = ensure_io(config.out_stream, config.error_stream)
20
20
  @ast_lookup = AstLookup.new(config)
21
21
  @counts = ConsoleCounts.new(@config)
22
22
  @issues = ConsoleIssues.new(@config, @ast_lookup)
@@ -0,0 +1,17 @@
1
+ module Cucumber
2
+ module Formatter
3
+ class URLReporter
4
+ def initialize(io)
5
+ @io = io
6
+ end
7
+
8
+ def report(banner)
9
+ @io.puts(banner)
10
+ end
11
+ end
12
+
13
+ class NoReporter
14
+ def report(banner); end
15
+ end
16
+ end
17
+ end
@@ -137,4 +137,4 @@ module Cucumber
137
137
  end
138
138
 
139
139
  # TODO: can we avoid adding methods to the global namespace (Kernel)
140
- extend(Cucumber::Glue::Dsl) # rubocop:disable Style/MixinUsage
140
+ extend(Cucumber::Glue::Dsl)
@@ -87,7 +87,7 @@ module Cucumber
87
87
  'If you simply want it in the console, '\
88
88
  'keep using "puts" (or Kernel.puts to avoid this message)',
89
89
  'puts(message)',
90
- '5.0.0'
90
+ '6.0.0'
91
91
  )
92
92
  messages.each { |message| log(message.to_s) }
93
93
  end
@@ -102,7 +102,7 @@ module Cucumber
102
102
  Cucumber.deprecate(
103
103
  'Please use attach(file, media_type) instead',
104
104
  'embed(file, mime_type, label)',
105
- '5.0.0'
105
+ '6.0.0'
106
106
  )
107
107
  attach(file, mime_type)
108
108
  end
@@ -143,7 +143,7 @@ module Cucumber
143
143
  end
144
144
 
145
145
  # Dynamially generate the API module, closuring the dependencies
146
- def self.for(runtime, language) # rubocop:disable Metrics/MethodLength
146
+ def self.for(runtime, language) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
147
147
  Module.new do # rubocop:disable Metrics/BlockLength
148
148
  def self.extended(object)
149
149
  # wrap the dynamically generated module so that we can document the methods
@@ -95,7 +95,7 @@ module Cucumber
95
95
  def changes
96
96
  require 'diff/lcs'
97
97
  diffable_cell_matrix = cell_matrix.dup.extend(::Diff::LCS)
98
- diffable_cell_matrix.diff(other_table_cell_matrix).flatten
98
+ diffable_cell_matrix.diff(other_table_cell_matrix).flatten(1)
99
99
  end
100
100
 
101
101
  def inspect_rows(missing_row, inserted_row)
@@ -5,9 +5,7 @@ require 'cucumber/gherkin/formatter/ansi_escapes'
5
5
  begin
6
6
  # Support Rake > 0.8.7
7
7
  require 'rake/dsl_definition'
8
- # rubocop:disable Lint/HandleExceptions
9
8
  rescue LoadError
10
- # rubocop:enable Lint/HandleExceptions
11
9
  end
12
10
 
13
11
  module Cucumber
@@ -13,9 +13,7 @@ Before do
13
13
  end
14
14
 
15
15
  After do
16
- begin
17
- RSpec::Mocks.verify
18
- ensure
19
- RSpec::Mocks.teardown
20
- end
16
+ RSpec::Mocks.verify
17
+ ensure
18
+ RSpec::Mocks.teardown
21
19
  end
@@ -166,11 +166,14 @@ module Cucumber
166
166
 
167
167
  require 'cucumber/formatter/ignore_missing_messages'
168
168
  require 'cucumber/formatter/fail_fast'
169
+ require 'cucumber/formatter/publish_banner_printer'
169
170
  require 'cucumber/core/report/summary'
171
+
170
172
  def report
171
173
  return @report if @report
172
174
  reports = [summary_report] + formatters
173
175
  reports << fail_fast_report if @configuration.fail_fast?
176
+ reports << publish_banner_printer unless @configuration.publish_quiet?
174
177
  @report ||= Formatter::Fanout.new(reports)
175
178
  end
176
179
 
@@ -182,6 +185,10 @@ module Cucumber
182
185
  @fail_fast_report ||= Formatter::FailFast.new(@configuration)
183
186
  end
184
187
 
188
+ def publish_banner_printer
189
+ @publish_banner_printer ||= Formatter::PublishBannerPrinter.new(@configuration)
190
+ end
191
+
185
192
  def formatters
186
193
  @formatters ||=
187
194
  @configuration.formatter_factories do |factory, formatter_options, path_or_io|
@@ -0,0 +1,56 @@
1
+ require 'cucumber/term/ansicolor'
2
+
3
+ module Cucumber
4
+ module Term
5
+ module Banner
6
+ def display_banner(lines, io, border_modifiers = nil)
7
+ BannerMaker.new.display_banner(lines, io, border_modifiers || %i[green bold])
8
+ end
9
+
10
+ class BannerMaker
11
+ include Term::ANSIColor
12
+
13
+ def display_banner(lines, io, border_modifiers)
14
+ lines = lines.split("\n") if lines.is_a? String
15
+ longest_line_length = lines.map { |line| line_length(line) }.max
16
+
17
+ io.puts apply_modifiers("┌#{'─' * (longest_line_length + 2)}┐", border_modifiers)
18
+ lines.map do |line|
19
+ padding = ' ' * (longest_line_length - line_length(line))
20
+ io.puts "#{apply_modifiers('│', border_modifiers)} #{display_line(line)}#{padding} #{apply_modifiers('│', border_modifiers)}"
21
+ end
22
+ io.puts apply_modifiers("└#{'─' * (longest_line_length + 2)}┘", border_modifiers)
23
+ end
24
+
25
+ private
26
+
27
+ def display_line(line)
28
+ line.is_a?(Array) ? line.map { |span| display_span(span) }.join : line
29
+ end
30
+
31
+ def display_span(span)
32
+ return apply_modifiers(span.shift, span) if span.is_a?(Array)
33
+ span
34
+ end
35
+
36
+ def apply_modifiers(str, modifiers)
37
+ display = str
38
+ modifiers.each { |modifier| display = send(modifier, display) }
39
+ display
40
+ end
41
+
42
+ def line_length(line)
43
+ if line.is_a?(Array)
44
+ line.map { |span| span_length(span) }.sum
45
+ else
46
+ line.length
47
+ end
48
+ end
49
+
50
+ def span_length(span)
51
+ span.is_a?(Array) ? span[0].length : span.length
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
data/lib/cucumber/version CHANGED
@@ -1 +1 @@
1
- 4.1.0
1
+ 5.3.0