gurke 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67753800c554ed5230279ea3fedb0765c04bdbebb23e0adcfe51d39aa171e943
4
- data.tar.gz: 1272789c4796298eccbea8d1c4b7993d09e5adb67be6d1c9750e7b9fc0c57837
3
+ metadata.gz: f2311a29357e984f6868342e33b6521a51c7697774155d061090b21484a446a8
4
+ data.tar.gz: 314bc36b51bd2236407ea0489679edca0aaa78ce47a2870348557a73a66637d1
5
5
  SHA512:
6
- metadata.gz: 68edef2b0fd8b60b87dca69ac2a6bd2bfbed63ea58d9c0a0484a72e1a4aea5713a673a0eb46b182ba0ffa006002d7db991d5e842504827bea841365e6ffb28cd
7
- data.tar.gz: 9c3f090fd25a651f46d85e11864d539379af2977c9d2174a3bf23fd542933af388336cd0a7f968d40e2330bab234c792645dd21999e2ac6710e1d422b1c7f9f2
6
+ metadata.gz: d658e154b2d261d8b4a529f8f7d6b474e8519a042e15808cdc8492a2084c4d0ffa1020cf997ef4900c33a79200cc31886024905da3725038f217b6c362241372
7
+ data.tar.gz: 2d2ec2d30909f5b6b3f2673cdb079ef2342c50f9cf7bdf9d9f40e62d022ab08d1570ec4f22212a7c337f9e8bcdef277dd4c862a701d923a4644e10d4cb68ed03
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.0
4
+
5
+ * Update TeamCity formatter to extend default formatter
6
+
3
7
  ## 3.0.0
4
8
 
5
9
  * Drop support for MRI < 2.3
@@ -61,7 +61,7 @@ module Gurke
61
61
  opt :version, 'Show program version information.'
62
62
  opt :backtrace, 'Show full error backtraces.'
63
63
  opt :formatter, 'Select a special formatter as reporter', \
64
- default: 'compact'
64
+ default: 'default'
65
65
  opt :pattern, 'File pattern matching feature files to be run.',
66
66
  default: 'features/**/*.feature'
67
67
  opt :require, 'Files matching this pattern will be required after' \
@@ -7,8 +7,6 @@ module Gurke
7
7
  #
8
8
  # @api public
9
9
  #
10
- # rubocop:disable MissingCopEnableDirective
11
- # rubocop:disable UnusedMethodArgument
12
10
  #
13
11
  class Reporter
14
12
  # List of all callback methods as symbols.
@@ -42,7 +40,7 @@ module Gurke
42
40
  #
43
41
  # @api public
44
42
  #
45
- def before_features(features)
43
+ def before_features(_features)
46
44
  raise NotImplementedError.new \
47
45
  "#{self.class.name}#before_features must be implemented in subclass."
48
46
  end
@@ -55,7 +53,7 @@ module Gurke
55
53
  #
56
54
  # @api public
57
55
  #
58
- def start_features(features)
56
+ def start_features(_features)
59
57
  raise NotImplementedError.new \
60
58
  "#{self.class.name}#before_features must be implemented in subclass."
61
59
  end
@@ -68,7 +66,7 @@ module Gurke
68
66
  #
69
67
  # @api public
70
68
  #
71
- def before_feature(feature)
69
+ def before_feature(_feature)
72
70
  raise NotImplementedError.new \
73
71
  "#{self.class.name}#start_feature must be implemented in subclass."
74
72
  end
@@ -81,7 +79,7 @@ module Gurke
81
79
  #
82
80
  # @api public
83
81
  #
84
- def start_feature(feature)
82
+ def start_feature(_feature)
85
83
  raise NotImplementedError.new \
86
84
  "#{self.class.name}#start_feature must be implemented in subclass."
87
85
  end
@@ -93,7 +91,7 @@ module Gurke
93
91
  #
94
92
  # @api public
95
93
  #
96
- def before_scenario(scenario)
94
+ def before_scenario(_scenario)
97
95
  raise NotImplementedError.new \
98
96
  "#{self.class.name}#before_scenario must be implemented in subclass."
99
97
  end
@@ -105,7 +103,7 @@ module Gurke
105
103
  #
106
104
  # @api public
107
105
  #
108
- def start_scenario(scenario)
106
+ def start_scenario(_scenario)
109
107
  raise NotImplementedError.new \
110
108
  "#{self.class.name}#start_scenario must be implemented in subclass."
111
109
  end
@@ -117,7 +115,7 @@ module Gurke
117
115
  #
118
116
  # @api public
119
117
  #
