spectre-core 1.12.3 → 1.14.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.
@@ -2,7 +2,7 @@ require_relative '../spectre'
2
2
  require 'date'
3
3
 
4
4
  module Spectre
5
- module Logger
5
+ module Logging
6
6
  module Status
7
7
  OK = '[ok]'
8
8
  FAILED = '[failed]'
@@ -12,6 +12,31 @@ module Spectre
12
12
  DEBUG = '[debug]'
13
13
  end
14
14
 
15
+ class ModuleLogger
16
+ def initialize config, name
17
+ @name = name
18
+ @debug = config['debug']
19
+ @logger = ::Logger.new(config['log_file'], progname: name)
20
+
21
+ @logger.level = @debug ? ::Logger::DEBUG : ::Logger::INFO
22
+ end
23
+
24
+ def info message
25
+ @logger.info(message)
26
+ Logging.add_log(message, :info, @name)
27
+ end
28
+
29
+ def debug message
30
+ @logger.debug(message)
31
+ Logging.add_log(message, :debug, @name) if @debug
32
+ end
33
+
34
+ def warn message
35
+ @logger.warn(message)
36
+ Logging.add_log(message, :warn, @name)
37
+ end
38
+ end
39
+
15
40
  class << self
16
41
  @@debug = false
17
42
  @@logger = []
@@ -93,24 +118,24 @@ module Spectre
93
118
  end
94
119
 
95
120
  def log_info message
96
- add_log(message)
121
+ add_log(message, :info)
97
122
  delegate(:log_info, message)
98
123
  end
99
124
 
100
125
  def log_debug message
101
126
  return unless @@debug
102
127
 
103
- add_log(message)
128
+ add_log(message, :debug)
104
129
  delegate(:log_debug, message)
105
130
  end
106
131
 
107
132
  def log_error spec, exception
108
- add_log(exception)
133
+ add_log(exception, :error)
109
134
  delegate(:log_error, spec, exception)
110
135
  end
111
136
 
112
- def log_skipped spec
113
- delegate(:log_skipped, spec)
137
+ def log_skipped spec, message=nil
138
+ delegate(:log_skipped, spec, message)
114
139
  end
115
140
 
116
141
  def log_status desc, status, annotation=nil
@@ -118,9 +143,15 @@ module Spectre
118
143
  end
119
144
 
120
145
  def group desc
121
- Logger.start_group desc
146
+ Logging.start_group desc
122
147
  yield
123
- Logger.end_group desc
148
+ Logging.end_group desc
149
+ end
150
+
151
+ def add_log message, level, logger_name='spectre'
152
+ return unless Spectre::Runner.current
153
+
154
+ Spectre::Runner.current.log.append([DateTime.now, message, level, logger_name])
124
155
  end
125
156
 
126
157
  alias_method :info, :log_info
@@ -135,10 +166,6 @@ module Spectre
135
166
  logger.send(method, *args) if logger.respond_to? method
136
167
  end
137
168
  end
138
-
139
- def add_log message
140
- Spectre::Runner.current.log.append([DateTime.now, message])
141
- end
142
169
  end
143
170
 
144
171
  Spectre.delegate :log, :info, :debug, :group, :separate, to: self
data/lib/spectre/mixin.rb CHANGED
@@ -12,12 +12,12 @@ module Spectre
12
12
 
13
13
  def required params, *keys
14
14
  missing_keys = keys.select { |x| !params.to_h.key? x }
15
- Spectre::Logger.log_debug("required parameters for '#{@__desc}': #{keys.join ', '}")
15
+ Spectre::Logging.log_debug("required parameters for '#{@__desc}': #{keys.join ', '}")
16
16
  raise ArgumentError, "mixin '#{@__desc}' requires #{keys.join ', '}, but only has #{missing_keys.join ', '} given" unless missing_keys.empty?
17
17
  end
18
18
 
19
19
  def optional params, *keys
20
- Spectre::Logger.log_debug("optional parameters for '#{@__desc}': #{keys.join ', '}")
20
+ Spectre::Logging.log_debug("optional parameters for '#{@__desc}': #{keys.join ', '}")
21
21
  params
22
22
  end
23
23
  end
@@ -32,7 +32,7 @@ module Spectre
32
32
  def run desc, with: []
