assert 2.15.2 → 2.16.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|