rutema 2.0.1 → 2.0.3
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/History.txt +7 -2
- data/README.md +12 -12
- data/bin/rutema +4 -4
- data/lib/rutema/application.rb +34 -31
- data/lib/rutema/core/configuration.rb +122 -117
- data/lib/rutema/core/engine.rb +102 -113
- data/lib/rutema/core/framework.rb +54 -54
- data/lib/rutema/core/objectmodel.rb +112 -95
- data/lib/rutema/core/parser.rb +9 -10
- data/lib/rutema/core/reporter.rb +76 -70
- data/lib/rutema/core/runner.rb +118 -97
- data/lib/rutema/elements/minimal.rb +29 -25
- data/lib/rutema/parsers/xml.rb +101 -93
- data/lib/rutema/reporters/json.rb +18 -20
- data/lib/rutema/reporters/junit.rb +88 -80
- data/lib/rutema/version.rb +1 -1
- metadata +13 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Copyright (c) 2007-2021 Vassilis Rizopoulos. All rights reserved.
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "patir/command"
|
|
4
4
|
|
|
5
5
|
module Rutema
|
|
6
6
|
##
|
|
@@ -20,11 +20,11 @@ module Rutema
|
|
|
20
20
|
# * +value+ - the initial value of the attribute
|
|
21
21
|
#
|
|
22
22
|
# If +symbol+ is neither a string nor a symbol this method will be a no-op.
|
|
23
|
-
def attribute
|
|
24
|
-
@attributes||=
|
|
23
|
+
def attribute(symbol, value)
|
|
24
|
+
@attributes ||= {}
|
|
25
25
|
case symbol
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
when String then @attributes[:"#{symbol}"] = value
|
|
27
|
+
when Symbol then @attributes[symbol] = value
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -37,29 +37,33 @@ module Rutema
|
|
|
37
37
|
# object.attribute= will set the attribute to the right operand and
|
|
38
38
|
# object.has_attribute? will return +true+ or +false+ according to the
|
|
39
39
|
# existence of the attribute.
|
|
40
|
-
def method_missing
|
|
41
|
-
@attributes||=
|
|
42
|
-
key=symbol.id2name.chomp(
|
|
43
|
-
@attributes[:"#{key}"]=args[0] if key
|
|
44
|
-
if @attributes.
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
def method_missing(symbol, *args)
|
|
41
|
+
@attributes ||= {}
|
|
42
|
+
key = symbol.id2name.chomp("?").chomp("=").sub(/^has_/, "")
|
|
43
|
+
@attributes[:"#{key}"] = args[0] if "#{key}=" == symbol.id2name
|
|
44
|
+
if @attributes.key?(:"#{key}")
|
|
45
|
+
return true if "has_#{key}?" == symbol.id2name
|
|
46
|
+
|
|
47
|
+
return @attributes[:"#{key}"]
|
|
47
48
|
else
|
|
48
|
-
return false if "has_
|
|
49
|
-
|
|
49
|
+
return false if "has_#{key}?" == symbol.id2name
|
|
50
|
+
|
|
51
|
+
super
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
def respond_to_missing?(*_args)
|
|
56
|
+
true
|
|
57
|
+
end
|
|
58
|
+
|
|
53
59
|
##
|
|
54
60
|
# Return +true+ if the object responds to the given method or else +false+
|
|
55
|
-
def respond_to?
|
|
56
|
-
@attributes||=
|
|
57
|
-
key=symbol.id2name.chomp(
|
|
58
|
-
if @attributes.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
super(symbol,include_all)
|
|
62
|
-
end
|
|
61
|
+
def respond_to?(symbol, include_all)
|
|
62
|
+
@attributes ||= {}
|
|
63
|
+
key = symbol.id2name.chomp("?").chomp("=").sub(/^has_/, "")
|
|
64
|
+
return true if @attributes.key?(:"#{key}")
|
|
65
|
+
|
|
66
|
+
super
|
|
63
67
|
end
|
|
64
68
|
end
|
|
65
69
|
|
|
@@ -70,6 +74,7 @@ module Rutema
|
|
|
70
74
|
include SpecificationElement
|
|
71
75
|
|
|
72
76
|
attr_accessor :scenario
|
|
77
|
+
|
|
73
78
|
##
|
|
74
79
|
# Expects a Hash of parameters
|
|
75
80
|
#
|
|
@@ -88,16 +93,14 @@ module Rutema
|
|
|
88
93
|
# :version - The version of this specification
|
|
89
94
|
#
|
|
90
95
|
# Default values are empty strings and arrays. (scenario is nil)
|
|
91
|
-
def initialize
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@attributes||=
|
|
96
|
-
@attributes[:
|
|
97
|
-
@attributes[:
|
|
98
|
-
@attributes[:
|
|
99
|
-
@attributes[:description]||=""
|
|
100
|
-
@scenario=@attributes[:scenario]
|
|
96
|
+
def initialize(params)
|
|
97
|
+
@attributes = params if params
|
|
98
|
+
@attributes ||= {}
|
|
99
|
+
@attributes[:name] ||= ""
|
|
100
|
+
@attributes[:title] ||= ""
|
|
101
|
+
@attributes[:filename] ||= ""
|
|
102
|
+
@attributes[:description] ||= ""
|
|
103
|
+
@scenario = @attributes[:scenario]
|
|
101
104
|
end
|
|
102
105
|
|
|
103
106
|
##
|
|
@@ -107,93 +110,90 @@ module Rutema
|
|
|
107
110
|
end
|
|
108
111
|
end
|
|
109
112
|
|
|
110
|
-
#A Rutema::Scenario is a sequence of Rutema::Step instances.
|
|
113
|
+
# A Rutema::Scenario is a sequence of Rutema::Step instances.
|
|
111
114
|
#
|
|
112
|
-
#Rutema::Step instances are run in the definition sequence and the scenario
|
|
113
|
-
#is succesfull when all steps are succesfull.
|
|
115
|
+
# Rutema::Step instances are run in the definition sequence and the scenario
|
|
116
|
+
# is succesfull when all steps are succesfull.
|
|
114
117
|
#
|
|
115
|
-
#From the execution point of view each step is either succesfull or failed and it depends on
|
|
116
|
-
#the exit code of the step's command.
|
|
118
|
+
# From the execution point of view each step is either succesfull or failed and it depends on
|
|
119
|
+
# the exit code of the step's command.
|
|
117
120
|
#
|
|
118
|
-
#Failure in a step results in the interruption of execution and the report of the errors.
|
|
121
|
+
# Failure in a step results in the interruption of execution and the report of the errors.
|
|
119
122
|
class Scenario
|
|
120
123
|
include SpecificationElement
|
|
121
124
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def initialize steps
|
|
125
|
-
@attributes=Hash.new
|
|
126
|
-
@steps=steps
|
|
127
|
-
@steps||=Array.new
|
|
128
|
-
end
|
|
125
|
+
attr_accessor :steps
|
|
129
126
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
@steps
|
|
127
|
+
def initialize(steps)
|
|
128
|
+
@attributes = {}
|
|
129
|
+
@steps = steps
|
|
130
|
+
@steps ||= []
|
|
133
131
|
end
|
|
134
132
|
|
|
135
|
-
#
|
|
136
|
-
def
|
|
137
|
-
@steps
|
|
133
|
+
# Adds a step at the end of the step sequence
|
|
134
|
+
def add_step(step)
|
|
135
|
+
@steps << step
|
|
138
136
|
end
|
|
137
|
+
|
|
138
|
+
# Overwrites the step sequence
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
#Represents a step in a Scenario.
|
|
141
|
+
# Represents a step in a Scenario.
|
|
142
142
|
#
|
|
143
|
-
#Each Rutema::Step can have text and a command associated with it.
|
|
143
|
+
# Each Rutema::Step can have text and a command associated with it.
|
|
144
144
|
#
|
|
145
|
-
#Step standard attributes are.
|
|
145
|
+
# Step standard attributes are.
|
|
146
146
|
#
|
|
147
|
-
#attended - the step can only run in attended mode, it requires user input.
|
|
147
|
+
# attended - the step can only run in attended mode, it requires user input.
|
|
148
148
|
#
|
|
149
|
-
#step_type - a string identifying the type of the step. It is "step" by default.
|
|
149
|
+
# step_type - a string identifying the type of the step. It is "step" by default.
|
|
150
150
|
#
|
|
151
|
-
#ignore - set to true if the step's success or failure is to be ignored. It essentially means that the step is always considered succesfull
|
|
151
|
+
# ignore - set to true if the step's success or failure is to be ignored. It essentially means that the step is always considered succesfull
|
|
152
152
|
#
|
|
153
|
-
#continue - set to true if the step's success or failure is to be recognized, but following steps in the same scenario are to be carried out regardless
|
|
153
|
+
# continue - set to true if the step's success or failure is to be recognized, but following steps in the same scenario are to be carried out regardless
|
|
154
154
|
# of if indicates test failure, but ensures any further state is carried out as needed
|
|
155
155
|
#
|
|
156
156
|
# skip_on_error - if the test case has been marked a failure, skip steps marked with this attribute
|
|
157
157
|
#
|
|
158
|
-
#number - this is set when the step is assigned to a Scenario and is the sequence number
|
|
158
|
+
# number - this is set when the step is assigned to a Scenario and is the sequence number
|
|
159
159
|
#
|
|
160
|
-
#cmd - the command associated with this step. This should quack like Patir::Command.
|
|
160
|
+
# cmd - the command associated with this step. This should quack like Patir::Command.
|
|
161
161
|
#
|
|
162
|
-
#status - one of :not_executed, :success, :warning, :error. Encapsulates the underlying command's status
|
|
162
|
+
# status - one of :not_executed, :success, :warning, :error. Encapsulates the underlying command's status
|
|
163
163
|
#
|
|
164
164
|
#==Dynamic behaviour
|
|
165
165
|
#
|
|
166
|
-
#A Rutema::Step can be queried dynamicaly about the attributes it posesses:
|
|
166
|
+
# A Rutema::Step can be queried dynamicaly about the attributes it posesses:
|
|
167
167
|
# step.has_script? - will return true if script is step's attribute.
|
|
168
|
-
#Attribute's are mostly assigned by the parser, i.e. the Rutema::BaseXMLParser from the XML element
|
|
168
|
+
# Attribute's are mostly assigned by the parser, i.e. the Rutema::BaseXMLParser from the XML element
|
|
169
169
|
# <test script="some_script"/>
|
|
170
|
-
#will create a Step instance with step_type=="test" and script="some_script". In this case
|
|
170
|
+
# will create a Step instance with step_type=="test" and script="some_script". In this case
|
|
171
171
|
#
|
|
172
172
|
# step.has_script? returns true
|
|
173
173
|
# step.script returns "some_script"
|
|
174
174
|
#
|
|
175
|
-
#Just like an OpenStruct, Step attributes will be created by direct assignment:
|
|
175
|
+
# Just like an OpenStruct, Step attributes will be created by direct assignment:
|
|
176
176
|
# step.script="some_script" creates the script attribute if it does not exist.
|
|
177
177
|
#
|
|
178
|
-
#See Rutema::SpecificationElement for the implementation details.
|
|
178
|
+
# See Rutema::SpecificationElement for the implementation details.
|
|
179
179
|
class Step
|
|
180
180
|
include SpecificationElement
|
|
181
181
|
include Patir::Command
|
|
182
|
-
|
|
183
|
-
#_txt_ describes the step, _cmd_ is the command to run
|
|
184
|
-
def initialize
|
|
185
|
-
@attributes=
|
|
186
|
-
#ignore is off by default
|
|
187
|
-
@attributes[:ignore]=false
|
|
182
|
+
|
|
183
|
+
# _txt_ describes the step, _cmd_ is the command to run
|
|
184
|
+
def initialize(txt = "", cmd = nil)
|
|
185
|
+
@attributes = {}
|
|
186
|
+
# ignore is off by default
|
|
187
|
+
@attributes[:ignore] = false
|
|
188
188
|
# continue is off by default
|
|
189
189
|
@attributes[:continue] = false
|
|
190
190
|
# skip_on_error is off by default
|
|
191
|
-
@attributes[:skip_on_error]=false
|
|
192
|
-
#assign
|
|
193
|
-
@attributes[:cmd]=cmd if cmd
|
|
194
|
-
@attributes[:text]=txt
|
|
195
|
-
@number=0
|
|
196
|
-
@attributes[:step_type]="step"
|
|
191
|
+
@attributes[:skip_on_error] = false
|
|
192
|
+
# assign
|
|
193
|
+
@attributes[:cmd] = cmd if cmd
|
|
194
|
+
@attributes[:text] = txt
|
|
195
|
+
@number = 0
|
|
196
|
+
@attributes[:step_type] = "step"
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
def name
|
|
@@ -202,83 +202,100 @@ module Rutema
|
|
|
202
202
|
|
|
203
203
|
def output
|
|
204
204
|
return "" unless @attributes[:cmd]
|
|
205
|
+
|
|
205
206
|
return @attributes[:cmd].output
|
|
206
207
|
end
|
|
207
208
|
|
|
208
209
|
def error
|
|
209
210
|
return "no command associated" unless @attributes[:cmd]
|
|
211
|
+
|
|
210
212
|
return @attributes[:cmd].error
|
|
211
213
|
end
|
|
212
214
|
|
|
213
215
|
def backtrace
|
|
214
216
|
return "no backtrace associated" unless @attributes[:cmd]
|
|
215
217
|
return @attributes[:cmd].backtrace if @attributes[:cmd].respond_to?(:backtrace)
|
|
218
|
+
|
|
216
219
|
return ""
|
|
217
220
|
end
|
|
218
221
|
|
|
219
222
|
def skip_on_error?
|
|
220
223
|
return false unless @attributes[:skip_on_error]
|
|
224
|
+
|
|
221
225
|
return @attributes[:skip_on_error]
|
|
222
226
|
end
|
|
223
227
|
|
|
224
228
|
def ignore?
|
|
225
229
|
return false unless @attributes[:ignore]
|
|
230
|
+
|
|
226
231
|
return @attributes[:ignore]
|
|
227
232
|
end
|
|
228
233
|
|
|
229
234
|
def continue?
|
|
230
235
|
return false unless @attributes[:continue]
|
|
236
|
+
|
|
231
237
|
return @attributes[:continue]
|
|
232
238
|
end
|
|
233
239
|
|
|
234
240
|
def exec_time
|
|
235
241
|
return 0 unless @attributes[:cmd]
|
|
242
|
+
|
|
236
243
|
return @attributes[:cmd].exec_time
|
|
237
244
|
end
|
|
238
245
|
|
|
239
246
|
def status
|
|
240
247
|
return :warning unless @attributes[:cmd]
|
|
248
|
+
|
|
241
249
|
return @attributes[:cmd].status
|
|
242
250
|
end
|
|
243
251
|
|
|
244
|
-
def status=
|
|
245
|
-
@attributes[:cmd].status=
|
|
252
|
+
def status=(stts)
|
|
253
|
+
@attributes[:cmd].status = stts if @attributes[:cmd]
|
|
246
254
|
end
|
|
247
255
|
|
|
248
|
-
def run
|
|
256
|
+
def run(context = nil)
|
|
249
257
|
return not_executed unless @attributes[:cmd]
|
|
258
|
+
|
|
250
259
|
return @attributes[:cmd].run(context)
|
|
251
260
|
end
|
|
252
261
|
|
|
253
262
|
def reset
|
|
254
|
-
@attributes[:cmd]
|
|
263
|
+
@attributes[:cmd]&.reset
|
|
255
264
|
end
|
|
256
265
|
|
|
257
266
|
def name_with_parameters
|
|
258
|
-
param=" - #{
|
|
267
|
+
param = " - #{cmd}" if has_cmd?
|
|
259
268
|
return "#{@attributes[:step_type]}#{param}"
|
|
260
269
|
end
|
|
261
270
|
|
|
262
|
-
def to_s
|
|
263
|
-
if
|
|
264
|
-
msg="#{
|
|
271
|
+
def to_s # :nodoc:
|
|
272
|
+
if has_cmd?
|
|
273
|
+
msg = "#{number} - #{cmd}"
|
|
265
274
|
else
|
|
266
|
-
msg="#{
|
|
275
|
+
msg = "#{number} - #{name}"
|
|
267
276
|
end
|
|
268
|
-
|
|
277
|
+
msg << " in #{included_in}" if has_included_in?
|
|
269
278
|
return msg
|
|
270
279
|
end
|
|
271
280
|
end
|
|
272
281
|
end
|
|
273
282
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
283
|
+
# rubocop:disable-next Style/OneClassPerFile
|
|
284
|
+
# Class functionality extensions - ye old good monkey patch
|
|
285
|
+
module Patir
|
|
286
|
+
# Decorates the class with a to_s
|
|
287
|
+
class ShellCommand
|
|
288
|
+
# :nodoc:
|
|
289
|
+
def to_s
|
|
290
|
+
return @command
|
|
291
|
+
end
|
|
277
292
|
end
|
|
278
|
-
end
|
|
279
293
|
|
|
280
|
-
class
|
|
281
|
-
|
|
282
|
-
|
|
294
|
+
# Decorates the class with a to_s
|
|
295
|
+
class RubyCommand
|
|
296
|
+
# :nodoc:
|
|
297
|
+
def to_s
|
|
298
|
+
return @name
|
|
299
|
+
end
|
|
283
300
|
end
|
|
284
301
|
end
|
data/lib/rutema/core/parser.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Copyright (c) 2007-2021 Vassilis Rizopoulos. All rights reserved.
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "framework"
|
|
4
4
|
|
|
5
5
|
module Rutema
|
|
6
6
|
##
|
|
@@ -23,9 +23,9 @@ module Rutema
|
|
|
23
23
|
##
|
|
24
24
|
# Initialize a new instance internally storing and validating the passed
|
|
25
25
|
# Configuration instance
|
|
26
|
-
def initialize
|
|
27
|
-
@configuration=configuration
|
|
28
|
-
@configuration||={}
|
|
26
|
+
def initialize(configuration)
|
|
27
|
+
@configuration = configuration
|
|
28
|
+
@configuration ||= {}
|
|
29
29
|
validate_configuration
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -34,15 +34,15 @@ module Rutema
|
|
|
34
34
|
#
|
|
35
35
|
# The passed argument can either be the path to a test specification file
|
|
36
36
|
# or the test specification itself.
|
|
37
|
-
def parse_specification
|
|
38
|
-
raise ParserError,"not implemented. You should derive a parser implementation from SpecificationParser!"
|
|
37
|
+
def parse_specification(_param)
|
|
38
|
+
raise ParserError, "not implemented. You should derive a parser implementation from SpecificationParser!"
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
##
|
|
42
42
|
# Parse a setup specification
|
|
43
43
|
#
|
|
44
44
|
# This calls #parse_specification by default.
|
|
45
|
-
def parse_setup
|
|
45
|
+
def parse_setup(param)
|
|
46
46
|
parse_specification(param)
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -50,7 +50,7 @@ module Rutema
|
|
|
50
50
|
# Parse a teardown specification
|
|
51
51
|
#
|
|
52
52
|
# This calls #parse_specification by default.
|
|
53
|
-
def parse_teardown
|
|
53
|
+
def parse_teardown(param)
|
|
54
54
|
parse_specification(param)
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -59,8 +59,7 @@ module Rutema
|
|
|
59
59
|
# internally
|
|
60
60
|
#
|
|
61
61
|
# To avoid validating the configuration in element_* methods repeatedly, do all configuration validation here
|
|
62
|
-
def validate_configuration
|
|
63
|
-
end
|
|
62
|
+
def validate_configuration; end
|
|
64
63
|
end
|
|
65
64
|
end
|
|
66
65
|
end
|
data/lib/rutema/core/reporter.rb
CHANGED
|
@@ -24,32 +24,31 @@ module Rutema
|
|
|
24
24
|
#
|
|
25
25
|
# * +configuration+ - the Configuration instance of the test run
|
|
26
26
|
# * +dispatcher+ - unused
|
|
27
|
-
def initialize
|
|
28
|
-
@configuration=configuration
|
|
27
|
+
def initialize(configuration, _dispatcher)
|
|
28
|
+
@configuration = configuration
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
##
|
|
32
32
|
#
|
|
33
|
-
def report
|
|
34
|
-
end
|
|
33
|
+
def report(specifications, states, errors); end
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
##
|
|
38
37
|
# Event reporters receive and process information continually during a test
|
|
39
38
|
# run
|
|
40
39
|
class EventReporter
|
|
41
|
-
def initialize
|
|
42
|
-
@configuration=configuration
|
|
43
|
-
@queue=dispatcher.subscribe(
|
|
40
|
+
def initialize(configuration, dispatcher)
|
|
41
|
+
@configuration = configuration
|
|
42
|
+
@queue = dispatcher.subscribe(object_id)
|
|
44
43
|
end
|
|
45
44
|
|
|
46
45
|
def run!
|
|
47
|
-
@thread=Thread.new do
|
|
48
|
-
|
|
49
|
-
data
|
|
46
|
+
@thread = Thread.new do
|
|
47
|
+
loop do
|
|
48
|
+
data = @queue.pop
|
|
50
49
|
begin
|
|
51
50
|
update(data) if data
|
|
52
|
-
rescue
|
|
51
|
+
rescue StandardError
|
|
53
52
|
puts "#{self.class} failed with #{$!.message}"
|
|
54
53
|
raise
|
|
55
54
|
end
|
|
@@ -57,104 +56,111 @@ module Rutema
|
|
|
57
56
|
end
|
|
58
57
|
end
|
|
59
58
|
|
|
60
|
-
def update
|
|
61
|
-
end
|
|
59
|
+
def update(data); end
|
|
62
60
|
|
|
63
61
|
def exit
|
|
64
62
|
puts "Exiting #{self.class}" if $DEBUG
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Thread.kill(@thread)
|
|
71
|
-
end
|
|
63
|
+
return unless @thread
|
|
64
|
+
|
|
65
|
+
puts "Reporter died with #{@queue.size} messages in the queue" unless @thread.alive?
|
|
66
|
+
sleep 0.1 while !@queue.empty? && @thread.alive?
|
|
67
|
+
Thread.kill(@thread)
|
|
72
68
|
end
|
|
73
69
|
end
|
|
74
|
-
|
|
70
|
+
|
|
71
|
+
# This reporter is always instantiated and collects all messages fired by the rutema engine
|
|
75
72
|
#
|
|
76
|
-
#The collections of errors and states are then at the end of a run fed to the block reporters
|
|
77
|
-
class Collector<EventReporter
|
|
78
|
-
attr_reader :errors
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
@
|
|
73
|
+
# The collections of errors and states are then at the end of a run fed to the block reporters
|
|
74
|
+
class Collector < EventReporter
|
|
75
|
+
attr_reader :errors, :states
|
|
76
|
+
|
|
77
|
+
def initialize(params, dispatcher)
|
|
78
|
+
super
|
|
79
|
+
@errors = []
|
|
80
|
+
@states = {}
|
|
83
81
|
end
|
|
84
82
|
|
|
85
|
-
def update
|
|
83
|
+
def update(message)
|
|
86
84
|
case message
|
|
87
85
|
when RunnerMessage
|
|
88
|
-
test_state
|
|
86
|
+
test_state = @states[message.test]
|
|
89
87
|
if test_state
|
|
90
|
-
test_state<<message
|
|
88
|
+
test_state << message
|
|
91
89
|
else
|
|
92
|
-
test_state=Rutema::ReportState.new(message)
|
|
90
|
+
test_state = Rutema::ReportState.new(message)
|
|
93
91
|
end
|
|
94
|
-
@states[message.test]=test_state
|
|
92
|
+
@states[message.test] = test_state
|
|
95
93
|
when ErrorMessage
|
|
96
|
-
@errors<<message
|
|
94
|
+
@errors << message
|
|
97
95
|
end
|
|
98
96
|
end
|
|
99
97
|
end
|
|
100
|
-
|
|
98
|
+
|
|
99
|
+
# A very simple event reporter that outputs to the console
|
|
101
100
|
#
|
|
102
|
-
#It has three settings: off, normal and verbose.
|
|
101
|
+
# It has three settings: off, normal and verbose.
|
|
103
102
|
#
|
|
104
|
-
#Example configuration:
|
|
103
|
+
# Example configuration:
|
|
105
104
|
# cfg.reporter={:class=>Rutema::Reporters::Console, "mode"=>"verbose"}
|
|
106
|
-
class Console<EventReporter
|
|
107
|
-
def initialize
|
|
108
|
-
super
|
|
109
|
-
@mode=configuration.reporters.fetch(self.class,{})["mode"]
|
|
105
|
+
class Console < EventReporter
|
|
106
|
+
def initialize(configuration, dispatcher)
|
|
107
|
+
super
|
|
108
|
+
@mode = configuration.reporters.fetch(self.class, {})["mode"]
|
|
110
109
|
end
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
puts message.
|
|
124
|
-
when Message
|
|
125
|
-
puts message.to_s if @mode=="verbose"
|
|
110
|
+
|
|
111
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
112
|
+
def update(message)
|
|
113
|
+
return if @mode == "off"
|
|
114
|
+
|
|
115
|
+
case message
|
|
116
|
+
when RunnerMessage
|
|
117
|
+
if message.status == :error
|
|
118
|
+
puts "FATAL|#{message}"
|
|
119
|
+
elsif message.status == :warning
|
|
120
|
+
puts "WARNING|#{message}"
|
|
121
|
+
elsif @mode == "verbose"
|
|
122
|
+
puts "#{message} #{message.status}."
|
|
126
123
|
end
|
|
124
|
+
when ErrorMessage
|
|
125
|
+
puts message
|
|
126
|
+
when Message
|
|
127
|
+
puts message if @mode == "verbose"
|
|
127
128
|
end
|
|
128
129
|
end
|
|
129
130
|
end
|
|
131
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
# Produces a summary of the test run returning aggregate numbers for tests and failures
|
|
134
|
+
class Summary < BlockReporter
|
|
135
|
+
def initialize(configuration, dispatcher)
|
|
136
|
+
super
|
|
137
|
+
@silent = configuration.reporters.fetch(self.class, {})["silent"]
|
|
135
138
|
end
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
|
|
140
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
141
|
+
def report(specs, states, errors)
|
|
142
|
+
failures = []
|
|
143
|
+
states.each_value { |v| failures << v.test if v.status == :error }
|
|
139
144
|
|
|
140
145
|
unless @silent
|
|
141
|
-
count_tests_run = states.
|
|
146
|
+
count_tests_run = states.reject { |_name, state| state.is_special }.count
|
|
142
147
|
puts "#{errors.size} errors. #{count_tests_run} test cases executed. #{failures.size} failed"
|
|
143
148
|
unless failures.empty?
|
|
144
149
|
puts "Failures:"
|
|
145
|
-
puts specs.map{|spec| " #{spec.name} - #{spec.filename}" if failures.include?(spec.name)}.compact.join("\n")
|
|
150
|
+
puts specs.map { |spec| " #{spec.name} - #{spec.filename}" if failures.include?(spec.name) }.compact.join("\n")
|
|
146
151
|
end
|
|
147
152
|
end
|
|
148
|
-
return failures.size+errors.size
|
|
153
|
+
return failures.size + errors.size
|
|
149
154
|
end
|
|
150
155
|
end
|
|
151
156
|
end
|
|
152
157
|
|
|
158
|
+
# rubocop:disable-next Style/Documentation
|
|
153
159
|
module Utilities
|
|
154
160
|
require "fileutils"
|
|
155
|
-
def self.write_file
|
|
156
|
-
FileUtils.mkdir_p(File.dirname(filename)
|
|
157
|
-
File.
|
|
158
|
-
end
|
|
161
|
+
def self.write_file(filename, content)
|
|
162
|
+
FileUtils.mkdir_p(File.dirname(filename), :verbose => false)
|
|
163
|
+
File.binwrite(filename, content)
|
|
164
|
+
end
|
|
159
165
|
end
|
|
160
166
|
end
|