33
33
  raise "no mixin with desc '#{desc}' defined" unless @@mixins.key? desc
34
34
 
35
- Spectre::Logger.log_debug "running mixin '#{desc}'"
35
+ Spectre::Logging.log_debug "running mixin '#{desc}'"
36
36
 
37
37
  params = with || {}
38
38
 
@@ -14,36 +14,34 @@ module Spectre::Reporter
14
14
  run_infos
15
15
  .select { |x| x.error != nil or x.failure != nil }
16
16
  .each_with_index do |run_info, index|
17
- spec = run_info.spec
17
+ report_str += "\n#{index+1}) #{format_title(run_info)}\n"
18
18
 
19
- report_str += "\n#{index+1}) #{format_title(run_info)}\n"
19
+ if run_info.failure
20
+ report_str += " Expected #{run_info.failure.expectation}"
21
+ report_str += " with #{run_info.data}" if run_info.data
20
22
 
21
- if run_info.failure
22
- report_str += " Expected #{run_info.failure.expectation}"
23
- report_str += " with #{run_info.data}" if run_info.data
23
+ report_str += " but it failed"
24
24
 
25
- report_str += " but it failed"
25
+ if run_info.failure.cause
26
+ report_str += "\n with an unexpected error:\n"
27
+ report_str += format_exception(run_info.failure.cause)
26
28
 
27
- if run_info.failure.cause
28
- report_str += "\n with an unexpected error:\n"
29
- report_str += format_exception(run_info.failure.cause)
29
+ elsif run_info.failure.message and not run_info.failure.message.empty?
30
+ report_str += " with:\n #{run_info.failure.message}"
30
31
 
31
- elsif run_info.failure.message and not run_info.failure.message.empty?
32
- report_str += " with:\n #{run_info.failure.message}"
32
+ else
33
+ report_str += '.'
34
+ end
35
+
36
+ report_str += "\n"
37
+ failures += 1
33
38
 
34
39
  else
35
- report_str += '.'
40
+ report_str += " but an unexpected error occurred during run\n"
41
+ report_str += format_exception(run_info.error)
42
+ errors += 1
36
43
  end
37
-
38
- report_str += "\n"
39
- failures += 1
40
-
41
- else
42
- report_str += " but an unexpected error occurred during run\n"
43
- report_str += format_exception(run_info.error)
44
- errors += 1
45
44
  end
46
- end
47
45
 
48
46
  if failures + errors > 0
49
47
  summary = ''
@@ -54,7 +52,6 @@ module Spectre::Reporter
54
52
  summary += "#{run_infos.length} total"
55
53
  print "\n#{summary}\n".red
56
54
  else
57
- summary = ''
58
55
  summary = "\nRun finished successfully"
59
56
  summary += " (#{skipped} skipped)" if skipped > 0
60
57
  print "#{summary}\n".green
data/lib/spectre.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Spectre
2
2
  module Version
3
3
  MAJOR = 1
4
- MINOR = 12
5
- TINY = 3
4
+ MINOR = 14
5
+ TINY = 0
6
6
  end
7
7
 
8
8
  VERSION = [Version::MAJOR, Version::MINOR, Version::TINY].compact * '.'
@@ -10,7 +10,7 @@ module Spectre
10
10
 
11
11
  class ::Hash
12
12
  def deep_merge!(second)
13
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge!(v2, &merger) : v2 }
13
+ merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge!(v2, &merger) : v2 }
14
14
  self.merge!(second, &merger)
15
15
  end
16
16
 
@@ -34,9 +34,6 @@ module Spectre
34
34
 
35
35
 
36
36
  class SpectreError < Exception
37
- def initialize message
38
- super message
39
- end
40
37
  end
41
38
 
42
39
  class ExpectationFailure < Exception
@@ -48,6 +45,9 @@ module Spectre
48
45
  end
49
46
  end
50
47
 
48
+ class SpectreSkip < Interrupt
49
+ end
50
+
51
51
 
52
52
  ###########################################
53
53
  # Internal Classes
@@ -111,7 +111,7 @@ module Spectre
111
111
 
112
112
  class RunInfo
113
113
  attr_accessor :spec, :data, :started, :finished, :error, :failure, :skipped