120
- def start_background(background, scenario)
118
+ def start_background(_background, _scenario)
121
119
  raise NotImplementedError.new \
122
120
  "#{self.class.name}#start_background must be implemented in subclass."
123
121
  end
@@ -129,7 +127,7 @@ module Gurke
129
127
  #
130
128
  # @api public
131
129
  #
132
- def end_background(background, scenario)
130
+ def end_background(_background, _scenario)
133
131
  raise NotImplementedError.new \
134
132
  "#{self.class.name}#end_background must be implemented in subclass."
135
133
  end
@@ -141,7 +139,7 @@ module Gurke
141
139
  #
142
140
  # @api public
143
141
  #
144
- def before_step(step, scenario)
142
+ def before_step(_step, _scenario)
145
143
  raise NotImplementedError.new \
146
144
  "#{self.class.name}#before_step must be implemented in subclass."
147
145
  end
@@ -153,7 +151,7 @@ module Gurke
153
151
  #
154
152
  # @api public
155
153
  #
156
- def start_step(step, scenario)
154
+ def start_step(_step, _scenario)
157
155
  raise NotImplementedError.new \
158
156
  "#{self.class.name}#start_step must be implemented in subclass."
159
157
  end
@@ -166,7 +164,7 @@ module Gurke
166
164
  #
167
165
  # @api public
168
166
  #
169
- def end_step(step_result, scenario)
167
+ def end_step(_step_result, _scenario)
170
168
  raise NotImplementedError.new \
171
169
  "#{self.class.name}#end_step must be implemented in subclass."
172
170
  end
@@ -179,7 +177,7 @@ module Gurke
179
177
  #
180
178
  # @api public
181
179
  #
182
- def after_step(step_result, scenario)
180
+ def after_step(_step_result, _scenario)
183
181
  raise NotImplementedError.new \
184
182
  "#{self.class.name}#after_step must be implemented in subclass."
185
183
  end
@@ -191,7 +189,7 @@ module Gurke
191
189
  #
192
190
  # @api public
193
191
  #
194
- def end_scenario(scenario)
192
+ def end_scenario(_scenario)
195
193
  raise NotImplementedError.new \
196
194
  "#{self.class.name}#end_scenario must be implemented in subclass."
197
195
  end
@@ -203,7 +201,7 @@ module Gurke
203
201
  #
204
202
  # @api public
205
203
  #
206
- def after_scenario(scenario)
204
+ def after_scenario(_scenario)
207
205
  raise NotImplementedError.new \
208
206
  "#{self.class.name}#after_scenario must be implemented in subclass."
209
207
  end
@@ -214,7 +212,7 @@ module Gurke
214
212
  #
215
213
  # @api public
216
214
  #
217
- def end_feature(feature)
215
+ def end_feature(_feature)
218
216
  raise NotImplementedError.new \
219
217
  "#{self.class.name}#end_feature must be implemented in subclass."
220
218
  end
@@ -225,7 +223,7 @@ module Gurke
225
223
  #
226
224
  # @api public
227
225
  #
228
- def after_feature(feature)
226
+ def after_feature(_feature)
229
227
  raise NotImplementedError.new \
230
228
  "#{self.class.name}#after_feature must be implemented in subclass."
231
229
  end
@@ -236,7 +234,7 @@ module Gurke
236
234
  #
237
235
  # @api public
238
236
  #
239
- def end_features(features)
237
+ def end_features(_features)
240
238
  raise NotImplementedError.new \
241
239
  "#{self.class.name}#end_features must be implemented in subclass."
242
240
  end
@@ -247,7 +245,7 @@ module Gurke
247
245
  #
248
246
  # @api public
249
247
  #
250
- def after_features(features)
248
+ def after_features(_features)
251
249
  raise NotImplementedError.new \
252
250
  "#{self.class.name}#after_features must be implemented in subclass."
253
251
  end
@@ -265,7 +263,7 @@ module Gurke
265
263
  protected
266
264
 
267
265
  def format_exception(ex, backtrace: true)
268
- s = [ex.class.to_s + ': ' + ex.message.strip]
266
+ s = ex.class.to_s << ': ' << ex.message.strip << "\n"
269
267
 
270
268
  if backtrace
271
269
  if ex.backtrace.nil?
@@ -274,7 +272,7 @@ module Gurke
274
272
  s << ' <backtrace empty>'
275
273
  else
276
274
  ex.backtrace.each do |bt|
277
- s << ' ' + bt.strip
275
+ s << ' ' << bt.strip << "\n"
278
276
  end
279
277
  end
280
278
  end
