assert 0.6.0 → 0.7.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/CHANGELOG.rdoc +21 -0
- data/Gemfile.lock +4 -4
- data/README.rdoc +18 -1
- data/assert.gemspec +1 -1
- data/lib/assert/assertions.rb +4 -4
- data/lib/assert/autorun.rb +1 -1
- data/lib/assert/context.rb +50 -38
- data/lib/assert/macros/methods.rb +15 -4
- data/lib/assert/rake_tasks.rb +34 -78
- data/lib/assert/rake_tasks/irb.rb +33 -0
- data/lib/assert/rake_tasks/scope.rb +73 -0
- data/lib/assert/rake_tasks/test_task.rb +63 -0
- data/lib/assert/result.rb +84 -36
- data/lib/assert/setup/helpers.rb +7 -4
- data/lib/assert/suite.rb +45 -61
- data/lib/assert/test.rb +22 -11
- data/lib/assert/version.rb +1 -1
- data/test/assertions_test.rb +1 -1
- data/test/context/class_methods_test.rb +22 -17
- data/test/context_test.rb +64 -12
- data/test/fixtures/test_root/one_test.rb +0 -0
- data/test/fixtures/test_root/parent/area_one/area_test.rb +0 -0
- data/test/fixtures/test_root/shallow/deeply/nested_test.rb +0 -0
- data/test/fixtures/test_root/shallow/nested_test.rb +0 -0
- data/test/fixtures/test_root/shallow_test.rb +0 -0
- data/test/fixtures/test_root/two_test.rb +0 -0
- data/test/helper.rb +24 -5
- data/test/rake_tasks/irb_test.rb +45 -0
- data/test/rake_tasks/scope_test.rb +63 -0
- data/test/rake_tasks/test_task_test.rb +80 -0
- data/test/result_set_test.rb +4 -4
- data/test/result_test.rb +78 -45
- data/test/suite/context_info_test.rb +42 -0
- data/test/suite_test.rb +9 -46
- data/test/test/running_test.rb +2 -3
- data/test/test_test.rb +9 -8
- metadata +31 -7
@@ -0,0 +1,33 @@
|
|
1
|
+
module Assert::RakeTasks
|
2
|
+
class Irb
|
3
|
+
|
4
|
+
def self.file_name
|
5
|
+
"irb.rb"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.task_name
|
9
|
+
:irb
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(test_root)
|
13
|
+
@test_root = test_root
|
14
|
+
end
|
15
|
+
|
16
|
+
def file_path
|
17
|
+
File.join(@test_root.to_s, self.class.file_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def helper_exists?
|
21
|
+
File.exists?(self.file_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def description
|
25
|
+
"Open irb preloaded with #{self.file_path}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def cmd
|
29
|
+
"irb -rubygems -r ./#{self.file_path}"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
require 'assert/rake_tasks/test_task'
|
3
|
+
|
4
|
+
module Assert::RakeTasks
|
5
|
+
class Scope
|
6
|
+
|
7
|
+
def self.test_file_suffix
|
8
|
+
"_test.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@path = path
|
13
|
+
end
|
14
|
+
|
15
|
+
def namespace
|
16
|
+
File.basename(@path).to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
# nested test files under the path
|
20
|
+
def nested_files
|
21
|
+
nested_files = Rake::FileList["#{@path}/**/*#{self.class.test_file_suffix}"]
|
22
|
+
end
|
23
|
+
|
24
|
+
# a list with the path test file "#{path}_test.rb" (if it exists)
|
25
|
+
def path_file_list
|
26
|
+
path_file_name = @path+self.class.test_file_suffix
|
27
|
+
(File.exists?(path_file_name) ? Rake::FileList[path_file_name] : [])
|
28
|
+
end
|
29
|
+
|
30
|
+
# return a test task covering the scopes nested files plus path file
|
31
|
+
# but only if there are nested files
|
32
|
+
def to_test_task
|
33
|
+
if !self.nested_files.empty?
|
34
|
+
TestTask.new(@path) do |tt|
|
35
|
+
tt.files = self.path_file_list + self.nested_files
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# a collection of test tasks for every standalone child test file
|
41
|
+
def test_tasks
|
42
|
+
# get immediate child test files
|
43
|
+
Dir.glob("#{@path}/*#{self.class.test_file_suffix}").collect do |f|
|
44
|
+
# get just the path name for each file
|
45
|
+
File.join(File.dirname(f), File.basename(f, self.class.test_file_suffix))
|
46
|
+
end.reject do |p|
|
47
|
+
# reject any that have deeply nested test files
|
48
|
+
!Dir.glob("#{p}/**/*#{self.class.test_file_suffix}").empty?
|
49
|
+
end.collect do |p|
|
50
|
+
# build a test task for the standalone test file of the path
|
51
|
+
TestTask.new(p) do |tt|
|
52
|
+
tt.files = Rake::FileList[p+self.class.test_file_suffix]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# a collection of scopes for every child test dir or test dir/file combo
|
58
|
+
def scopes
|
59
|
+
# get immediate child paths
|
60
|
+
Dir.glob("#{@path}/*").collect do |p|
|
61
|
+
# get just the path name for each dir/file and uniq it
|
62
|
+
File.join(File.dirname(p), File.basename(p, self.class.test_file_suffix))
|
63
|
+
end.uniq.select do |p|
|
64
|
+
# select any that have deeply nested test files
|
65
|
+
!Dir.glob("#{p}/**/*#{self.class.test_file_suffix}").empty?
|
66
|
+
end.collect do |p|
|
67
|
+
# build a scope for each path
|
68
|
+
self.class.new(p)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'assert/rake_tasks/scope'
|
2
|
+
|
3
|
+
module Assert::RakeTasks
|
4
|
+
|
5
|
+
class TestTask
|
6
|
+
|
7
|
+
attr_accessor :name, :path, :files
|
8
|
+
|
9
|
+
# Create a testing task
|
10
|
+
def initialize(path)
|
11
|
+
@path = path
|
12
|
+
@files = []
|
13
|
+
yield self if block_given?
|
14
|
+
end
|
15
|
+
|
16
|
+
def relative_path
|
17
|
+
File.join(@path.to_s.split(File::SEPARATOR)[1..-1])
|
18
|
+
end
|
19
|
+
|
20
|
+
def scope_description
|
21
|
+
relative_path.empty? ? "" : " for #{relative_path}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def description
|
25
|
+
"Run all tests#{scope_description}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def name
|
29
|
+
File.basename(@path, Scope.test_file_suffix).to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
def file_list # :nodoc:
|
33
|
+
self.files.collect{|f| "\"#{f}\""}.join(' ')
|
34
|
+
end
|
35
|
+
|
36
|
+
def ruby_args
|
37
|
+
[ "-rrubygems",
|
38
|
+
"\"#{self.rake_loader}\"",
|
39
|
+
self.file_list
|
40
|
+
].compact.join(" ")
|
41
|
+
end
|
42
|
+
|
43
|
+
def show_loaded_files?
|
44
|
+
ENV["show_loaded_files"] == 'true'
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def rake_loader
|
50
|
+
find_file('rake/rake_test_loader')
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_file(fn) # :nodoc:
|
54
|
+
$LOAD_PATH.each do |path|
|
55
|
+
file_path = File.join(path, "#{fn}.rb")
|
56
|
+
return file_path if File.exist? file_path
|
57
|
+
end
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/lib/assert/result.rb
CHANGED
@@ -3,11 +3,10 @@ module Assert::Result
|
|
3
3
|
|
4
4
|
class Base; end
|
5
5
|
class Pass < Base; end
|
6
|
-
class Fail < Base; end
|
7
6
|
class Ignore < Base; end
|
8
|
-
class
|
9
|
-
class Error <
|
10
|
-
class Skip <
|
7
|
+
class Fail < Base; end
|
8
|
+
class Error < Base; end
|
9
|
+
class Skip < Base; end
|
11
10
|
|
12
11
|
class << self
|
13
12
|
def types
|
@@ -39,7 +38,6 @@ module Assert::Result
|
|
39
38
|
|
40
39
|
# './lib' in project dir, or '/usr/local/blahblah' if installed
|
41
40
|
ASSERT_DIR = File.dirname(File.dirname(file))
|
42
|
-
MACROS_DIR = File.join(File.dirname(file), 'macros')
|
43
41
|
|
44
42
|
def initialize(value=nil)
|
45
43
|
super(value || ["No backtrace"])
|
@@ -66,7 +64,7 @@ module Assert::Result
|
|
66
64
|
protected
|
67
65
|
|
68
66
|
def filter_out?(line)
|
69
|
-
line.rindex(ASSERT_DIR, 0)
|
67
|
+
line.rindex(ASSERT_DIR, 0)
|
70
68
|
end
|
71
69
|
|
72
70
|
end
|
@@ -76,11 +74,11 @@ module Assert::Result
|
|
76
74
|
|
77
75
|
class Base
|
78
76
|
|
79
|
-
attr_reader :
|
77
|
+
attr_reader :test, :message, :backtrace
|
80
78
|
|
81
|
-
def initialize(
|
79
|
+
def initialize(test, message, backtrace=nil)
|
80
|
+
@test = test
|
82
81
|
@backtrace = Backtrace.new(backtrace)
|
83
|
-
@test_name = test_name
|
84
82
|
@message = message && !message.empty? ? message : nil
|
85
83
|
end
|
86
84
|
|
@@ -88,10 +86,21 @@ module Assert::Result
|
|
88
86
|
define_method("#{meth}?") { false }
|
89
87
|
end
|
90
88
|
|
89
|
+
def test_name
|
90
|
+
@test.name
|
91
|
+
end
|
92
|
+
|
91
93
|
def to_sym; nil; end
|
92
94
|
|
93
95
|
def to_s
|
94
|
-
[
|
96
|
+
[ "#{self.name.upcase}: #{self.test_name}",
|
97
|
+
self.message,
|
98
|
+
self.trace
|
99
|
+
].compact.join("\n")
|
100
|
+
end
|
101
|
+
|
102
|
+
def name
|
103
|
+
""
|
95
104
|
end
|
96
105
|
|
97
106
|
def trace
|
@@ -109,58 +118,97 @@ module Assert::Result
|
|
109
118
|
end
|
110
119
|
|
111
120
|
class Pass < Base
|
121
|
+
|
112
122
|
def pass?; true; end
|
113
|
-
def to_sym; :
|
123
|
+
def to_sym; :pass; end
|
114
124
|
|
115
|
-
def
|
116
|
-
"
|
125
|
+
def name
|
126
|
+
"Pass"
|
117
127
|
end
|
118
|
-
end
|
119
|
-
|
120
|
-
class Fail < Base
|
121
|
-
def fail?; true; end
|
122
|
-
def to_sym; :failed; end
|
123
128
|
|
124
|
-
def to_s
|
125
|
-
"FAIL: #{super}"
|
126
|
-
end
|
127
129
|
end
|
128
130
|
|
129
131
|
class Ignore < Base
|
132
|
+
|
130
133
|
def ignore?; true; end
|
131
|
-
def to_sym; :
|
134
|
+
def to_sym; :ignore; end
|
132
135
|
|
133
|
-
def
|
134
|
-
"
|
136
|
+
def name
|
137
|
+
"Ignore"
|
135
138
|
end
|
139
|
+
|
136
140
|
end
|
137
141
|
|
138
|
-
#
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
+
# raised by the 'fail' context helper to break test execution
|
143
|
+
# (if Test.halt_on_fail?)
|
144
|
+
class TestFailure < RuntimeError; end
|
145
|
+
|
146
|
+
class Fail < Base
|
147
|
+
|
148
|
+
# fail results can be generated manually or by raising Assert::Result::TestFailure
|
149
|
+
def initialize(test, message_or_exception, backtrace=nil)
|
150
|
+
if message_or_exception.kind_of?(TestFailure)
|
151
|
+
super(test, message_or_exception.message, message_or_exception.backtrace || [])
|
152
|
+
elsif message_or_exception.kind_of?(Exception)
|
153
|
+
raise ArgumentError, "generate fail results by raising Assert::Result::TestFailure"
|
154
|
+
else
|
155
|
+
super(test, message_or_exception, backtrace)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def fail?; true; end
|
160
|
+
def to_sym; :fail; end
|
161
|
+
|
162
|
+
def name
|
163
|
+
"Fail"
|
142
164
|
end
|
165
|
+
|
166
|
+
# override of the base, show the test's context info called_from
|
167
|
+
def trace
|
168
|
+
self.test.context_info.called_from
|
169
|
+
end
|
170
|
+
|
143
171
|
end
|
144
172
|
|
145
173
|
# raised by the 'skip' context helper to break test execution
|
146
174
|
class TestSkipped < RuntimeError; end
|
147
175
|
|
148
|
-
class Skip <
|
176
|
+
class Skip < Base
|
177
|
+
|
178
|
+
# skip results are generated by raising Assert::Result::TestSkipped
|
179
|
+
def initialize(test, exception)
|
180
|
+
if exception.kind_of?(TestSkipped)
|
181
|
+
super(test, exception.message, exception.backtrace || [])
|
182
|
+
else
|
183
|
+
raise ArgumentError, "generate skip results by raising Assert::Result::TestSkipped"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
149
187
|
def skip?; true; end
|
150
|
-
def to_sym; :
|
188
|
+
def to_sym; :skip; end
|
151
189
|
|
152
|
-
def
|
153
|
-
"
|
190
|
+
def name
|
191
|
+
"Skip"
|
154
192
|
end
|
193
|
+
|
155
194
|
end
|
156
195
|
|
157
|
-
class Error <
|
196
|
+
class Error < Base
|
197
|
+
|
198
|
+
# error results are generated by raising exceptions in tests
|
199
|
+
def initialize(test, exception)
|
200
|
+
if exception.kind_of?(Exception)
|
201
|
+
super(test, "#{exception.message} (#{exception.class.name})", exception.backtrace || [])
|
202
|
+
else
|
203
|
+
raise ArgumentError, "generate error results by raising an exception"
|
204
|
+
end
|
205
|
+
end
|
158
206
|
|
159
207
|
def error?; true; end
|
160
|
-
def to_sym; :
|
208
|
+
def to_sym; :error; end
|
161
209
|
|
162
|
-
def
|
163
|
-
"
|
210
|
+
def name
|
211
|
+
"Error"
|
164
212
|
end
|
165
213
|
|
166
214
|
# override of the base, always show the full unfiltered backtrace for errors
|
data/lib/assert/setup/helpers.rb
CHANGED
@@ -11,7 +11,7 @@ module Assert
|
|
11
11
|
class << self
|
12
12
|
|
13
13
|
USER_TEST_HELPER = "~/.assert/options"
|
14
|
-
|
14
|
+
|
15
15
|
# assume the test dir path is ./test and look for helpers in ./test/helper.rb
|
16
16
|
def package_test_dir
|
17
17
|
"test"
|
@@ -34,7 +34,9 @@ module Assert
|
|
34
34
|
|
35
35
|
def require_user_test_helper
|
36
36
|
begin
|
37
|
-
|
37
|
+
if ENV['HOME']
|
38
|
+
require File.expand_path(USER_TEST_HELPER)
|
39
|
+
end
|
38
40
|
rescue LoadError => err
|
39
41
|
# do nothing
|
40
42
|
end
|
@@ -45,7 +47,7 @@ module Assert
|
|
45
47
|
begin
|
46
48
|
require package_helper_file(root_path)
|
47
49
|
rescue LoadError => err
|
48
|
-
|
50
|
+
# do nothing
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -57,7 +59,8 @@ module Assert
|
|
57
59
|
# this expects the caller's root path to be the parent dir of the first
|
58
60
|
# parent dir of caller named TEST_DIR
|
59
61
|
def caller_root_path(caller_info)
|
60
|
-
|
62
|
+
non_custom_require_caller_info = caller_info.reject{|i| i =~ /rubygems\/custom_require.rb/}
|
63
|
+
caller_dirname = File.expand_path(File.dirname(non_custom_require_caller_info[0]))
|
61
64
|
test_dir_pos = caller_dirname.index(package_test_helper_regex)
|
62
65
|
if test_dir_pos && (test_dir_pos > 0)
|
63
66
|
caller_dirname[0..(test_dir_pos-1)]
|
data/lib/assert/suite.rb
CHANGED
@@ -1,15 +1,38 @@
|
|
1
1
|
require 'assert/test'
|
2
2
|
|
3
3
|
module Assert
|
4
|
-
class Suite
|
4
|
+
class Suite
|
5
|
+
|
6
|
+
class ContextInfo
|
7
|
+
|
8
|
+
attr_reader :klass, :called_from, :file
|
9
|
+
|
10
|
+
def initialize(klass, called_from=nil)
|
11
|
+
@klass = klass
|
12
|
+
@called_from = called_from
|
13
|
+
@file = if called_from
|
14
|
+
called_from.gsub(/\:[0-9]+.*$/, '')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
TEST_METHOD_REGEX = /^test./
|
5
21
|
|
6
22
|
# A suite is a set of tests to run. When a test class subclasses
|
7
23
|
# the Context class, that test class is pushed to the suite.
|
8
24
|
|
9
|
-
attr_accessor :start_time, :end_time
|
25
|
+
attr_accessor :tests, :test_methods, :start_time, :end_time
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@tests = []
|
29
|
+
@test_methods = []
|
30
|
+
@start_time = 0
|
31
|
+
@end_time = 0
|
32
|
+
end
|
10
33
|
|
11
34
|
def run_time
|
12
|
-
|
35
|
+
@end_time - @start_time
|
13
36
|
end
|
14
37
|
|
15
38
|
def runner_seed
|
@@ -19,42 +42,12 @@ module Assert
|
|
19
42
|
end).to_i
|
20
43
|
end
|
21
44
|
|
22
|
-
|
23
|
-
# gsub off any trailing 'Test'
|
24
|
-
self[context_klass] ||= []
|
25
|
-
end
|
26
|
-
|
27
|
-
def contexts
|
28
|
-
self.keys.sort{|a,b| a.to_s <=> b.to_s}
|
29
|
-
end
|
30
|
-
|
31
|
-
def tests
|
32
|
-
prep
|
33
|
-
self.values.flatten
|
34
|
-
end
|
35
|
-
|
36
|
-
def ordered_tests(klass=nil)
|
37
|
-
prep
|
38
|
-
(klass.nil? ? self.contexts : [klass]).inject([]) do |tests, klass|
|
39
|
-
tests += (self[klass] || [])
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def ordered_results(klass=nil)
|
44
|
-
ordered_tests(klass).inject([]) do |results, test|
|
45
|
-
results += test.results
|
46
|
-
end
|
47
|
-
end
|
45
|
+
alias_method :ordered_tests, :tests
|
48
46
|
|
49
|
-
def
|
50
|
-
|
51
|
-
count_tests(klass.nil? ? self.values : [self[klass]])
|
52
|
-
end
|
53
|
-
|
54
|
-
def result_count(type=nil)
|
55
|
-
prep
|
56
|
-
count_results(self.values, type)
|
47
|
+
def results
|
48
|
+
tests.inject([]) {|results, test| results += test.results}
|
57
49
|
end
|
50
|
+
alias_method :ordered_results, :results
|
58
51
|
|
59
52
|
def count(thing)
|
60
53
|
case thing
|
@@ -77,6 +70,20 @@ module Assert
|
|
77
70
|
end
|
78
71
|
end
|
79
72
|
|
73
|
+
def test_count
|
74
|
+
self.tests.size
|
75
|
+
end
|
76
|
+
|
77
|
+
def result_count(type=nil)
|
78
|
+
if type
|
79
|
+
self.tests.inject(0) do |count, test|
|
80
|
+
count += test.result_count(type)
|
81
|
+
end
|
82
|
+
else
|
83
|
+
self.results.size
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
80
87
|
def setup(&block)
|
81
88
|
if block_given?
|
82
89
|
self.setups << block
|
@@ -119,30 +126,7 @@ module Assert
|
|
119
126
|
methods += local_methods
|
120
127
|
|
121
128
|
# uniq and remove any that don't start with 'test'
|
122
|
-
methods.uniq.delete_if {|method_name| method_name !~
|
123
|
-
end
|
124
|
-
|
125
|
-
private
|
126
|
-
|
127
|
-
def count_tests(test_sets)
|
128
|
-
test_sets.inject(0) {|count, tests| count += tests.size}
|
129
|
-
end
|
130
|
-
|
131
|
-
def count_results(test_sets, type)
|
132
|
-
self.values.flatten.inject(0){|count, test| count += test.result_count(type) }
|
133
|
-
end
|
134
|
-
|
135
|
-
def prep
|
136
|
-
if @prepared != true
|
137
|
-
# look for local public methods starting with 'test_'and add
|
138
|
-
self.each do |context_class, tests|
|
139
|
-
local_public_test_methods(context_class).each do |meth|
|
140
|
-
tests << Test.new(meth.to_s, context_class, meth)
|
141
|
-
end
|
142
|
-
tests.uniq
|
143
|
-
end
|
144
|
-
end
|
145
|
-
@prepared = true
|
129
|
+
methods.uniq.delete_if {|method_name| method_name !~ TEST_METHOD_REGEX }
|
146
130
|
end
|
147
131
|
|
148
132
|
end
|