114
- attr_reader :log, :properties
114
+ attr_reader :expectations, :log, :properties
115
115
 
116
116
  def initialize spec, data=nil
117
117
  @spec = spec
@@ -122,6 +122,7 @@ module Spectre
122
122
  @failure = nil
123
123
  @skipped = false
124
124
  @log = []
125
+ @expectations = []
125
126
  @properties = {}
126
127
  end
127
128
 
@@ -134,12 +135,24 @@ module Spectre
134
135
  end
135
136
 
136
137
  def failed?
138
+ @failure != nil
139
+ end
140
+
141
+ def error?
137
142
  @error != nil
138
143
  end
144
+
145
+ def status
146
+ return :error if error?
147
+ return :failed if failed?
148
+ return :skipped if skipped?
149
+
150
+ return :success
151
+ end
139
152
  end
140
153
 
141
154
  class Runner
142
- @@current
155
+ @@current = nil
143
156
 
144
157
  def self.current
145
158
  @@current
@@ -148,11 +161,11 @@ module Spectre
148
161
  def run specs
149
162
  runs = []
150
163
 
151
- specs.group_by { |x| x.subject }.each do |subject, spec_group|
152
- Logger.log_subject subject do
153
- spec_group.group_by { |x| x.context }.each do |context, specs|
154
- Logger.log_context(context) do
155
- runs.concat run_context(context, specs)
164
+ specs.group_by { |x| x.subject }.each do |subject, subject_specs|
165
+ Logging.log_subject subject do
166
+ subject_specs.group_by { |x| x.context }.each do |context, context_specs|
167
+ Logging.log_context(context) do
168
+ runs.concat run_context(context, context_specs)
156
169
  end
157
170
  end
158
171
  end
@@ -166,8 +179,8 @@ module Spectre
166
179
  def run_context context, specs
167
180
  runs = []
168
181
 
169
- if context.__setup_blocks.count > 0
170
- setup_run = run_blocks('setup', context, context.__setup_blocks)
182
+ context.__setup_blocks.each do |setup_spec|
183
+ setup_run = run_setup(setup_spec)
171
184
  runs << setup_run
172
185
  return runs if setup_run.error or setup_run.failure
173
186
  end
@@ -180,47 +193,42 @@ module Spectre
180
193
  spec.data
181
194
  .map { |x| x.is_a?(Hash) ? OpenStruct.new(x) : x }
182
195
  .each do |data|
183
- Logger.log_spec(spec, data) do
196
+ Logging.log_spec(spec, data) do
184
197
  runs << run_spec(spec, data)
185
198
  end
186
199
  end
187
200
  else
188
- Logger.log_spec(spec) do
201
+ Logging.log_spec(spec) do
189
202
  runs << run_spec(spec)
190
203
  end
191
204
  end
192
205
  end
193
206
  ensure
194
- if context.__teardown_blocks.count > 0
195
- runs << run_blocks('teardown', context, context.__teardown_blocks)
207
+ context.__teardown_blocks.each do |teardown_spec|
208
+ runs << run_setup(teardown_spec)
196
209
  end
197
210
  end
198
211
 
199
212
  runs
200
213
  end
201
214
 
202
- def run_blocks name, context, blocks
203
- ctx = SpecContext.new context.__subject, name
204
- spec = Spec.new name, context.__subject, name, [], nil, nil, ctx, nil
205
-
206
- run_info = RunInfo.new spec
215
+ def run_setup spec
216
+ run_info = RunInfo.new(spec)
207
217
 
208
218
  @@current = run_info
209
219
 
210
220
  run_info.started = Time.now
211
221
 
212
- Logger.log_context ctx do
222
+ Logging.log_context(spec.context) do
213
223
  begin
214
- blocks.each do |block|
215
- block.call
216
- end
224
+ spec.block.call()
217
225
 
218
226
  run_info.finished = Time.now
219
227
  rescue ExpectationFailure => e
220
228
  run_info.failure = e
221
229
  rescue Exception => e
222
230
  run_info.error = e
223
- Logger.log_error spec, e
231
+ Logging.log_error(spec, e)
224
232
  end
225
233
  end
226
234
 
@@ -240,9 +248,9 @@ module Spectre
240
248
 
241
249
  begin
242
250
  if spec.context.__before_blocks.count > 0
243
- before_ctx = SpecContext.new(spec.subject, 'before')
251
+ before_ctx = SpecContext.new(spec.subject, 'before', spec.context)
244
252
 
245
- Logger.log_context before_ctx do
253
+ Logging.log_context before_ctx do
246
254
  spec.context.__before_blocks.each do |block|
247
255
  block.call(data)
248
256
  end
@@ -252,17 +260,20 @@ module Spectre
252
260
  spec.block.call(data)
253
261
  rescue ExpectationFailure => e
254
262
  run_info.failure = e
263
+ rescue SpectreSkip => e
264
+ run_info.skipped = true
265
+ Logging.log_skipped(spec, e.message)
255
266
  rescue Interrupt
256
267
  run_info.skipped = true
257
- Logger.log_skipped spec
268
+ Logging.log_skipped(spec, 'canceled by user')
258
269
  rescue Exception => e
259
270
  run_info.error = e
260
- Logger.log_error spec, e
271
+ Logging.log_error(spec, e)
261
272
  ensure
262
273
  if spec.context.__after_blocks.count > 0
263
- after_ctx = SpecContext.new(spec.subject, 'after')
274
+ after_ctx = SpecContext.new(spec.subject, 'after', spec.context)
264
275
 
265
- Logger.log_context after_ctx do
276
+ Logging.log_context after_ctx do
266
277
  begin
267
278
  spec.context.__after_blocks.each do |block|
268
279
  block.call
@@ -273,7 +284,7 @@ module Spectre
273
284
  run_info.failure = e
274
285
  rescue Exception => e
275
286
  run_info.error = e
276
- Logger.log_error spec, e
287
+ Logging.log_error(spec, e)
277
288
  end
278
289
  end
279
290
  end
@@ -294,11 +305,12 @@ module Spectre
294
305
 
295
306
 
296
307
  class SpecContext < DslClass
297
- attr_reader :__subject, :__desc, :__before_blocks, :__after_blocks, :__setup_blocks, :__teardown_blocks
308
+ attr_reader :__subject, :__desc, :__parent, :__before_blocks, :__after_blocks, :__setup_blocks, :__teardown_blocks
298
309
 
299
- def initialize subject, desc=nil
310
+ def initialize subject, desc=nil, parent=nil
300
311
  @__subject = subject
301
312
  @__desc = desc
313
+ @__parent = parent
302
314
 
303
315
  @__before_blocks = []
304
316
  @__after_blocks = []
@@ -307,20 +319,7 @@ module Spectre
307
319
  end
308
320
 
309
321
  def it desc, tags: [], with: [], &block
310
- # Get the file, where the spec is defined.
311
- # Nasty, but it works
312
- # Maybe there is another way, but this works for now
313
- spec_file = nil
314
- begin
315
- raise
316
- rescue => e
317
- spec_file = e.backtrace
318
- .select { |file| !file.include? 'lib/spectre' }
319
- .first
320
- .match(/(.*\.rb):\d+/)
321
- .captures
322
- .first
323
- end
322
+ spec_file = get_file()
324
323
 
325
324
  @__subject.add_spec(desc, tags, with, block, self, spec_file)
326
325
  end
@@ -334,17 +333,44 @@ module Spectre
334
333
  end
335
334
 
336
335
  def setup &block
337
- @__setup_blocks << block
336
+ name = "#{@__subject.name}-setup"
337
+ spec_file = get_file()
338
+
339
+ setup_ctx = SpecContext.new(@__subject, 'setup', self)
340
+ @__setup_blocks << Spec.new(name, @__subject, 'setup', [], nil, block, setup_ctx, spec_file)
338
341
  end
339
342
 
340
343
  def teardown &block
341
- @__teardown_blocks << block
344
+ name = "#{@__subject.name}-teardown"
345
+ spec_file = get_file()
346
+
347
+ teardown_ctx = SpecContext.new(@__subject, 'teardown', self)
348
+ @__teardown_blocks << Spec.new(name, @__subject, 'teardown', [], nil, block, teardown_ctx, spec_file)
342
349
  end
343
350
 
344
351
  def context desc=nil, &block
345
- ctx = SpecContext.new(@__subject, desc)
352
+ ctx = SpecContext.new(@__subject, desc, self)
346
353
  ctx._evaluate &block
347
354
  end
355
+
356
+ private
357
+
358
+ def get_file
359
+ # Get the file, where the spec is defined.
360
+ # Nasty, but it works
361
+ # Maybe there is another way, but this works for now
362
+
363
+ begin
364
+ raise
365
+ rescue => e
366
+ return e.backtrace
367
+ .select { |file| !file.include? 'lib/spectre' }
368
+ .first
369
+ .match(/(.*\.rb):\d+/)
370
+ .captures
371
+ .first
372
+ end
373
+ end
348
374
  end
349
375
 
350
376
 
@@ -397,14 +423,14 @@ module Spectre
397
423
 
398
424
  def tag? tags, tag_exp
399
425
  tags = tags.map { |x| x.to_s }
400
- all_tags = tag_exp.split '+'
426
+ all_tags = tag_exp.split('+')
401
427
  included_tags = all_tags.select { |x| !x.start_with? '!' }
402
428
  excluded_tags = all_tags.select { |x| x.start_with? '!' }.map { |x| x[1..-1] }
403
429
  included_tags & tags == included_tags and excluded_tags & tags == []
404
430
  end
405
431
 
406
432
  def delegate *method_names, to: nil
407
- Spectre::Delegator.delegate *method_names, to
433
+ Spectre::Delegator.delegate(*method_names, to)
408
434
  end
409
435
 
410
436
  def register &block
@@ -438,9 +464,13 @@ module Spectre
438
464
  def property key, val
439
465
  Spectre::Runner.current.properties[key] = val
440
466
  end
467
+
468
+ def skip message=nil
469
+ raise SpectreSkip.new(message)
470
+ end
441
471
  end
442
472
 
443
- delegate :describe, :property, to: Spectre
473
+ delegate :describe, :property, :skip, to: Spectre
444
474
  end
445
475
 
446
476
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectre-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.3
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Neubauer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-01 00:00:00.000000000 Z
11
+ date: 2022-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ectoplasm
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.2.1
19
+ version: 1.2.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.2.1
26
+ version: 1.2.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: jsonpath
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -49,6 +49,7 @@ files:
49
49
  - exe/spectre
50
50
  - lib/spectre.rb
51
51
  - lib/spectre/assertion.rb
52
+ - lib/spectre/async.rb
52
53
  - lib/spectre/bag.rb
53
54
  - lib/spectre/curl.rb
54
55
  - lib/spectre/diagnostic.rb
@@ -62,17 +63,15 @@ files:
62
63
  - lib/spectre/logger/file.rb
63
64
  - lib/spectre/mixin.rb
64
65
  - lib/spectre/reporter/console.rb
65
- - lib/spectre/reporter/junit.rb
66
66
  - lib/spectre/resources.rb
67
67
  homepage: https://github.com/ionos-spectre/spectre-core
68
68
  licenses:
69
69
  - GPL-3.0-or-later
70
70
  metadata:
71
- allowed_push_host: https://rubygems.org/
72
71
  homepage_uri: https://github.com/ionos-spectre/spectre-core
73
72
  source_code_uri: https://github.com/ionos-spectre/spectre-core
74
73
  changelog_uri: https://github.com/ionos-spectre/spectre-core/blob/master/CHANGELOG.md
75
- post_install_message:
74
+ post_install_message:
76
75
  rdoc_options: []
77
76
  require_paths:
78
77
  - lib
@@ -80,15 +79,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
79
  requirements:
81
80
  - - ">="
82
81
  - !ruby/object:Gem::Version
83
- version: 2.5.0
82
+ version: 3.0.0
84
83
  required_rubygems_version: !ruby/object:Gem::Requirement
85
84
  requirements:
86
85
  - - ">="
87
86
  - !ruby/object:Gem::Version
88
87
  version: '0'
89
88
  requirements: []
90
- rubygems_version: 3.2.3
91
- signing_key:
89
+ rubygems_version: 3.3.7
90
+ signing_key:
92
91
  specification_version: 4
93
92
  summary: Describe and run automated tests
94
93
  test_files: []