@@ -282,9 +280,7 @@ module Gurke
282
280
  if ex.respond_to?(:cause) && ex.cause &&
283
281
  ex.cause.respond_to?(:message) && ex.cause.respond_to?(:backtrace)
284
282
 
285
- cause = format_exception(ex.cause, backtrace: backtrace)
286
- s << 'caused by: ' + cause.shift
287
- s += cause
283
+ s << 'caused by: ' << format_exception(ex.cause, backtrace: backtrace)
288
284
  end
289
285
 
290
286
  s
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'colorize'
4
-
5
3
  # Colors
6
4
  # :black, :red, :green, :yellow, :blue,
7
5
  # :magenta, :cyan, :white, :default, :light_black,
@@ -63,13 +61,14 @@ module Gurke::Reporters
63
61
  io.print step.name.gsub(/"(.*?)"/, cyan('\0'))
64
62
  end
65
63
 
66
- def after_step(step, *)
64
+ def after_step(step, *args)
67
65
  case step.state
68
- when :pending then print_braces yellow 'pending'
69
- when :failed then print_failed step
70
- when :passed then print_braces green 'passed'
71
- else print_braces cyan 'skipped'
66
+ when :pending then step_pending(step, *args)
67
+ when :failed then step_failed(step, *args)
68
+ when :passed then step_passed(step, *args)
69
+ else step_skipped(step, *args)
72
70
  end
71
+
73
72
  io.puts
74
73
  io.flush
75
74
  end
@@ -107,7 +106,36 @@ module Gurke::Reporters
107
106
  io.puts
108
107
  end
109
108
 
110
- private
109
+ protected
110
+
111
+ def status(str)
112
+ " (#{str})"
113
+ end
114
+
115
+ def step_pending(*)
116
+ io.print status yellow 'pending'
117
+ end
118
+
119
+ def step_failed(step, *_args, exception: true)
120
+ io.print status red 'failure'
121
+ io.puts
122
+
123
+ return unless exception
124
+
125
+ print_exception(step.exception)
126
+ end
127
+
128
+ def step_passed(*)
129
+ io.print status green 'passed'
130
+ end
131
+
132
+ def step_skipped(*)
133
+ io.print cyan 'skipped'
134
+ end
135
+
136
+ def print_exception(exception)
137
+ io.puts red format_exception(exception).gsub(/^/, ' ')
138
+ end
111
139
 
112
140
  def format_location(obj)
113
141
  file = obj.file.to_s
@@ -119,18 +147,6 @@ module Gurke::Reporters
119
147
  light_black("# #{path}:#{line}")
120
148
  end
121
149
 
