spectre-core 1.11.0 → 1.12.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.
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