gurke 3.0.0 → 3.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/gurke/cli.rb +1 -1
- data/lib/gurke/reporter.rb +21 -25
- data/lib/gurke/reporters/default_reporter.rb +36 -20
- data/lib/gurke/reporters/team_city_reporter.rb +31 -69
- data/lib/gurke/step.rb +8 -7
- data/lib/gurke/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2311a29357e984f6868342e33b6521a51c7697774155d061090b21484a446a8
|
4
|
+
data.tar.gz: 314bc36b51bd2236407ea0489679edca0aaa78ce47a2870348557a73a66637d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d658e154b2d261d8b4a529f8f7d6b474e8519a042e15808cdc8492a2084c4d0ffa1020cf997ef4900c33a79200cc31886024905da3725038f217b6c362241372
|
7
|
+
data.tar.gz: 2d2ec2d30909f5b6b3f2673cdb079ef2342c50f9cf7bdf9d9f40e62d022ab08d1570ec4f22212a7c337f9e8bcdef277dd4c862a701d923a4644e10d4cb68ed03
|
data/CHANGELOG.md
CHANGED
data/lib/gurke/cli.rb
CHANGED
@@ -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: '
|
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' \
|
data/lib/gurke/reporter.rb
CHANGED
@@ -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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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 =
|
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 << ' '
|
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
|
-
|
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
|
69
|
-
when :failed then
|
70
|
-
when :passed then
|
71
|
-
else
|
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
|
-
|
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 <
|
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
|
-
|
26
|
-
io.puts ' Background:' unless @background
|
27
|
-
|
28
|
-
@background = true
|
12
|
+
super
|
29
13
|
end
|
30
14
|
|
31
|
-
def
|
32
|
-
@
|
33
|
-
end
|
15
|
+
def before_scenario(scenario)
|
16
|
+
@status_reported = false
|
34
17
|
|
35
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
35
|
+
protected
|
75
36
|
|
76
|
-
def
|
77
|
-
|
78
|
-
end
|
37
|
+
def step_pending(step, *)
|
38
|
+
super
|
79
39
|
|
80
|
-
|
81
|
-
|
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
|
89
|
-
|
90
|
-
|
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
|
-
|
96
|
-
|
53
|
+
print_exception(step.exception)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
97
57
|
|
98
|
-
|
99
|
-
|
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
|
data/lib/gurke/step.rb
CHANGED
@@ -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
|
|
data/lib/gurke/version.rb
CHANGED