122
- def print_braces(str)
123
- io.print " (#{str})"
124
- end
125
-
126
- def print_failed(step)
127
- print_braces red('failure')
128
- io.puts
129
-
130
- exout = format_exception(step.exception)
131
- io.puts exout.map {|s| red(" #{s}\n") }.join
132
- end
133
-
134
150
  %i[black red green yellow blue
135
151
  magenta cyan white default light_black
136
152
  light_red light_green light_yellow light_blue
@@ -5,98 +5,64 @@ module Gurke::Reporters
5
5
  # The {TeamCityReporter} prints features, scenarios and
6
6
  # steps in a format parseable by TeamCity CI.
7
7
  #
8
- class TeamCityReporter < NullReporter
9
- attr_reader :io
10
- def initialize(io = $stdout)
11
- @io = io
12
- end
13
-
8
+ class TeamCityReporter < DefaultReporter
14
9
  def before_feature(feature)
15
10
  publish :testSuiteStarted, name: feature.name
16
- io.puts " #{feature.description.split("\n").join("\n ")}"
17
- io.puts
18
- end
19
-
20
- def before_scenario(scenario)
21
- @scenario = scenario
22
- publish :testStarted, name: scenario.name
23
- end
24
11
 
25
- def start_background(*)
26
- io.puts ' Background:' unless @background
27
-
28
- @background = true
12
+ super
29
13
  end
30
14
 
31
- def end_background(*)
32
- @background = false
33
- end
15
+ def before_scenario(scenario)
16
+ @status_reported = false
34
17
 
35
- def before_step(step, *)
36
- io.print ' ' if @background
37
- io.print ' '
38
- io.print step.keyword
39
- io.print step.name
40
- end
18
+ publish :testStarted, name: scenario.name
41
19
 
42
- def after_step(step, *)
43
- case step.state
44
- when :pending then print_pending step
45
- when :failed then print_failed step
46
- when :success then print_braces 'success'
47
- else print_braces 'skipped'
48
- end
49
- io.puts
50
- io.flush
20
+ super
51
21
  end
52
22
 
53
23
  def after_scenario(scenario)
54
24
  publish :testFinished, name: scenario.name
25
+
26
+ super
55
27
  end
56
28
 
57
29
  def after_feature(feature)
58
30
  publish :testSuiteFinished, name: feature.name
59
- end
60
-
61
- def after_features(features)
62
- scenarios = features.map(&:scenarios).flatten
63
31
 
64
- example_count = scenarios.size
65
- failure_count = scenarios.select(&:failed?).size
66
- pending_count = scenarios.select(&:pending?).size
67
-
68
- io.puts " #{example_count} scenarios: " \
69
- "#{failure_count} failing, " \
70
- "#{pending_count} pending"
71
- io.puts
32
+ super
72
33
  end
73
34
 
74
- private
35
+ protected
75
36
 
76
- def print_braces(str)
77
- io.print " (#{str})"
78
- end
37
+ def step_pending(step, *)
38
+ super
79
39
 
80
- def print_pending(_step)
81
- return if @pending == @scenario # only once per scenario
82
- publish :testIgnored,
83
- name: @scenario.name,
40
+ report :testIgnored,
41
+ name: step.scenario.name,
84
42
  message: 'Step definition missing'
85
- @pending = @scenario
86
43
  end
87
44
 
88
- def print_failed(step)
89
- publish :testFailed,
90
- name: @scenario.name,
45
+ def step_failed(step, *args)
46
+ super(step, *args, exception: false)
47
+
48
+ report :testFailed,
49
+ name: step.scenario.name,
91
50
  message: step.exception.inspect,
92
51
  backtrace: step.exception.backtrace.join('\n')
93
- @pending = @scenario
94
52
 
95
- print_braces 'failure'
96
- io.puts
53
+ print_exception(step.exception)
54
+ end
55
+
56
+ private
97
57
 
98
- exout = format_exception(step.exception)
99
- io.puts exout.map {|s| " #{s}\n" }.join
58
+ def status_reported?
59
+ @status_reported
60
+ end
61
+
62
+ def report(*args)
63
+ return if status_reported?
64
+
65
+ publish(*args)
100
66
  end
101
67
 
102
68
  def publish(message_name, args)
@@ -119,9 +85,5 @@ module Gurke::Reporters
119
85
  "'#{escape args}'"
120
86
  end
121
87
  end
122
-
123
- def step_name(step)
124
- step.keyword + step.name.gsub(/"(.*?)"/, '\0')
125
- end
126
88
  end
127
89
  end
@@ -61,14 +61,14 @@ module Gurke
61
61
  result = find_and_run_step runner, scenario, world
62
62
  rescue Interrupt
63
63
  scenario.abort!
64
- result = StepResult.new self, :aborted
64
+ result = StepResult.new self, scenario, :aborted
65
65
  raise
66
66
  rescue StepPending => e
67
67
  scenario.pending! e
68
- result = StepResult.new self, :pending, e
68
+ result = StepResult.new self, scenario, :pending, e
69
69
  rescue Exception => e # rubocop:disable RescueException
70
70
  scenario.failed! e
71
- result = StepResult.new self, :failed, e
71
+ result = StepResult.new self, scenario, :failed, e
72
72
  ensure
73
73
  reporter.invoke :end_step, result, scenario
74
74
  end
@@ -78,23 +78,24 @@ module Gurke
78
78
  match = Steps.find_step self, world, type
79
79
 
80
80
  if scenario.pending? || scenario.failed? || scenario.aborted?
81
- return StepResult.new self, :skipped
81
+ return StepResult.new self, scenario, :skipped
82
82
  end
83
83
 
84
84
  m = world.method match.method_name
85
85
  world.send match.method_name, *(match.params + [self])[0...m.arity]
86
86
 
87
- StepResult.new self, :passed
87
+ StepResult.new self, scenario, :passed
88
88
  end
89
89
  end
90
90
 
91
91
  #
92
92
  class StepResult
93
- attr_reader :step, :exception, :state
93
+ attr_reader :step, :exception, :state, :scenario
94
94
 
95
- def initialize(step, state, err = nil)
95
+ def initialize(step, scenario, state, err = nil)
96
96
  @step = step
97
97
  @state = state
98
+ @scenario = scenario
98
99
  @exception = err
99
100
  end
100
101
 
@@ -3,7 +3,7 @@
3
3
  module Gurke
4
4
  module VERSION
5
5
  MAJOR = 3
6
- MINOR = 0
6
+ MINOR = 1
7
7
  PATCH = 0
8
8
  STAGE = nil
9
9
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.').freeze
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gurke
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen