assert 2.15.2 → 2.16.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.
- checksums.yaml +5 -5
- data/lib/assert/assertions.rb +6 -0
- data/lib/assert/config_helpers.rb +35 -14
- data/lib/assert/context.rb +36 -43
- data/lib/assert/context/test_dsl.rb +4 -4
- data/lib/assert/default_suite.rb +35 -40
- data/lib/assert/default_view.rb +109 -37
- data/lib/assert/file_line.rb +1 -1
- data/lib/assert/result.rb +67 -27
- data/lib/assert/runner.rb +14 -10
- data/lib/assert/suite.rb +41 -50
- data/lib/assert/test.rb +39 -81
- data/lib/assert/version.rb +1 -1
- data/lib/assert/view_helpers.rb +11 -21
- data/test/helper.rb +40 -0
- data/test/system/test_tests.rb +90 -88
- data/test/unit/assertions/assert_block_tests.rb +14 -10
- data/test/unit/assertions/assert_empty_tests.rb +14 -10
- data/test/unit/assertions/assert_equal_tests.rb +22 -14
- data/test/unit/assertions/assert_file_exists_tests.rb +14 -10
- data/test/unit/assertions/assert_includes_tests.rb +14 -10
- data/test/unit/assertions/assert_instance_of_tests.rb +14 -10
- data/test/unit/assertions/assert_kind_of_tests.rb +14 -10
- data/test/unit/assertions/assert_match_tests.rb +14 -10
- data/test/unit/assertions/assert_nil_tests.rb +14 -10
- data/test/unit/assertions/assert_raises_tests.rb +14 -10
- data/test/unit/assertions/assert_respond_to_tests.rb +14 -10
- data/test/unit/assertions/assert_same_tests.rb +20 -14
- data/test/unit/assertions/assert_true_false_tests.rb +28 -20
- data/test/unit/assertions_tests.rb +12 -9
- data/test/unit/config_helpers_tests.rb +72 -13
- data/test/unit/context/test_dsl_tests.rb +38 -45
- data/test/unit/context_tests.rb +12 -8
- data/test/unit/default_suite_tests.rb +66 -43
- data/test/unit/file_line_tests.rb +4 -1
- data/test/unit/result_tests.rb +71 -47
- data/test/unit/runner_tests.rb +34 -16
- data/test/unit/suite_tests.rb +61 -29
- data/test/unit/test_tests.rb +97 -134
- data/test/unit/view_helpers_tests.rb +17 -31
- metadata +2 -2
data/lib/assert/file_line.rb
CHANGED
data/lib/assert/result.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'assert/file_line'
|
2
|
+
|
1
3
|
module Assert; end
|
2
4
|
module Assert::Result
|
3
5
|
|
@@ -30,11 +32,11 @@ module Assert::Result
|
|
30
32
|
|
31
33
|
def self.for_test(test, message, bt)
|
32
34
|
self.new({
|
33
|
-
:test_name
|
34
|
-
:
|
35
|
-
:message
|
36
|
-
:output
|
37
|
-
:backtrace
|
35
|
+
:test_name => test.name,
|
36
|
+
:test_file_line => test.file_line,
|
37
|
+
:message => message,
|
38
|
+
:output => test.output,
|
39
|
+
:backtrace => Backtrace.new(bt)
|
38
40
|
})
|
39
41
|
end
|
40
42
|
|
@@ -42,17 +44,43 @@ module Assert::Result
|
|
42
44
|
@build_data = build_data
|
43
45
|
end
|
44
46
|
|
45
|
-
def type
|
46
|
-
|
47
|
-
|
48
|
-
def test_id; @test_id ||= (@build_data[:test_id] || ''); end
|
49
|
-
def message; @message ||= (@build_data[:message] || ''); end
|
50
|
-
def output; @output ||= (@build_data[:output] || ''); end
|
51
|
-
def backtrace; @backtrace ||= (@build_data[:backtrace] || Backtrace.new([])); end
|
52
|
-
def trace; @trace ||= (@build_data[:trace] || build_trace(self.backtrace)); end
|
47
|
+
def type
|
48
|
+
@type ||= (@build_data[:type] || self.class.type).to_sym
|
49
|
+
end
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
def name
|
52
|
+
@name ||= (@build_data[:name] || self.class.name.to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_name
|
56
|
+
@test_name ||= (@build_data[:test_name] || '')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_file_line
|
60
|
+
@test_file_line ||= (@build_data[:test_file_line] || Assert::FileLine.parse(''))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_file_name; self.test_file_line.file; end
|
64
|
+
def test_line_num; self.test_file_line.line.to_i; end
|
65
|
+
|
66
|
+
def test_id
|
67
|
+
self.test_file_line.to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
def message
|
71
|
+
@message ||= (@build_data[:message] || '')
|
72
|
+
end
|
73
|
+
|
74
|
+
def output
|
75
|
+
@output ||= (@build_data[:output] || '')
|
76
|
+
end
|
77
|
+
|
78
|
+
def backtrace
|
79
|
+
@backtrace ||= (@build_data[:backtrace] || Backtrace.new([]))
|
80
|
+
end
|
81
|
+
|
82
|
+
def trace
|
83
|
+
@trace ||= (@build_data[:trace] || build_trace(self.backtrace))
|
56
84
|
end
|
57
85
|
|
58
86
|
# we choose to implement this way instead of using an `attr_writer` to be
|
@@ -60,18 +88,18 @@ module Assert::Result
|
|
60
88
|
def set_backtrace(bt)
|
61
89
|
@backtrace = Backtrace.new(bt)
|
62
90
|
@trace = build_trace(@backtrace)
|
91
|
+
@file_line = Assert::FileLine.parse(first_filtered_bt_line(@backtrace))
|
63
92
|
end
|
64
93
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
}
|
94
|
+
def file_line
|
95
|
+
@file_line ||= Assert::FileLine.parse(first_filtered_bt_line(self.backtrace))
|
96
|
+
end
|
97
|
+
|
98
|
+
def file_name; self.file_line.file; end
|
99
|
+
def line_num; self.file_line.line.to_i; end
|
100
|
+
|
101
|
+
Assert::Result.types.keys.each do |type|
|
102
|
+
define_method("#{type}?"){ self.type == type }
|
75
103
|
end
|
76
104
|
|
77
105
|
def to_sym; self.type; end
|
@@ -88,14 +116,26 @@ module Assert::Result
|
|
88
116
|
end
|
89
117
|
|
90
118
|
def inspect
|
91
|
-
"#<#{self.class}:#{'0x0%x' % (object_id << 1)}
|
119
|
+
"#<#{self.class}:#{'0x0%x' % (object_id << 1)} "\
|
120
|
+
"@message=#{self.message.inspect} "\
|
121
|
+
"@file_line=#{self.file_line.to_s.inspect} "\
|
122
|
+
"@test_file_line=#{self.test_file_line.to_s.inspect}>"
|
92
123
|
end
|
93
124
|
|
94
125
|
private
|
95
126
|
|
96
127
|
# by default, a result's trace is the first line of its filtered backtrace
|
97
|
-
|
128
|
+
# if the filtered backtrace is empty, just use the backtrace itself (this
|
129
|
+
# should only occur if the result is an error from a line in assert's
|
130
|
+
# non-test code). This is overridden for error results as they always show
|
131
|
+
# the entire backtrace
|
132
|
+
def build_trace(backtrace)
|
133
|
+
first_filtered_bt_line(backtrace)
|
134
|
+
end
|
98
135
|
|
136
|
+
def first_filtered_bt_line(backtrace)
|
137
|
+
((fbt = backtrace.filtered).empty? ? backtrace : fbt).first.to_s
|
138
|
+
end
|
99
139
|
end
|
100
140
|
|
101
141
|
class Pass < Base
|
data/lib/assert/runner.rb
CHANGED
@@ -21,16 +21,18 @@ module Assert
|
|
21
21
|
self.view.on_start
|
22
22
|
|
23
23
|
if self.single_test?
|
24
|
-
self.view.
|
25
|
-
elsif self.
|
26
|
-
self.view.
|
27
|
-
|
24
|
+
self.view.print "Running test: #{self.single_test_file_line}"
|
25
|
+
elsif self.tests_to_run?
|
26
|
+
self.view.print "Running tests in random order"
|
27
|
+
end
|
28
|
+
if self.tests_to_run?
|
29
|
+
self.view.puts ", seeded with \"#{self.runner_seed}\""
|
28
30
|
end
|
29
31
|
|
30
32
|
begin
|
31
33
|
self.suite.start_time = Time.now
|
32
34
|
self.suite.setups.each(&:call)
|
33
|
-
tests_to_run.
|
35
|
+
tests_to_run.tap{ self.suite.clear_tests_to_run }.delete_if do |test|
|
34
36
|
self.before_test(test)
|
35
37
|
self.suite.before_test(test)
|
36
38
|
self.view.before_test(test)
|
@@ -42,6 +44,9 @@ module Assert
|
|
42
44
|
self.after_test(test)
|
43
45
|
self.suite.after_test(test)
|
44
46
|
self.view.after_test(test)
|
47
|
+
|
48
|
+
# always delete `test` from `tests_to_run` since it has been run
|
49
|
+
true
|
45
50
|
end
|
46
51
|
self.suite.teardowns.each(&:call)
|
47
52
|
self.suite.end_time = Time.now
|
@@ -52,7 +57,7 @@ module Assert
|
|
52
57
|
raise(err)
|
53
58
|
end
|
54
59
|
|
55
|
-
(self.
|
60
|
+
(self.fail_result_count + self.error_result_count).tap do
|
56
61
|
self.view.on_finish
|
57
62
|
self.suite.on_finish
|
58
63
|
self.on_finish
|
@@ -76,12 +81,11 @@ module Assert
|
|
76
81
|
private
|
77
82
|
|
78
83
|
def tests_to_run
|
84
|
+
srand self.runner_seed
|
79
85
|
if self.single_test?
|
80
|
-
[
|
81
|
-
].compact
|
86
|
+
[self.suite.find_test_to_run(self.single_test_file_line)].compact
|
82
87
|
else
|
83
|
-
|
84
|
-
self.suite.tests.sort.sort_by{ rand self.suite.tests.size }
|
88
|
+
self.suite.sorted_tests_to_run{ rand self.tests_to_run_count }
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
data/lib/assert/suite.rb
CHANGED
@@ -3,6 +3,12 @@ require 'assert/test'
|
|
3
3
|
|
4
4
|
module Assert
|
5
5
|
|
6
|
+
# This is the base suite. It loads the tests to run in memory and provides
|
7
|
+
# methods for these tests that the runner/view uses for handling and
|
8
|
+
# presentation purposes. It also stores suite-level setups and teardowns.
|
9
|
+
# Override the test/result count methods and the callbacks as needed. See
|
10
|
+
# the default suite for example usage.
|
11
|
+
|
6
12
|
class Suite
|
7
13
|
include Assert::ConfigHelpers
|
8
14
|
|
@@ -11,7 +17,7 @@ module Assert
|
|
11
17
|
# A suite is a set of tests to run. When a test class subclasses
|
12
18
|
# the Context class, that test class is pushed to the suite.
|
13
19
|
|
14
|
-
attr_reader :config, :
|
20
|
+
attr_reader :config, :test_methods, :setups, :teardowns
|
15
21
|
attr_accessor :start_time, :end_time
|
16
22
|
|
17
23
|
def initialize(config)
|
@@ -36,6 +42,26 @@ module Assert
|
|
36
42
|
end
|
37
43
|
alias_method :shutdown, :teardown
|
38
44
|
|
45
|
+
def tests_to_run?; @tests.size > 0; end
|
46
|
+
def tests_to_run_count; @tests.size; end
|
47
|
+
def clear_tests_to_run; @tests.clear; end
|
48
|
+
|
49
|
+
def find_test_to_run(file_line)
|
50
|
+
@tests.find{ |t| t.file_line == file_line }
|
51
|
+
end
|
52
|
+
|
53
|
+
def sorted_tests_to_run(&sort_by_proc)
|
54
|
+
@tests.sort.sort_by(&sort_by_proc)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_count; end
|
58
|
+
def result_count; end
|
59
|
+
def pass_result_count; end
|
60
|
+
def fail_result_count; end
|
61
|
+
def error_result_count; end
|
62
|
+
def skip_result_count; end
|
63
|
+
def ignore_result_count; end
|
64
|
+
|
39
65
|
def run_time
|
40
66
|
@end_time - @start_time
|
41
67
|
end
|
@@ -48,55 +74,26 @@ module Assert
|
|
48
74
|
get_rate(self.result_count, self.run_time)
|
49
75
|
end
|
50
76
|
|
51
|
-
def count(thing)
|
52
|
-
if thing == :tests
|
53
|
-
test_count
|
54
|
-
elsif thing == :results
|
55
|
-
result_count
|
56
|
-
elsif thing == :pass || thing == :passed
|
57
|
-
result_count(:pass)
|
58
|
-
elsif thing == :fail || thing == :failed
|
59
|
-
result_count(:fail)
|
60
|
-
elsif thing == :error || thing == :errored
|
61
|
-
result_count(:error)
|
62
|
-
elsif thing == :skip || thing == :skipped
|
63
|
-
result_count(:skip)
|
64
|
-
elsif thing == :ignore || thing == :ignored
|
65
|
-
result_count(:ignore)
|
66
|
-
else
|
67
|
-
0
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Test data
|
72
|
-
|
73
|
-
def ordered_tests; end
|
74
|
-
def reversed_tests; end
|
75
|
-
def ordered_tests_by_run_time; end
|
76
|
-
def reversed_tests_by_run_time; end
|
77
|
-
def test_count; end
|
78
|
-
|
79
|
-
# Result data
|
80
|
-
|
81
|
-
def ordered_results; end
|
82
|
-
def reversed_results; end
|
83
|
-
def ordered_results_for_dump; end
|
84
|
-
def reversed_results_for_dump; end
|
85
|
-
def result_count(type = nil); end
|
86
|
-
|
87
77
|
# Callbacks
|
88
78
|
|
89
79
|
# define callback handlers to do special behavior during the test run. These
|
90
80
|
# will be called by the test runner
|
91
81
|
|
92
82
|
def before_load(test_files); end
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
83
|
+
|
84
|
+
# this is required to load tests into the suite, be sure to `super` if you
|
85
|
+
# override this method
|
86
|
+
def on_test(test)
|
87
|
+
@tests << test
|
88
|
+
end
|
89
|
+
|
90
|
+
def after_load; end
|
91
|
+
def on_start; end
|
92
|
+
def before_test(test); end
|
93
|
+
def on_result(result); end
|
94
|
+
def after_test(test); end
|
95
|
+
def on_finish; end
|
96
|
+
def on_interrupt(err); end
|
100
97
|
|
101
98
|
def inspect
|
102
99
|
"#<#{self.class}:#{'0x0%x' % (object_id << 1)}"\
|
@@ -104,12 +101,6 @@ module Assert
|
|
104
101
|
" result_count=#{self.result_count.inspect}>"
|
105
102
|
end
|
106
103
|
|
107
|
-
private
|
108
|
-
|
109
|
-
def get_rate(count, time)
|
110
|
-
time == 0 ? 0.0 : (count.to_f / time.to_f)
|
111
|
-
end
|
112
|
-
|
113
104
|
end
|
114
105
|
|
115
106
|
end
|
data/lib/assert/test.rb
CHANGED
@@ -9,10 +9,6 @@ module Assert
|
|
9
9
|
# a Test is some code/method to run in the scope of a Context that may
|
10
10
|
# produce results
|
11
11
|
|
12
|
-
def self.result_count_meth(type)
|
13
|
-
"#{type}_result_count".to_sym
|
14
|
-
end
|
15
|
-
|
16
12
|
def self.name_file_line_context_data(ci, name)
|
17
13
|
{ :name => ci.test_name(name),
|
18
14
|
:file_line => ci.called_from
|
@@ -35,82 +31,55 @@ module Assert
|
|
35
31
|
}))
|
36
32
|
end
|
37
33
|
|
38
|
-
attr_reader :results
|
39
|
-
attr_writer :total_result_count
|
40
|
-
|
41
34
|
def initialize(build_data = nil)
|
42
|
-
@build_data
|
35
|
+
@build_data = build_data || {}
|
36
|
+
@result_callback = nil
|
43
37
|
end
|
44
38
|
|
45
|
-
def file_line
|
46
|
-
|
47
|
-
def output; @output ||= (@build_data[:output] || ''); end
|
48
|
-
def run_time; @run_time ||= (@build_data[:run_time] || 0); end
|
49
|
-
|
50
|
-
def total_result_count
|
51
|
-
@total_result_count ||= (@build_data[:total_result_count] || 0)
|
39
|
+
def file_line
|
40
|
+
@file_line ||= FileLine.parse((@build_data[:file_line] || '').to_s)
|
52
41
|
end
|
53
42
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
43
|
+
def file_name; self.file_line.file; end
|
44
|
+
def line_num; self.file_line.line.to_i; end
|
45
|
+
|
46
|
+
def name
|
47
|
+
@name ||= (@build_data[:name] || '')
|
59
48
|
end
|
60
49
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
50
|
+
def output
|
51
|
+
@output ||= (@build_data[:output] || '')
|
52
|
+
end
|
64
53
|
|
65
|
-
def
|
66
|
-
|
67
|
-
:name => self.name.to_s,
|
68
|
-
:output => self.output.to_s,
|
69
|
-
:run_time => self.run_time
|
70
|
-
}.merge(result_count_data(:total_result_count => self.total_result_count))
|
54
|
+
def run_time
|
55
|
+
@run_time ||= (@build_data[:run_time] || 0)
|
71
56
|
end
|
72
57
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
58
|
+
def context_info
|
59
|
+
@context_info ||= @build_data[:context_info]
|
60
|
+
end
|
76
61
|
|
77
|
-
def
|
78
|
-
|
62
|
+
def context_class
|
63
|
+
self.context_info.klass
|
79
64
|
end
|
80
65
|
|
81
|
-
def
|
82
|
-
|
83
|
-
self.send(result_count_meth(type))
|
84
|
-
else
|
85
|
-
self.total_result_count
|
86
|
-
end
|
66
|
+
def config
|
67
|
+
@config ||= @build_data[:config]
|
87
68
|
end
|
88
69
|
|
89
|
-
def
|
90
|
-
|
91
|
-
self.total_result_count += 1
|
92
|
-
n = result_count_meth(result.to_sym)
|
93
|
-
instance_variable_set("@#{n}", (instance_variable_get("@#{n}") || 0) + 1)
|
94
|
-
callback.call(result)
|
70
|
+
def code
|
71
|
+
@code ||= @build_data[:code]
|
95
72
|
end
|
96
73
|
|
97
74
|
def run(&result_callback)
|
98
|
-
result_callback
|
99
|
-
scope = self.context_class.new(self, self.config, result_callback)
|
75
|
+
@result_callback = result_callback || proc{ |result| } # noop by default
|
76
|
+
scope = self.context_class.new(self, self.config, @result_callback)
|
100
77
|
start_time = Time.now
|
101
78
|
capture_output do
|
102
|
-
self.context_class.run_arounds(scope)
|
103
|
-
run_test(scope, result_callback)
|
104
|
-
end
|
79
|
+
self.context_class.run_arounds(scope){ run_test(scope) }
|
105
80
|
end
|
81
|
+
@result_callback = nil
|
106
82
|
@run_time = Time.now - start_time
|
107
|
-
@results
|
108
|
-
end
|
109
|
-
|
110
|
-
Assert::Result.types.each do |name, klass|
|
111
|
-
define_method "#{name}_results" do
|
112
|
-
self.results.select{|r| r.kind_of?(klass) }
|
113
|
-
end
|
114
83
|
end
|
115
84
|
|
116
85
|
def <=>(other_test)
|
@@ -118,7 +87,7 @@ module Assert
|
|
118
87
|
end
|
119
88
|
|
120
89
|
def inspect
|
121
|
-
attributes_string = ([
|
90
|
+
attributes_string = ([:name, :context_info].collect do |attr|
|
122
91
|
"@#{attr}=#{self.send(attr).inspect}"
|
123
92
|
end).join(" ")
|
124
93
|
"#<#{self.class}:#{'0x0%x' % (object_id << 1)} #{attributes_string}>"
|
@@ -126,7 +95,7 @@ module Assert
|
|
126
95
|
|
127
96
|
private
|
128
97
|
|
129
|
-
def run_test(scope
|
98
|
+
def run_test(scope)
|
130
99
|
begin
|
131
100
|
# run any assert style 'setup do' setups
|
132
101
|
self.context_class.run_setups(scope)
|
@@ -135,13 +104,13 @@ module Assert
|
|
135
104
|
# run the code block
|
136
105
|
scope.instance_eval(&(self.code || proc{}))
|
137
106
|
rescue Result::TestFailure => err
|
138
|
-
capture_result(Result::Fail
|
107
|
+
capture_result(Result::Fail, err)
|
139
108
|
rescue Result::TestSkipped => err
|
140
|
-
capture_result(Result::Skip
|
109
|
+
capture_result(Result::Skip, err)
|
141
110
|
rescue SignalException => err
|
142
111
|
raise(err)
|
143
112
|
rescue Exception => err
|
144
|
-
capture_result(Result::Error
|
113
|
+
capture_result(Result::Error, err)
|
145
114
|
ensure
|
146
115
|
begin
|
147
116
|
# run any assert style 'teardown do' teardowns
|
@@ -149,17 +118,21 @@ module Assert
|
|
149
118
|
# run any test/unit style 'def teardown' teardowns
|
150
119
|
scope.teardown if scope.respond_to?(:teardown)
|
151
120
|
rescue Result::TestFailure => err
|
152
|
-
capture_result(Result::Fail
|
121
|
+
capture_result(Result::Fail, err)
|
153
122
|
rescue Result::TestSkipped => err
|
154
|
-
capture_result(Result::Skip
|
123
|
+
capture_result(Result::Skip, err)
|
155
124
|
rescue SignalException => err
|
156
125
|
raise(err)
|
157
126
|
rescue Exception => err
|
158
|
-
capture_result(Result::Error
|
127
|
+
capture_result(Result::Error, err)
|
159
128
|
end
|
160
129
|
end
|
161
130
|
end
|
162
131
|
|
132
|
+
def capture_result(result_klass, err)
|
133
|
+
@result_callback.call(result_klass.for_test(self, err))
|
134
|
+
end
|
135
|
+
|
163
136
|
def capture_output(&block)
|
164
137
|
if self.config.capture_output == true
|
165
138
|
orig_stdout = $stdout.clone
|
@@ -175,21 +148,6 @@ module Assert
|
|
175
148
|
StringIO.new(self.output, "a+")
|
176
149
|
end
|
177
150
|
|
178
|
-
def result_count_data(seed)
|
179
|
-
Assert::Result.types.keys.inject(seed) do |d, t|
|
180
|
-
d[result_count_meth(t)] = self.send(result_count_meth(t))
|
181
|
-
d
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def result_count_meth(type)
|
186
|
-
self.class.result_count_meth(type)
|
187
|
-
end
|
188
|
-
|
189
|
-
def get_rate(count, time)
|
190
|
-
time == 0 ? 0.0 : (count.to_f / time.to_f)
|
191
|
-
end
|
192
|
-
|
193
151
|
end
|
194
152
|
|
195
153
|
end
|