spectre-core 1.11.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/spectre/mixin.rb CHANGED
@@ -1,34 +1,58 @@
1
- require 'ostruct'
2
- require 'spectre/logger'
3
-
4
- module Spectre
5
- module Mixin
6
- class << self
7
- @@mixins = {}
8
-
9
- def mixin desc, &block
10
- @@mixins[desc] = block
11
- end
12
-
13
- def run desc, with: []
14
- raise "no mixin with desc '#{desc}' defined" unless @@mixins.key? desc
15
- Spectre::Logger.log_debug "running mixin '#{desc}'"
16
-
17
- params = with || {}
18
-
19
- if params.is_a? Array
20
- @@mixins[desc].call *params
21
- elsif params.is_a? Hash
22
- @@mixins[desc].call OpenStruct.new(params)
23
- else
24
- @@mixins[desc].call params
25
- end
26
- end
27
-
28
- alias_method :also, :run
29
- alias_method :step, :run
30
- end
31
-
32
- Spectre.delegate :mixin, :run, :also, :step, to: Mixin
33
- end
34
- end
1
+ require_relative '../spectre'
2
+ require_relative 'logger'
3
+
4
+ require 'ostruct'
5
+
6
+ module Spectre
7
+ module Mixin
8
+ class MixinContext < Spectre::DslClass
9
+ def initialize desc
10
+ @__desc = desc
11
+ end
12
+
13
+ def required params, *keys
14
+ missing_keys = keys.select { |x| !params.to_h.key? x }
15
+ Spectre::Logger.log_debug("required parameters for '#{@__desc}': #{keys.join ', '}")
16
+ raise ArgumentError, "mixin '#{@__desc}' requires #{keys.join ', '}, but only has #{missing_keys.join ', '} given" unless missing_keys.empty?
17
+ end
18
+
19
+ def optional params, *keys
20
+ Spectre::Logger.log_debug("optional parameters for '#{@__desc}': #{keys.join ', '}")
21
+ params
22
+ end
23
+ end
24
+
25
+ class << self
26
+ @@mixins = {}
27
+
28
+ def mixin desc, &block
29
+ @@mixins[desc] = block
30
+ end
31
+
32
+ def run desc, with: []
33
+ raise "no mixin with desc '#{desc}' defined" unless @@mixins.key? desc
34
+
35
+ Spectre::Logger.log_debug "running mixin '#{desc}'"
36
+
37
+ params = with || {}
38
+
39
+ ctx = MixinContext.new(desc)
40
+
41
+ if params.is_a? Array
42
+ return_val = ctx._execute(*params, &@@mixins[desc])
43
+ elsif params.is_a? Hash
44
+ return_val = ctx._execute(OpenStruct.new(params), &@@mixins[desc])
45
+ else
46
+ return_val = ctx._execute(params, &@@mixins[desc])
47
+ end
48
+
49
+ return_val.is_a?(Hash) ? OpenStruct.new(return_val) : return_val
50
+ end
51
+
52
+ alias_method :also, :run
53
+ alias_method :step, :run
54
+ end
55
+
56
+ Spectre.delegate :mixin, :run, :also, :step, to: self
57
+ end
58
+ end
@@ -1,104 +1,102 @@
1
- module Spectre::Reporter
2
- class Console
3
- def initialize config
4
- @config = config
5
- end
6
-
7
- def report run_infos
8
-
9
- report_str = ''
10
-
11
- errors = 0
12
- failures = 0
13
- skipped = run_infos.select { |x| x.skipped? }.count
14
-
15
- run_infos
16
- .select { |x| x.error != nil or x.failure != nil }
17
- .each_with_index do |run_info, index|
18
-
19
- spec = run_info.spec
20
-
21
- report_str += "\n#{index+1}) #{format_title(run_info)}\n"
22
-
23
- if run_info.failure
24
- report_str += " Expected #{run_info.failure.expectation}"
25
- report_str += " with #{run_info.data}" if run_info.data
26
- report_str += " during #{spec.context.__desc}" if spec.context.__desc
27
-
28
- report_str += " but it failed"
29
-
30
- if run_info.failure.cause
31
- report_str += "\n with an unexpected error:\n"
32
- report_str += format_exception(run_info.failure.cause)
33
-
34
- elsif run_info.failure.message and not run_info.failure.message.empty?
35
- report_str += " with:\n #{run_info.failure.message}"
36
-
37
- else
38
- report_str += '.'
39
- end
40
-
41
- report_str += "\n"
42
- failures += 1
43
-
44
- else
45
- report_str += " but an unexpected error occured during run\n"
46
- report_str += format_exception(run_info.error)
47
- errors += 1
48
- end
49
- end
50
-
51
- if failures + errors > 0
52
- summary = ''
53
- summary += "#{run_infos.length - failures - errors - skipped} succeeded "
54
- summary += "#{failures} failures " if failures > 0
55
- summary += "#{errors} errors " if errors > 0
56
- summary += "#{skipped} skipped " if skipped > 0
57
- summary += "#{run_infos.length} total"
58
- print "\n#{summary}\n".red
59
- else
60
- summary = ''
61
- summary = "\nRun finished successfully"
62
- summary += " (#{skipped} skipped)" if skipped > 0
63
- print "#{summary}\n".green
64
- end
65
-
66
- puts report_str.red
67
- end
68
-
69
- private
70
-
71
- def format_title run_info
72
- title = run_info.spec.subject.desc
73
- title += ' ' + run_info.spec.desc
74
- title += " (#{'%.3f' % run_info.duration}s)"
75
- title += " [#{run_info.spec.name}]"
76
- title
77
- end
78
-
79
- def format_exception error
80
- non_spectre_files = error.backtrace.select { |x| !x.include? 'lib/spectre' }
81
-
82
- if non_spectre_files.count > 0
83
- causing_file = non_spectre_files.first
84
- else
85
- causing_file = error.backtrace[0]
86
- end
87
-
88
- matches = causing_file.match(/(.*\.rb):(\d+)/)
89
-
90
- return '' unless matches
91
-
92
- file, line = matches.captures
93
- file.slice!(Dir.pwd + '/')
94
-
95
- str = ''
96
- str += " file.....: #{file}\n"
97
- str += " line.....: #{line}\n"
98
- str += " type.....: #{error.class}\n"
99
- str += " message..: #{error.message}\n"
100
- str += " backtrace: \n #{error.backtrace.join("\n ")}\n" if @config['debug']
101
- str
102
- end
103
- end
104
- end
1
+ module Spectre::Reporter
2
+ class Console
3
+ def initialize config
4
+ @config = config
5
+ end
6
+
7
+ def report run_infos
8
+ report_str = ''
9
+
10
+ errors = 0
11
+ failures = 0
12
+ skipped = run_infos.select { |x| x.skipped? }.count
13
+
14
+ run_infos
15
+ .select { |x| x.error != nil or x.failure != nil }
16
+ .each_with_index do |run_info, index|
17
+ spec = run_info.spec
18
+
19
+ report_str += "\n#{index+1}) #{format_title(run_info)}\n"
20
+
21
+ if run_info.failure
22
+ report_str += " Expected #{run_info.failure.expectation}"
23
+ report_str += " with #{run_info.data}" if run_info.data
24
+ report_str += " during #{spec.context.__desc}" if spec.context.__desc
25
+
26
+ report_str += " but it failed"
27
+
28
+ if run_info.failure.cause
29
+ report_str += "\n with an unexpected error:\n"
30
+ report_str += format_exception(run_info.failure.cause)
31
+
32
+ elsif run_info.failure.message and not run_info.failure.message.empty?
33
+ report_str += " with:\n #{run_info.failure.message}"
34
+
35
+ else
36
+ report_str += '.'
37
+ end
38
+
39
+ report_str += "\n"
40
+ failures += 1
41
+
42
+ else
43
+ report_str += " but an unexpected error occured during run\n"
44
+ report_str += format_exception(run_info.error)
45
+ errors += 1
46
+ end
47
+ end
48
+
49
+ if failures + errors > 0
50
+ summary = ''
51
+ summary += "#{run_infos.length - failures - errors - skipped} succeeded "
52
+ summary += "#{failures} failures " if failures > 0
53
+ summary += "#{errors} errors " if errors > 0
54
+ summary += "#{skipped} skipped " if skipped > 0
55
+ summary += "#{run_infos.length} total"
56
+ print "\n#{summary}\n".red
57
+ else
58
+ summary = ''
59
+ summary = "\nRun finished successfully"
60
+ summary += " (#{skipped} skipped)" if skipped > 0
61
+ print "#{summary}\n".green
62
+ end
63
+
64
+ puts report_str.red
65
+ end
66
+
67
+ private
68
+
69
+ def format_title run_info
70
+ title = run_info.spec.subject.desc
71
+ title += ' ' + run_info.spec.desc
72
+ title += " (#{'%.3f' % run_info.duration}s)"
73
+ title += " [#{run_info.spec.name}]"
74
+ title
75
+ end
76
+
77
+ def format_exception error
78
+ non_spectre_files = error.backtrace.select { |x| !x.include? 'lib/spectre' }
79
+
80
+ if non_spectre_files.count > 0
81
+ causing_file = non_spectre_files.first
82
+ else
83
+ causing_file = error.backtrace[0]
84
+ end
85
+
86
+ matches = causing_file.match(/(.*\.rb):(\d+)/)
87
+
88
+ return '' unless matches
89
+
90
+ file, line = matches.captures
91
+ file.slice!(Dir.pwd + '/')
92
+
93
+ str = ''
94
+ str += " file.....: #{file}\n"
95
+ str += " line.....: #{line}\n"
96
+ str += " type.....: #{error.class}\n"
97
+ str += " message..: #{error.message}\n"
98
+ str += " backtrace: \n #{error.backtrace.join("\n ")}\n" if @config['debug']
99
+ str
100
+ end
101
+ end
102
+ end
@@ -1,100 +1,100 @@
1
- # https://llg.cubic.org/docs/junit/
2
- # Azure mappings: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/test/publish-test-results?view=azure-devops&tabs=junit%2Cyaml
3
-
4
- module Spectre::Reporter
5
- class JUnit
6
- def initialize config
7
- @config = config
8
- end
9
-
10
- def report run_infos
11
- now = Time.now.getutc
12
- timestamp = now.strftime('%s')
13
- datetime = now.strftime('%FT%T%:z')
14
-
15
- xml_str = '<?xml version="1.0" encoding="UTF-8" ?>'
16
- xml_str += '<testsuites>'
17
-
18
- suite_id = 0
19
-
20
- run_infos.group_by { |x| x.spec.subject }.each do |subject, run_infos|
21
- failures = run_infos.select { |x| x.failure != nil }
22
- errors = run_infos.select { |x| x.error != nil }
23
- skipped = run_infos.select { |x| x.skipped? }
24
-
25
- xml_str += '<testsuite package="' + subject.desc + '" id="' + suite_id.to_s + '" name="' + 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 + '">'
26
- suite_id += 1
27
-
28
- run_infos.each do |run_info|
29
- xml_str += '<testcase classname="' + run_info.spec.file.to_s + '" name="' + run_info.spec.desc + '" timestamp="' + run_info.started.to_s + '" time="' + ('%.3f' % run_info.duration) + '">'
30
-
31
- if run_info.failure and !run_info.failure.cause
32
- failure_message = "Expected #{run_info.failure.expectation}"
33
- failure_message += " with #{run_info.data}" if run_info.data
34
-
35
- if run_info.failure.message
36
- failure_message += " but it failed with #{run_info.failure.message}"
37
- else
38
- failure_message += " but it failed"
39
- end
40
-
41
- xml_str += '<failure message="' + failure_message.gsub('"', '`') + '"></failure>'
42
- end
43
-
44
-
45
- if run_info.error or (run_info.failure and run_info.failure.cause)
46
- error = run_info.error || run_info.failure.cause
47
-
48
- type = error.class.name
49
- failure_message = error.message
50
- text = error.backtrace.join "\n"
51
-
52
- xml_str += '<error message="' + failure_message.gsub('"', '`') + '" type="' + type + '">'
53
- xml_str += '<![CDATA[' + text + ']]>'
54
- xml_str += '</error>'
55
- end
56
-
57
-
58
- if run_info.log.count > 0 or run_info.properties.count > 0 or run_info.data
59
- xml_str += '<system-out>'
60
- xml_str += '<![CDATA['
61
-
62
- if run_info.properties.count > 0
63
- run_info.properties.each do |key, val|
64
- xml_str += "#{key}: #{val}\n"
65
- end
66
- end
67
-
68
- if run_info.data
69
- data_str = run_info.data
70
- data_str = run_info.data.inspect unless run_info.data.is_a? String or run_info.data.is_a? Integer
71
- xml_str += "data: #{data_str}\n"
72
- end
73
-
74
- if run_info.log.count > 0
75
- messages = run_info.log.map { |x| "[#{x[0].strftime('%F %T')}] #{x[1]}" }
76
- xml_str += messages.join("\n")
77
- end
78
-
79
- xml_str += ']]>'
80
- xml_str += '</system-out>'
81
- end
82
-
83
- xml_str += '</testcase>'
84
- end
85
-
86
- xml_str += '</testsuite>'
87
- end
88
-
89
- xml_str += '</testsuites>'
90
-
91
- Dir.mkdir @config['out_path'] if not Dir.exist? @config['out_path']
92
-
93
- file_path = File.join(@config['out_path'], "spectre-junit_#{timestamp}.xml")
94
-
95
- File.open(file_path, 'w') do |file|
96
- file.write(xml_str)
97
- end
98
- end
99
- end
100
- end
1
+ # https://llg.cubic.org/docs/junit/
2
+ # Azure mappings: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/test/publish-test-results?view=azure-devops&tabs=junit%2Cyaml
3
+
4
+ module Spectre::Reporter
5
+ class JUnit
6
+ def initialize config
7
+ @config = config
8
+ end
9
+
10
+ def report run_infos
11
+ now = Time.now.getutc
12
+ timestamp = now.strftime('%s')
13
+ datetime = now.strftime('%FT%T%:z')
14
+
15
+ xml_str = '<?xml version="1.0" encoding="UTF-8" ?>'
16
+ xml_str += '<testsuites>'
17
+
18
+ suite_id = 0
19
+
20
+ run_infos.group_by { |x| x.spec.subject }.each do |subject, run_infos|
21
+ failures = run_infos.select { |x| x.failure != nil }
22
+ errors = run_infos.select { |x| x.error != nil }
23
+ skipped = run_infos.select { |x| x.skipped? }
24
+
25
+ xml_str += '<testsuite package="' + subject.desc + '" id="' + suite_id.to_s + '" name="' + 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 + '">'
26
+ suite_id += 1
27
+
28
+ run_infos.each do |run_info|
29
+ xml_str += '<testcase classname="' + run_info.spec.file.to_s + '" name="' + run_info.spec.desc + '" timestamp="' + run_info.started.to_s + '" time="' + ('%.3f' % run_info.duration) + '">'
30
+
31
+ if run_info.failure and !run_info.failure.cause
32
+ failure_message = "Expected #{run_info.failure.expectation}"
33
+ failure_message += " with #{run_info.data}" if run_info.data
34
+
35
+ if run_info.failure.message
36
+ failure_message += " but it failed with #{run_info.failure.message}"
37
+ else
38
+ failure_message += " but it failed"
39
+ end
40
+
41
+ xml_str += '<failure message="' + failure_message.gsub('"', '`') + '"></failure>'
42
+ end
43
+
44
+
45
+ if run_info.error or (run_info.failure and run_info.failure.cause)
46
+ error = run_info.error || run_info.failure.cause
47
+
48
+ type = error.class.name
49
+ failure_message = error.message
50
+ text = error.backtrace.join "\n"
51
+
52
+ xml_str += '<error message="' + failure_message.gsub('"', '`') + '" type="' + type + '">'
53
+ xml_str += '<![CDATA[' + text + ']]>'
54
+ xml_str += '</error>'
55
+ end
56
+
57
+
58
+ if run_info.log.count > 0 or run_info.properties.count > 0 or run_info.data
59
+ xml_str += '<system-out>'
60
+ xml_str += '<![CDATA['
61
+
62
+ if run_info.properties.count > 0
63
+ run_info.properties.each do |key, val|
64
+ xml_str += "#{key}: #{val}\n"
65
+ end
66
+ end
67
+
68
+ if run_info.data
69
+ data_str = run_info.data
70
+ data_str = run_info.data.inspect unless run_info.data.is_a? String or run_info.data.is_a? Integer
71
+ xml_str += "data: #{data_str}\n"
72
+ end
73
+
74
+ if run_info.log.count > 0
75
+ messages = run_info.log.map { |x| "[#{x[0].strftime('%F %T')}] #{x[1]}" }
76
+ xml_str += messages.join("\n")
77
+ end
78
+
79
+ xml_str += ']]>'
80
+ xml_str += '</system-out>'
81
+ end
82
+
83
+ xml_str += '</testcase>'
84
+ end
85
+
86
+ xml_str += '</testsuite>'
87
+ end
88
+
89
+ xml_str += '</testsuites>'
90
+
91
+ Dir.mkdir @config['out_path'] unless Dir.exist? @config['out_path']
92
+
93
+ file_path = File.join(@config['out_path'], "spectre-junit_#{timestamp}.xml")
94
+
95
+ File.open(file_path, 'w') do |file|
96
+ file.write(xml_str)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,46 +1,49 @@
1
- require 'ostruct'
2
-
3
- module Spectre
4
- module Resources
5
- class ResourceCollection
6
- def initialize
7
- @items = {}
8
- end
9
-
10
- def add name, path
11
- @items[name] = path
12
- end
13
-
14
- def [] name
15
- raise "Resource with name '#{name}' does not exist" if not @items.key? name
16
- @items[name]
17
- end
18
- end
19
-
20
- class << self
21
- @@resources = ResourceCollection.new
22
-
23
- def resources
24
- @@resources
25
- end
26
- end
27
-
28
- Spectre.register do |config|
29
- return if !config.key? 'resource_paths'
30
-
31
- config['resource_paths'].each do |resource_path|
32
- resource_files = Dir.glob File.join(resource_path, '**/*')
33
-
34
- resource_files.each do |file|
35
- file.slice! resource_path
36
- file = file[1..-1]
37
- @@resources.add file, File.expand_path(File.join resource_path, file)
38
- end
39
- end
40
-
41
- @@resources.freeze
42
- end
43
-
44
- Spectre.delegate :resources, to: Resources
45
- end
46
- end
1
+ require_relative '../spectre'
2
+
3
+ require 'ostruct'
4
+
5
+ module Spectre
6
+ module Resources
7
+ class ResourceCollection
8
+ def initialize
9
+ @items = {}
10
+ end
11
+
12
+ def add name, path
13
+ @items[name] = path
14
+ end
15
+
16
+ def [] name
17
+ raise "Resource with name '#{name}' does not exist" unless @items.key? name
18
+
19
+ @items[name]
20
+ end
21
+ end
22
+
23
+ class << self
24
+ @@resources = ResourceCollection.new
25
+
26
+ def resources
27
+ @@resources
28
+ end
29
+ end
30
+
31
+ Spectre.register do |config|
32
+ return unless config.key? 'resource_paths'
33
+
34
+ config['resource_paths'].each do |resource_path|
35
+ resource_files = Dir.glob File.join(resource_path, '**/*')
36
+
37
+ resource_files.each do |file|
38
+ file.slice! resource_path
39
+ file = file[1..-1]
40
+ @@resources.add file, File.expand_path(File.join resource_path, file)
41
+ end
42
+ end
43
+
44
+ @@resources.freeze
45
+ end
46
+
47
+ Spectre.delegate :resources, to: self
48
+ end
49
+ end