moto 0.0.22 → 0.0.23
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/bin/moto +5 -5
- data/lib/app_generator.rb +8 -8
- data/lib/clients/base.rb +29 -23
- data/lib/clients/website.rb +8 -4
- data/lib/empty_listener.rb +16 -16
- data/lib/exceptions/moto.rb +6 -6
- data/lib/exceptions/test_forced_failure.rb +6 -6
- data/lib/exceptions/test_forced_passed.rb +6 -6
- data/lib/exceptions/test_skipped.rb +6 -6
- data/lib/forward_context_methods.rb +20 -20
- data/lib/initializer.rb +6 -6
- data/lib/listeners/base.rb +25 -25
- data/lib/listeners/console.rb +28 -28
- data/lib/listeners/console_dots.rb +62 -62
- data/lib/listeners/junit_xml.rb +36 -36
- data/lib/page.rb +27 -31
- data/lib/parser.rb +103 -103
- data/lib/result.rb +83 -83
- data/lib/runner_logging.rb +26 -26
- data/lib/test_logging.rb +48 -48
- data/lib/thread_context.rb +13 -6
- data/lib/version.rb +1 -1
- metadata +25 -25
data/lib/listeners/junit_xml.rb
CHANGED
@@ -1,37 +1,37 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
module Moto
|
4
|
-
module Listeners
|
5
|
-
class JunitXml < Base
|
6
|
-
|
7
|
-
def end_run
|
8
|
-
path = @runner.my_config[:output_file]
|
9
|
-
|
10
|
-
builder = Nokogiri::XML::Builder.new { |xml|
|
11
|
-
xml.testsuite(
|
12
|
-
errors: @runner.result.summary[:cnt_error],
|
13
|
-
failures: @runner.result.summary[:cnt_failure],
|
14
|
-
name: "Moto run",
|
15
|
-
tests: @runner.result.summary[:cnt_all],
|
16
|
-
time: @runner.result.summary[:duration],
|
17
|
-
timestamp: Time.at(@runner.result.summary[:started_at])) do
|
18
|
-
@runner.result.all.each do |test_name, data|
|
19
|
-
xml.testcase(name: test_name, time: data[:duration], classname: data[:class].name, moto_result: data[:result]) do
|
20
|
-
if !data[:error].nil?
|
21
|
-
xml.error(message: data[:error].message)
|
22
|
-
elsif data[:failures].count > 0
|
23
|
-
data[:failures].each do |f|
|
24
|
-
xml.failure(message: f)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
}
|
31
|
-
|
32
|
-
File.open(path, 'w') {|f| f.write(builder.to_xml) }
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Moto
|
4
|
+
module Listeners
|
5
|
+
class JunitXml < Base
|
6
|
+
|
7
|
+
def end_run
|
8
|
+
path = @runner.my_config[:output_file]
|
9
|
+
|
10
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
11
|
+
xml.testsuite(
|
12
|
+
errors: @runner.result.summary[:cnt_error],
|
13
|
+
failures: @runner.result.summary[:cnt_failure],
|
14
|
+
name: "Moto run",
|
15
|
+
tests: @runner.result.summary[:cnt_all],
|
16
|
+
time: @runner.result.summary[:duration],
|
17
|
+
timestamp: Time.at(@runner.result.summary[:started_at])) do
|
18
|
+
@runner.result.all.each do |test_name, data|
|
19
|
+
xml.testcase(name: test_name, time: data[:duration], classname: data[:class].name, moto_result: data[:result]) do
|
20
|
+
if !data[:error].nil?
|
21
|
+
xml.error(message: data[:error].message)
|
22
|
+
elsif data[:failures].count > 0
|
23
|
+
data[:failures].each do |f|
|
24
|
+
xml.failure(message: f)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
}
|
31
|
+
|
32
|
+
File.open(path, 'w') {|f| f.write(builder.to_xml) }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
37
|
end
|
data/lib/page.rb
CHANGED
@@ -1,32 +1,28 @@
|
|
1
|
-
module Moto
|
2
|
-
|
3
|
-
class Page
|
4
|
-
|
5
|
-
include Moto::TestLogging
|
6
|
-
include Moto::ForwardContextMethods
|
7
|
-
|
8
|
-
ignore_logging :const
|
9
|
-
ignore_logging :session
|
10
|
-
|
11
|
-
attr_reader :website
|
12
|
-
attr_reader :context
|
13
|
-
|
14
|
-
def initialize(website)
|
15
|
-
@website = website
|
16
|
-
@context = @website.context
|
17
|
-
end
|
18
|
-
|
19
|
-
def
|
20
|
-
@website.
|
21
|
-
end
|
22
|
-
|
23
|
-
def
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
raise "Invalid state: page #{self.class.name} is not loaded." unless loaded?
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
1
|
+
module Moto
|
2
|
+
|
3
|
+
class Page
|
4
|
+
|
5
|
+
include Moto::TestLogging
|
6
|
+
include Moto::ForwardContextMethods
|
7
|
+
|
8
|
+
ignore_logging :const
|
9
|
+
ignore_logging :session
|
10
|
+
|
11
|
+
attr_reader :website
|
12
|
+
attr_reader :context
|
13
|
+
|
14
|
+
def initialize(website)
|
15
|
+
@website = website
|
16
|
+
@context = @website.context
|
17
|
+
end
|
18
|
+
|
19
|
+
def page(p)
|
20
|
+
@context.client(@website.class.name.split('::').pop).page(p)
|
21
|
+
end
|
22
|
+
|
23
|
+
def raise_unless_loaded
|
24
|
+
raise "Invalid state: page #{self.class.name} is not loaded." unless loaded?
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
32
28
|
end
|
data/lib/parser.rb
CHANGED
@@ -1,103 +1,103 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
require_relative '../lib/cli'
|
5
|
-
require_relative '../lib/app_generator'
|
6
|
-
|
7
|
-
module Moto
|
8
|
-
|
9
|
-
class Parser
|
10
|
-
|
11
|
-
def self.run(argv)
|
12
|
-
begin
|
13
|
-
# TODO Generate app / Change the way parsing options goes so it doesnt generate them if they`re not needed
|
14
|
-
case argv[0]
|
15
|
-
when '--version' then puts Moto::VERSION
|
16
|
-
when 'run' then Moto::Cli.run run_parse(argv)
|
17
|
-
when 'help' then show_help
|
18
|
-
when 'generate' then Moto::AppGenerator.run generate_parse(argv)
|
19
|
-
else puts "Command '#{argv[0]}' not recognized. Type help for list of supported commands."
|
20
|
-
end
|
21
|
-
rescue Exception => e
|
22
|
-
puts e.message
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.run_parse(argv)
|
27
|
-
|
28
|
-
# TODO: fix this dumb verification of current working directory.
|
29
|
-
unless File.exists? "#{MotoApp::DIR}/config/moto.rb"
|
30
|
-
msg = "Config file (config/moto.rb) not present.\n"
|
31
|
-
msg << 'Does current working directory contain Moto application?'
|
32
|
-
raise msg
|
33
|
-
end
|
34
|
-
|
35
|
-
require 'bundler/setup'
|
36
|
-
Bundler.require
|
37
|
-
|
38
|
-
# Default options
|
39
|
-
options = {}
|
40
|
-
options[:reporters] = []
|
41
|
-
# TODO Mandatory env var in app config
|
42
|
-
options[:config] = eval(File.read("#{MotoApp::DIR}/config/moto.rb"))
|
43
|
-
options[:environments] = []
|
44
|
-
options[:name] = ""
|
45
|
-
|
46
|
-
# Parse arguments
|
47
|
-
# TODO eval ?
|
48
|
-
# TODO const
|
49
|
-
# TODO reporters should be consts - not strings
|
50
|
-
OptionParser.new do |opts|
|
51
|
-
opts.on('-t', '--tests Tests', Array) { |v| options[:tests ] = v }
|
52
|
-
opts.on('-g', '--tags Tags', Array) { |v| options[:tags ] = v }
|
53
|
-
opts.on('-r', '--reporters Reporters', Array) { |v| options[:reporters] = v }
|
54
|
-
opts.on('-e', '--environments Environment', Array) { |v| options[:environments] = v }
|
55
|
-
opts.on('-c', '--const Const') { |v| options[:const] = v }
|
56
|
-
opts.on('-n', '--name Name') { |v| options[:name] = v }
|
57
|
-
opts.on('-f', '--config Config') { |v| options[:config]
|
58
|
-
end.parse!
|
59
|
-
|
60
|
-
if options[:name].empty?
|
61
|
-
options[:name] = evaluate_name(options[:tags], options[:tests])
|
62
|
-
end
|
63
|
-
|
64
|
-
if options[ :config ][ :moto ][ :runner ][ :mandatory_environment ] && options[ :environments ].empty?
|
65
|
-
puts 'Environment is mandatory for this project.'
|
66
|
-
exit 1
|
67
|
-
end
|
68
|
-
|
69
|
-
return options
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.evaluate_name(tags, tests)
|
73
|
-
tags ||= ""
|
74
|
-
tests ||= ""
|
75
|
-
if !tags.empty? && !tests.empty?
|
76
|
-
return "#{tags.count} tags + #{tests.count} tests"
|
77
|
-
elsif tags.empty?
|
78
|
-
return tests.count == 1 ? "Test: #{tests.first}" : "#{tests.count} tests"
|
79
|
-
elsif tests.empty?
|
80
|
-
return tags.count == 1 ? "Tag: #{tags.first}" : "#{tags.count} tags"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.generate_parse(argv)
|
85
|
-
options = {}
|
86
|
-
options[:dir]
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.show_help
|
90
|
-
puts """
|
91
|
-
Moto (#{Moto::VERSION}) CLI Help:
|
92
|
-
moto --version Display current version
|
93
|
-
moto run:
|
94
|
-
-t, --tests = Tests to be executed. For e.x Tests\Failure\Failure.rb should be passed as Tests::Failure
|
95
|
-
-r, --reporter = Reporters to be used. Defaults are Moto::Listeners::ConsoleDots, Moto::Listeners::JunitXml
|
96
|
-
-e, --environment etc etc
|
97
|
-
moto generate:
|
98
|
-
moto generate app_name -d, --dir = directory. Default is current dir.
|
99
|
-
"""
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
end
|
1
|
+
require 'optparse'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
require_relative '../lib/cli'
|
5
|
+
require_relative '../lib/app_generator'
|
6
|
+
|
7
|
+
module Moto
|
8
|
+
|
9
|
+
class Parser
|
10
|
+
|
11
|
+
def self.run(argv)
|
12
|
+
begin
|
13
|
+
# TODO Generate app / Change the way parsing options goes so it doesnt generate them if they`re not needed
|
14
|
+
case argv[0]
|
15
|
+
when '--version' then puts Moto::VERSION
|
16
|
+
when 'run' then Moto::Cli.run run_parse(argv)
|
17
|
+
when 'help' then show_help
|
18
|
+
when 'generate' then Moto::AppGenerator.run generate_parse(argv)
|
19
|
+
else puts "Command '#{argv[0]}' not recognized. Type help for list of supported commands."
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
puts e.message
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.run_parse(argv)
|
27
|
+
|
28
|
+
# TODO: fix this dumb verification of current working directory.
|
29
|
+
unless File.exists? "#{MotoApp::DIR}/config/moto.rb"
|
30
|
+
msg = "Config file (config/moto.rb) not present.\n"
|
31
|
+
msg << 'Does current working directory contain Moto application?'
|
32
|
+
raise msg
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'bundler/setup'
|
36
|
+
Bundler.require
|
37
|
+
|
38
|
+
# Default options
|
39
|
+
options = {}
|
40
|
+
options[:reporters] = []
|
41
|
+
# TODO Mandatory env var in app config
|
42
|
+
options[:config] = eval(File.read("#{MotoApp::DIR}/config/moto.rb"))
|
43
|
+
options[:environments] = []
|
44
|
+
options[:name] = ""
|
45
|
+
|
46
|
+
# Parse arguments
|
47
|
+
# TODO eval ?
|
48
|
+
# TODO const
|
49
|
+
# TODO reporters should be consts - not strings
|
50
|
+
OptionParser.new do |opts|
|
51
|
+
opts.on('-t', '--tests Tests', Array) { |v| options[:tests ] = v }
|
52
|
+
opts.on('-g', '--tags Tags', Array) { |v| options[:tags ] = v }
|
53
|
+
opts.on('-r', '--reporters Reporters', Array) { |v| options[:reporters] = v }
|
54
|
+
opts.on('-e', '--environments Environment', Array) { |v| options[:environments] = v }
|
55
|
+
opts.on('-c', '--const Const') { |v| options[:const] = v }
|
56
|
+
opts.on('-n', '--name Name') { |v| options[:name] = v }
|
57
|
+
opts.on('-f', '--config Config') { |v| options[:config].deep_merge!( eval( File.read(v) ) ) }
|
58
|
+
end.parse!
|
59
|
+
|
60
|
+
if options[:name].empty?
|
61
|
+
options[:name] = evaluate_name(options[:tags], options[:tests])
|
62
|
+
end
|
63
|
+
|
64
|
+
if options[ :config ][ :moto ][ :runner ][ :mandatory_environment ] && options[ :environments ].empty?
|
65
|
+
puts 'Environment is mandatory for this project.'
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
|
69
|
+
return options
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.evaluate_name(tags, tests)
|
73
|
+
tags ||= ""
|
74
|
+
tests ||= ""
|
75
|
+
if !tags.empty? && !tests.empty?
|
76
|
+
return "#{tags.count} tags + #{tests.count} tests"
|
77
|
+
elsif tags.empty?
|
78
|
+
return tests.count == 1 ? "Test: #{tests.first}" : "#{tests.count} tests"
|
79
|
+
elsif tests.empty?
|
80
|
+
return tags.count == 1 ? "Tag: #{tags.first}" : "#{tags.count} tags"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.generate_parse(argv)
|
85
|
+
options = {}
|
86
|
+
options[:dir]
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.show_help
|
90
|
+
puts """
|
91
|
+
Moto (#{Moto::VERSION}) CLI Help:
|
92
|
+
moto --version Display current version
|
93
|
+
moto run:
|
94
|
+
-t, --tests = Tests to be executed. For e.x Tests\Failure\Failure.rb should be passed as Tests::Failure
|
95
|
+
-r, --reporter = Reporters to be used. Defaults are Moto::Listeners::ConsoleDots, Moto::Listeners::JunitXml
|
96
|
+
-e, --environment etc etc
|
97
|
+
moto generate:
|
98
|
+
moto generate app_name -d, --dir = directory. Default is current dir.
|
99
|
+
"""
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
data/lib/result.rb
CHANGED
@@ -1,84 +1,84 @@
|
|
1
|
-
module Moto
|
2
|
-
class Result
|
3
|
-
|
4
|
-
PENDING = :pending # -2
|
5
|
-
RUNNING = :running # -1
|
6
|
-
PASSED = :passed # 0
|
7
|
-
FAILURE = :failure # 1
|
8
|
-
ERROR = :error # 2
|
9
|
-
SKIPPED = :skipped # 3
|
10
|
-
|
11
|
-
attr_reader :summary
|
12
|
-
|
13
|
-
def [](key)
|
14
|
-
@results[key]
|
15
|
-
end
|
16
|
-
|
17
|
-
def all
|
18
|
-
@results
|
19
|
-
end
|
20
|
-
|
21
|
-
def initialize(runner)
|
22
|
-
@runner = runner
|
23
|
-
@results = {}
|
24
|
-
@summary = {}
|
25
|
-
end
|
26
|
-
|
27
|
-
def start_run
|
28
|
-
# start timer
|
29
|
-
@summary[:started_at] = Time.now.to_f
|
30
|
-
end
|
31
|
-
|
32
|
-
def end_run
|
33
|
-
# info about duration and overall execution result
|
34
|
-
@summary[:finished_at] = Time.now.to_f
|
35
|
-
@summary[:duration] = @summary[:finished_at] - @summary[:started_at]
|
36
|
-
@summary[:result] = PASSED
|
37
|
-
@summary[:result] = FAILURE unless @results.values.select{ |v| v[:failures].count > 0 }.empty?
|
38
|
-
@summary[:result] = ERROR unless @results.values.select{ |v| v[:result] == ERROR }.empty?
|
39
|
-
@summary[:cnt_all] = @results.count
|
40
|
-
@summary[:tests_passed] = @results.select{ |k,v| v[:result] == PASSED }
|
41
|
-
@summary[:tests_failure] = @results.select{ |k,v| v[:result] == FAILURE }
|
42
|
-
@summary[:tests_error] = @results.select{ |k,v| v[:result] == ERROR }
|
43
|
-
@summary[:tests_skipped] = @results.select{ |k,v| v[:result] == SKIPPED }
|
44
|
-
@summary[:cnt_passed] = @summary[:tests_passed].count
|
45
|
-
@summary[:cnt_failure] = @summary[:tests_failure].count
|
46
|
-
@summary[:cnt_error] = @summary[:tests_error].count
|
47
|
-
@summary[:cnt_skipped] = @summary[:tests_skipped].count
|
48
|
-
end
|
49
|
-
|
50
|
-
def start_test(test)
|
51
|
-
@results[test.name] = { class: test.class, result: RUNNING, env: test.env, params: test.params, name: test.name, error: nil, failures: [], started_at: Time.now.to_f }
|
52
|
-
end
|
53
|
-
|
54
|
-
def end_test(test)
|
55
|
-
# calculate result basing on errors/failures
|
56
|
-
@results[test.name][:finished_at] = Time.now.to_f
|
57
|
-
test.result = PASSED
|
58
|
-
test.result = FAILURE unless @results[test.name][:failures].empty?
|
59
|
-
unless @results[test.name][:error].nil?
|
60
|
-
if @results[test.name][:error].is_a? Moto::Exceptions::TestSkipped
|
61
|
-
test.result = SKIPPED
|
62
|
-
elsif @results[test.name][:error].is_a? Moto::Exceptions::TestForcedPassed
|
63
|
-
test.result = PASSED
|
64
|
-
elsif @results[test.name][:error].is_a? Moto::Exceptions::TestForcedFailure
|
65
|
-
add_failure(test, @results[test.name][:error].message)
|
66
|
-
test.result = FAILURE
|
67
|
-
else
|
68
|
-
test.result = ERROR
|
69
|
-
end
|
70
|
-
end
|
71
|
-
@results[test.name][:duration] = @results[test.name][:finished_at] - @results[test.name][:started_at]
|
72
|
-
@results[test.name][:result] = test.result
|
73
|
-
end
|
74
|
-
|
75
|
-
def add_failure(test, msg)
|
76
|
-
@results[test.name][:failures] << msg
|
77
|
-
end
|
78
|
-
|
79
|
-
def add_error(test, e)
|
80
|
-
@results[test.name][:error] = e
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
1
|
+
module Moto
|
2
|
+
class Result
|
3
|
+
|
4
|
+
PENDING = :pending # -2
|
5
|
+
RUNNING = :running # -1
|
6
|
+
PASSED = :passed # 0
|
7
|
+
FAILURE = :failure # 1
|
8
|
+
ERROR = :error # 2
|
9
|
+
SKIPPED = :skipped # 3
|
10
|
+
|
11
|
+
attr_reader :summary
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
@results[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def all
|
18
|
+
@results
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(runner)
|
22
|
+
@runner = runner
|
23
|
+
@results = {}
|
24
|
+
@summary = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_run
|
28
|
+
# start timer
|
29
|
+
@summary[:started_at] = Time.now.to_f
|
30
|
+
end
|
31
|
+
|
32
|
+
def end_run
|
33
|
+
# info about duration and overall execution result
|
34
|
+
@summary[:finished_at] = Time.now.to_f
|
35
|
+
@summary[:duration] = @summary[:finished_at] - @summary[:started_at]
|
36
|
+
@summary[:result] = PASSED
|
37
|
+
@summary[:result] = FAILURE unless @results.values.select{ |v| v[:failures].count > 0 }.empty?
|
38
|
+
@summary[:result] = ERROR unless @results.values.select{ |v| v[:result] == ERROR }.empty?
|
39
|
+
@summary[:cnt_all] = @results.count
|
40
|
+
@summary[:tests_passed] = @results.select{ |k,v| v[:result] == PASSED }
|
41
|
+
@summary[:tests_failure] = @results.select{ |k,v| v[:result] == FAILURE }
|
42
|
+
@summary[:tests_error] = @results.select{ |k,v| v[:result] == ERROR }
|
43
|
+
@summary[:tests_skipped] = @results.select{ |k,v| v[:result] == SKIPPED }
|
44
|
+
@summary[:cnt_passed] = @summary[:tests_passed].count
|
45
|
+
@summary[:cnt_failure] = @summary[:tests_failure].count
|
46
|
+
@summary[:cnt_error] = @summary[:tests_error].count
|
47
|
+
@summary[:cnt_skipped] = @summary[:tests_skipped].count
|
48
|
+
end
|
49
|
+
|
50
|
+
def start_test(test)
|
51
|
+
@results[test.name] = { class: test.class, result: RUNNING, env: test.env, params: test.params, name: test.name, error: nil, failures: [], started_at: Time.now.to_f }
|
52
|
+
end
|
53
|
+
|
54
|
+
def end_test(test)
|
55
|
+
# calculate result basing on errors/failures
|
56
|
+
@results[test.name][:finished_at] = Time.now.to_f
|
57
|
+
test.result = PASSED
|
58
|
+
test.result = FAILURE unless @results[test.name][:failures].empty?
|
59
|
+
unless @results[test.name][:error].nil?
|
60
|
+
if @results[test.name][:error].is_a? Moto::Exceptions::TestSkipped
|
61
|
+
test.result = SKIPPED
|
62
|
+
elsif @results[test.name][:error].is_a? Moto::Exceptions::TestForcedPassed
|
63
|
+
test.result = PASSED
|
64
|
+
elsif @results[test.name][:error].is_a? Moto::Exceptions::TestForcedFailure
|
65
|
+
add_failure(test, @results[test.name][:error].message)
|
66
|
+
test.result = FAILURE
|
67
|
+
else
|
68
|
+
test.result = ERROR
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@results[test.name][:duration] = @results[test.name][:finished_at] - @results[test.name][:started_at]
|
72
|
+
@results[test.name][:result] = test.result
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_failure(test, msg)
|
76
|
+
@results[test.name][:failures] << msg
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_error(test, e)
|
80
|
+
@results[test.name][:error] = e
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
84
|
end
|