@@ -1,102 +0,0 @@
1
- require 'CGI'
2
-
3
- # https://llg.cubic.org/docs/junit/
4
- # Azure mappings: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/test/publish-test-results?view=azure-devops&tabs=junit%2Cyaml
5
-
6
- module Spectre::Reporter
7
- class JUnit
8
- def initialize config
9
- @config = config
10
- end
11
-
12
- def report run_infos
13
- now = Time.now.getutc
14
- timestamp = now.strftime('%s')
15
- datetime = now.strftime('%FT%T%:z')
16
-
17
- xml_str = '<?xml version="1.0" encoding="UTF-8" ?>'
18
- xml_str += '<testsuites>'
19
-
20
- suite_id = 0
21
-
22
- run_infos.group_by { |x| x.spec.subject }.each do |subject, run_infos|
23
- failures = run_infos.select { |x| x.failure != nil }
24
- errors = run_infos.select { |x| x.error != nil }
25
- skipped = run_infos.select { |x| x.skipped? }
26
-
27
- xml_str += '<testsuite package="' + CGI::escapeHTML(subject.desc) + '" id="' + CGI::escapeHTML(suite_id.to_s) + '" name="' + CGI::escapeHTML(subject.desc) + '" timestamp="' + datetime + '" tests="' + run_infos.count.to_s + '" failures="' + failures.count.to_s + '" errors="' + errors.count.to_s + '" skipped="' + skipped.count.to_s + '">'
28
- suite_id += 1
29
-
30
- run_infos.each do |run_info|
31
- xml_str += '<testcase classname="' + CGI::escapeHTML(run_info.spec.file.to_s) + '" name="' + CGI::escapeHTML(run_info.spec.desc) + '" timestamp="' + run_info.started.to_s + '" time="' + ('%.3f' % run_info.duration) + '">'
32
-
33
- if run_info.failure and !run_info.failure.cause
34
- failure_message = "Expected #{run_info.failure.expectation}"
35
- failure_message += " with #{run_info.data}" if run_info.data
36
-
37
- if run_info.failure.message
38
- failure_message += " but it failed with #{run_info.failure.message}"
39
- else
40
- failure_message += " but it failed"
41
- end
42
-
43
- xml_str += '<failure message="' + CGI::escapeHTML(failure_message.gsub('"', '`')) + '"></failure>'
44
- end
45
-
46
-
47
- if run_info.error or (run_info.failure and run_info.failure.cause)
48
- error = run_info.error || run_info.failure.cause
49
-
50
- type = error.class.name
51
- failure_message = error.message
52
- text = error.backtrace.join "\n"
53
-
54
- xml_str += '<error message="' + CGI::escapeHTML(failure_message.gsub('"', '`')) + '" type="' + type + '">'
55
- xml_str += '<![CDATA[' + text + ']]>'
56
- xml_str += '</error>'
57
- end
58
-
59
-
60
- if run_info.log.count > 0 or run_info.properties.count > 0 or run_info.data
61
- xml_str += '<system-out>'
62
- xml_str += '<![CDATA['
63
-
64
- if run_info.properties.count > 0
65
- run_info.properties.each do |key, val|
66
- xml_str += "#{key}: #{val}\n"
67
- end
68
- end
69
-
70
- if run_info.data
71
- data_str = run_info.data
72
- data_str = run_info.data.inspect unless run_info.data.is_a? String or run_info.data.is_a? Integer
73
- xml_str += "data: #{data_str}\n"
74
- end
75
-
76
- if run_info.log.count > 0
77
- messages = run_info.log.map { |x| "[#{x[0].strftime('%F %T')}] #{x[1]}" }
78
- xml_str += messages.join("\n")
79
- end
80
-
81
- xml_str += ']]>'
82
- xml_str += '</system-out>'
83
- end
84
-
85
- xml_str += '</testcase>'
86
- end
87
-
88
- xml_str += '</testsuite>'
89
- end
90
-
91
- xml_str += '</testsuites>'
92
-
93
- Dir.mkdir @config['out_path'] unless Dir.exist? @config['out_path']
94
-
95
- file_path = File.join(@config['out_path'], "spectre-junit_#{timestamp}.xml")
96
-
97
- File.open(file_path, 'w') do |file|
98
- file.write(xml_str)
99
- end
100
- end
101
- end
102
- end