rspec-unit 0.9.22

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source :gemcutter
2
+
3
+ # gem 'bundler', '>= 0.9.16'
4
+ gem 'rspec', '= 2.0.0.beta.22'
5
+
6
+ group :test do
7
+ gem 'rake', '>= 0.8.7'
8
+ gem 'rcov', '>= 0.9.9'
9
+ end
10
+
11
+ group :release do
12
+ gem 'jeweler', '>= 1.4.0'
13
+ end
14
+
@@ -0,0 +1,34 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ gemcutter (0.6.1)
6
+ git (1.2.5)
7
+ jeweler (1.4.0)
8
+ gemcutter (>= 0.1.0)
9
+ git (>= 1.2.5)
10
+ rubyforge (>= 2.0.0)
11
+ json_pure (1.4.6)
12
+ rake (0.8.7)
13
+ rcov (0.9.9)
14
+ rspec (2.0.0.beta.22)
15
+ rspec-core (= 2.0.0.beta.22)
16
+ rspec-expectations (= 2.0.0.beta.22)
17
+ rspec-mocks (= 2.0.0.beta.22)
18
+ rspec-core (2.0.0.beta.22)
19
+ rspec-expectations (2.0.0.beta.22)
20
+ diff-lcs (>= 1.1.2)
21
+ rspec-mocks (2.0.0.beta.22)
22
+ rspec-core (= 2.0.0.beta.22)
23
+ rspec-expectations (= 2.0.0.beta.22)
24
+ rubyforge (2.0.4)
25
+ json_pure (>= 1.1.7)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ jeweler (>= 1.4.0)
32
+ rake (>= 0.8.7)
33
+ rcov (>= 0.9.9)
34
+ rspec (= 2.0.0.beta.22)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009, 2010 Glenn Vanderburg
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,121 @@
1
+ # rspec-unit
2
+
3
+ test/unit compatibility for RSpec 2.
4
+
5
+ ## Summary
6
+
7
+ rspec-unit adds support for test/unit-style assertions and test
8
+ cases to RSpec 2. This is useful for piecemeal conversions of your
9
+ test suite (in either direction), mixing styles, or if you simply
10
+ want to use test/unit-style assertions occasionally in your specs.
11
+
12
+ Just add this to your code:
13
+
14
+ require 'rspec/unit'
15
+
16
+ and then you can write test classes like this:
17
+
18
+ class FooTest < RSpec::Unit::TestCase
19
+ def test_foo
20
+ assert_equal 3, Foo::major_version
21
+ end
22
+ end
23
+
24
+ Using the `test_info` method, you can attach metadata to the next
25
+ defined test (this works much the same way Rake's `desc` method
26
+ attaches a description string to the next defined task):
27
+
28
+ test_info :speed => 'slow', :run => 'nightly'
29
+ def test_tarantula_multipass
30
+ # ...
31
+ end
32
+
33
+ You can also attach metadata to the entire class with the
34
+ `test_case_info` method:
35
+
36
+ class BarTest < RSpec::Unit::TestCase
37
+ test_case_info :integration => true
38
+
39
+ # ...
40
+ end
41
+
42
+ Each instance of `Rspec::Unit::TestCase` is equivalent to an
43
+ RSpec `describe` block, so it can also include `example` blocks,
44
+ `before` and `after` blocks, and nested `describe` blocks. Test
45
+ methods and `example` blocks can contain either assertions or `should`
46
+ expressions. `test` blocks (as found in Rails 2.x) also work.
47
+
48
+ Additionally, assertions can be used inside ordinary RSpec
49
+ examples.
50
+
51
+ ## Rationale
52
+
53
+ This gem is the rough equivalent, for RSpec 2, of the test/unit
54
+ compatibility that was a part of the core RSpec gem in RSpec 1.
55
+ The new RSpec runner design makes it quite easy to implement this
56
+ functionality as a separate gem, which seems like a better choice
57
+ in many ways.
58
+
59
+ Currently, test/unit compatibility is much more limited than in
60
+ RSpec 1. The goal is not to make RSpec 2 a drop-in replacement for
61
+ test/unit; rather, we have two more limited goals:
62
+
63
+ 1. to allow RSpec 2 examples to easily make use of test/unit assertions
64
+ in cases where those assertions are valuable, or where assertions
65
+ might be the best way to express particular expectations.
66
+ 2. to make it *easy* for a project to switch an existing test/unit
67
+ suite over to run under RSpec, as the start of a gradual, piecemeal
68
+ conversion to RSpec.
69
+
70
+ As such, there are some things we don''t support:
71
+
72
+ * The top-level module name is different. For example, one requires
73
+ `rspec/unit` rather than `test/unit`, and extends `RSpec::Unit::TestCase`
74
+ rather than `Test::Unit::TestCase`.
75
+ * TestSuite is not supported. The RSpec 2 metadata features are
76
+ far more flexible than test/unit-style suites.
77
+ * Because of the very different implementation, many test/unit extensions
78
+ will not run properly.
79
+ * All test output and summaries are in RSpec style; test/unit-compatible
80
+ output is not supported.
81
+
82
+ We will certainly consider supporting those things if there is demand.
83
+
84
+ I originally wrote this test/unit compatibility gem for Micronaut, a
85
+ lightweight RSpec clone by Chad Humphries. Micronaut has been rolled
86
+ into RSpec as the core of RSpec 2, and I was able to move the test/unit
87
+ compatibility over with minimal changes.
88
+
89
+ The point of this gem is not that I think test/unit is a better way
90
+ to write tests than the RSpec style. I admit that I'm a TDD oldtimer
91
+ who sees RSpec as mostly a cosmetic (rather than fundamental) change,
92
+ but that doesn't mean it's not an important change. My curmudgeonly
93
+ nature has its limits, and I do find specs a big improvement.
94
+
95
+ So why rspec-unit? Three reasons:
96
+
97
+ 1. I wanted to show off the generality of Micronaut's (and now RSpec's)
98
+ architecture. I hope rspec-unit can serve as an example for anyone
99
+ who wants to experiment with new ways of expressing tests and specs
100
+ on top of RSpec.
101
+ 2. Many projects with existing test/unit test suites might want to
102
+ benefit from the [metadata goodness][metadata] in RSpec 2, or begin
103
+ a gradual, piecemeal change to an RSpec style. That's pretty
104
+ easy to do with rspec-unit.
105
+ 3. Even when writing specs and examples, I frequently encounter
106
+ cases where an assertion is more expressive than a `should`
107
+ expression. It's nice just to have assertions supported within
108
+ RSpec examples.
109
+
110
+ [uth]: http://blog.thinkrelevance.com/2009/4/1/micronaut-innovation-under-the-hood
111
+ [metadata]: http://blog.thinkrelevance.com/2009/3/26/introducing-micronaut-a-lightweight-bdd-framework
112
+
113
+ ## To Do
114
+
115
+ It would be nice to try using the assertion code from minitest,
116
+ which is much more compact and seems less coupled than that from
117
+ test/unit.
118
+
119
+ ### Copyright
120
+
121
+ Copyright (c) 2009, 2010 Glenn Vanderburg. See LICENSE for details.
@@ -0,0 +1,49 @@
1
+ require 'bundler/setup'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = "rspec-unit"
7
+ gem.summary = %Q{test/unit compatibility for RSpec 2.}
8
+ gem.description = gem.summary # File.read('README.md').sub(/\A.*^## Summary\s*$\s*(.*?)\s*^#+\s.*\Z/m, '\1')
9
+ gem.email = "glv@vanderburg.org"
10
+ gem.homepage = "http://github.com/glv/rspec-unit"
11
+ gem.authors = ["Glenn Vanderburg"]
12
+ gem.rubyforge_project = "rspec-unit"
13
+ gem.add_dependency('rspec', '~> 2.0')
14
+ gem.has_rdoc = false
15
+ gem.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
16
+ gem.rubyforge_project = 'glv'
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+
20
+ Jeweler::RubyforgeTasks.new
21
+ Jeweler::GemcutterTasks.new
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
+ end
25
+
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new(:spec) do |spec|
28
+ spec.pattern = 'spec/**/*_spec.rb'
29
+ spec.ruby_opts = '-Ilib -Ispec'
30
+ end
31
+
32
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.rcov_opts = '-Ilib -Ispec -x ' + "'#{Regexp.escape(Bundler.settings.path)},^spec/'"
35
+ spec.rcov = true
36
+ end
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "rspec-unit #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
49
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 9
4
+ :patch: 22
@@ -0,0 +1 @@
1
+ require 'rspec/unit'
@@ -0,0 +1,3 @@
1
+ # This file may be the starting point in some cases, so pull in all of micronaut:
2
+ require 'rspec'
3
+ require 'rspec/unit/test_case'
@@ -0,0 +1,651 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ module RSpec
6
+ module Unit
7
+
8
+ ##
9
+ # Test::Unit::Assertions contains the standard Test::Unit assertions.
10
+ # Assertions is included in Test::Unit::TestCase.
11
+ #
12
+ # To include it in your own code and use its functionality, you simply
13
+ # need to rescue Test::Unit::AssertionFailedError. Additionally you may
14
+ # override add_assertion to get notified whenever an assertion is made.
15
+ #
16
+ # Notes:
17
+ # * The message to each assertion, if given, will be propagated with the
18
+ # failure.
19
+ # * It is easy to add your own assertions based on assert_block().
20
+ #
21
+ # = Example Custom Assertion
22
+ #
23
+ # def deny(boolean, message = nil)
24
+ # message = build_message message, '<?> is not false or nil.', boolean
25
+ # assert_block message do
26
+ # not boolean
27
+ # end
28
+ # end
29
+
30
+ module Assertions
31
+
32
+ ##
33
+ # The assertion upon which all other assertions are based. Passes if the
34
+ # block yields true.
35
+ #
36
+ # Example:
37
+ # assert_block "Couldn't do the thing" do
38
+ # do_the_thing
39
+ # end
40
+
41
+ public
42
+ def assert_block(message="assert_block failed.") # :yields:
43
+ _wrap_assertion do
44
+ if (! yield)
45
+ raise AssertionFailedError.new(message.to_s)
46
+ end
47
+ end
48
+ end
49
+
50
+ ##
51
+ # Asserts that +boolean+ is not false or nil.
52
+ #
53
+ # Example:
54
+ # assert [1, 2].include?(5)
55
+
56
+ public
57
+ def assert(boolean, message=nil)
58
+ _wrap_assertion do
59
+ assert_block("assert should not be called with a block.") { !block_given? }
60
+ assert_block(build_message(message, "<?> is not true.", boolean)) { boolean }
61
+ end
62
+ end
63
+
64
+ ##
65
+ # Passes if +expected+ == +actual.
66
+ #
67
+ # Note that the ordering of arguments is important, since a helpful
68
+ # error message is generated when this one fails that tells you the
69
+ # values of expected and actual.
70
+ #
71
+ # Example:
72
+ # assert_equal 'MY STRING', 'my string'.upcase
73
+
74
+ public
75
+ def assert_equal(expected, actual, message=nil)
76
+ full_message = build_message(message, <<EOT, expected, actual)
77
+ <?> expected but was
78
+ <?>.
79
+ EOT
80
+ assert_block(full_message) { expected == actual }
81
+ end
82
+
83
+ private
84
+ def _check_exception_class(args) # :nodoc:
85
+ args.partition do |klass|
86
+ next if klass.instance_of?(Module)
87
+ assert(Exception >= klass, "Should expect a class of exception, #{klass}")
88
+ true
89
+ end
90
+ end
91
+
92
+ private
93
+ def _expected_exception?(actual_exception, exceptions, modules) # :nodoc:
94
+ exceptions.include?(actual_exception.class) or
95
+ modules.any? {|mod| actual_exception.is_a?(mod)}
96
+ end
97
+
98
+ ##
99
+ # Passes if the block raises one of the given exceptions.
100
+ #
101
+ # Example:
102
+ # assert_raise RuntimeError, LoadError do
103
+ # raise 'Boom!!!'
104
+ # end
105
+
106
+ public
107
+ def assert_raise(*args)
108
+ _wrap_assertion do
109
+ if Module === args.last
110
+ message = ""
111
+ else
112
+ message = args.pop
113
+ end
114
+ exceptions, modules = _check_exception_class(args)
115
+ expected = args.size == 1 ? args.first : args
116
+ actual_exception = nil
117
+ full_message = build_message(message, "<?> exception expected but none was thrown.", expected)
118
+ assert_block(full_message) do
119
+ begin
120
+ yield
121
+ rescue Exception => actual_exception
122
+ break
123
+ end
124
+ false
125
+ end
126
+ full_message = build_message(message, "<?> exception expected but was\n?", expected, actual_exception)
127
+ assert_block(full_message) {_expected_exception?(actual_exception, exceptions, modules)}
128
+ actual_exception
129
+ end
130
+ end
131
+
132
+ ##
133
+ # Alias of assert_raise.
134
+ #
135
+ # Will be deprecated in 1.9, and removed in 2.0.
136
+
137
+ public
138
+ def assert_raises(*args, &block)
139
+ assert_raise(*args, &block)
140
+ end
141
+
142
+ ##
143
+ # Passes if +object+ .instance_of? +klass+
144
+ #
145
+ # Example:
146
+ # assert_instance_of String, 'foo'
147
+
148
+ public
149
+ def assert_instance_of(klass, object, message="")
150
+ _wrap_assertion do
151
+ assert_equal(Class, klass.class, "assert_instance_of takes a Class as its first argument")
152
+ full_message = build_message(message, <<EOT, object, klass, object.class)
153
+ <?> expected to be an instance of
154
+ <?> but was
155
+ <?>.
156
+ EOT
157
+ assert_block(full_message){object.instance_of?(klass)}
158
+ end
159
+ end
160
+
161
+ ##
162
+ # Passes if +object+ is nil.
163
+ #
164
+ # Example:
165
+ # assert_nil [1, 2].uniq!
166
+
167
+ public
168
+ def assert_nil(object, message="")
169
+ assert_equal(nil, object, message)
170
+ end
171
+
172
+ ##
173
+ # Passes if +object+ .kind_of? +klass+
174
+ #
175
+ # Example:
176
+ # assert_kind_of Object, 'foo'
177
+
178
+ public
179
+ def assert_kind_of(klass, object, message="")
180
+ _wrap_assertion do
181
+ assert(klass.kind_of?(Module), "The first parameter to assert_kind_of should be a kind_of Module.")
182
+ full_message = build_message(message, "<?>\nexpected to be kind_of\\?\n<?> but was\n<?>.", object, klass, object.class)
183
+ assert_block(full_message){object.kind_of?(klass)}
184
+ end
185
+ end
186
+
187
+ ##
188
+ # Passes if +object+ .respond_to? +method+
189
+ #
190
+ # Example:
191
+ # assert_respond_to 'bugbear', :slice
192
+
193
+ public
194
+ def assert_respond_to(object, method, message="")
195
+ _wrap_assertion do
196
+ full_message = build_message(nil, "<?>\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to\\?(:to_str).", method)
197
+
198
+ assert_block(full_message) do
199
+ method.kind_of?(Symbol) || method.respond_to?(:to_str)
200
+ end
201
+ full_message = build_message(message, <<EOT, object, object.class, method)
202
+ <?>
203
+ of type <?>
204
+ expected to respond_to\\?<?>.
205
+ EOT
206
+ assert_block(full_message) { object.respond_to?(method) }
207
+ end
208
+ end
209
+
210
+ ##
211
+ # Passes if +string+ =~ +pattern+.
212
+ #
213
+ # Example:
214
+ # assert_match(/\d+/, 'five, 6, seven')
215
+
216
+ public
217
+ def assert_match(pattern, string, message="")
218
+ _wrap_assertion do
219
+ pattern = case(pattern)
220
+ when String
221
+ Regexp.new(Regexp.escape(pattern))
222
+ else
223
+ pattern
224
+ end
225
+ full_message = build_message(message, "<?> expected to be =~\n<?>.", string, pattern)
226
+ assert_block(full_message) { string =~ pattern }
227
+ end
228
+ end
229
+
230
+ ##
231
+ # Passes if +actual+ .equal? +expected+ (i.e. they are the same
232
+ # instance).
233
+ #
234
+ # Example:
235
+ # o = Object.new
236
+ # assert_same o, o
237
+
238
+ public
239
+ def assert_same(expected, actual, message="")
240
+ full_message = build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__)
241
+ <?>
242
+ with id <?> expected to be equal\\? to
243
+ <?>
244
+ with id <?>.
245
+ EOT
246
+ assert_block(full_message) { actual.equal?(expected) }
247
+ end
248
+
249
+ ##
250
+ # Compares the +object1+ with +object2+ using +operator+.
251
+ #
252
+ # Passes if object1.__send__(operator, object2) is true.
253
+ #
254
+ # Example:
255
+ # assert_operator 5, :>=, 4
256
+
257
+ public
258
+ def assert_operator(object1, operator, object2, message="")
259
+ _wrap_assertion do
260
+ full_message = build_message(nil, "<?>\ngiven as the operator for #assert_operator must be a Symbol or #respond_to\\?(:to_str).", operator)
261
+ assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)}
262
+ full_message = build_message(message, <<EOT, object1, AssertionMessage.literal(operator), object2)
263
+ <?> expected to be
264
+ ?
265
+ <?>.
266
+ EOT
267
+ assert_block(full_message) { object1.__send__(operator, object2) }
268
+ end
269
+ end
270
+
271
+ ##
272
+ # Passes if block does not raise an exception.
273
+ #
274
+ # Example:
275
+ # assert_nothing_raised do
276
+ # [1, 2].uniq
277
+ # end
278
+
279
+ public
280
+ def assert_nothing_raised(*args)
281
+ _wrap_assertion do
282
+ if Module === args.last
283
+ message = ""
284
+ else
285
+ message = args.pop
286
+ end
287
+ exceptions, modules = _check_exception_class(args)
288
+ begin
289
+ yield
290
+ rescue Exception => e
291
+ if ((args.empty? && !e.instance_of?(AssertionFailedError)) ||
292
+ _expected_exception?(e, exceptions, modules))
293
+ assert_block(build_message(message, "Exception raised:\n?", e)){false}
294
+ else
295
+ raise
296
+ end
297
+ end
298
+ nil
299
+ end
300
+ end
301
+
302
+ ##
303
+ # Flunk always fails.
304
+ #
305
+ # Example:
306
+ # flunk 'Not done testing yet.'
307
+
308
+ public
309
+ def flunk(message="Flunked")
310
+ assert_block(build_message(message)){false}
311
+ end
312
+
313
+ ##
314
+ # Passes if ! +actual+ .equal? +expected+
315
+ #
316
+ # Example:
317
+ # assert_not_same Object.new, Object.new
318
+
319
+ public
320
+ def assert_not_same(expected, actual, message="")
321
+ full_message = build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__)
322
+ <?>
323
+ with id <?> expected to not be equal\\? to
324
+ <?>
325
+ with id <?>.
326
+ EOT
327
+ assert_block(full_message) { !actual.equal?(expected) }
328
+ end
329
+
330
+ ##
331
+ # Passes if +expected+ != +actual+
332
+ #
333
+ # Example:
334
+ # assert_not_equal 'some string', 5
335
+
336
+ public
337
+ def assert_not_equal(expected, actual, message="")
338
+ full_message = build_message(message, "<?> expected to be != to\n<?>.", expected, actual)
339
+ assert_block(full_message) { expected != actual }
340
+ end
341
+
342
+ ##
343
+ # Passes if ! +object+ .nil?
344
+ #
345
+ # Example:
346
+ # assert_not_nil '1 two 3'.sub!(/two/, '2')
347
+
348
+ public
349
+ def assert_not_nil(object, message="")
350
+ full_message = build_message(message, "<?> expected to not be nil.", object)
351
+ assert_block(full_message){!object.nil?}
352
+ end
353
+
354
+ ##
355
+ # Passes if +regexp+ !~ +string+
356
+ #
357
+ # Example:
358
+ # assert_no_match(/two/, 'one 2 three')
359
+
360
+ public
361
+ def assert_no_match(regexp, string, message="")
362
+ _wrap_assertion do
363
+ assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
364
+ full_message = build_message(message, "<?> expected to not match\n<?>.", regexp, string)
365
+ assert_block(full_message) { regexp !~ string }
366
+ end
367
+ end
368
+
369
+ UncaughtThrow = {NameError => /^uncaught throw \`(.+)\'$/,
370
+ ThreadError => /^uncaught throw \`(.+)\' in thread /} #`
371
+
372
+ ##
373
+ # Passes if the block throws +expected_symbol+
374
+ #
375
+ # Example:
376
+ # assert_throws :done do
377
+ # throw :done
378
+ # end
379
+
380
+ public
381
+ def assert_throws(expected_symbol, message="", &proc)
382
+ _wrap_assertion do
383
+ assert_instance_of(Symbol, expected_symbol, "assert_throws expects the symbol that should be thrown for its first argument")
384
+ assert_block("Should have passed a block to assert_throws."){block_given?}
385
+ caught = true
386
+ begin
387
+ catch(expected_symbol) do
388
+ proc.call
389
+ caught = false
390
+ end
391
+ full_message = build_message(message, "<?> should have been thrown.", expected_symbol)
392
+ assert_block(full_message){caught}
393
+ rescue NameError, ThreadError => error
394
+ if UncaughtThrow[error.class] !~ error.message
395
+ raise error
396
+ end
397
+ full_message = build_message(message, "<?> expected to be thrown but\n<?> was thrown.", expected_symbol, $1.intern)
398
+ flunk(full_message)
399
+ end
400
+ end
401
+ end
402
+
403
+ ##
404
+ # Passes if block does not throw anything.
405
+ #
406
+ # Example:
407
+ # assert_nothing_thrown do
408
+ # [1, 2].uniq
409
+ # end
410
+
411
+ public
412
+ def assert_nothing_thrown(message="", &proc)
413
+ _wrap_assertion do
414
+ assert(block_given?, "Should have passed a block to assert_nothing_thrown")
415
+ begin
416
+ proc.call
417
+ rescue NameError, ThreadError => error
418
+ if UncaughtThrow[error.class] !~ error.message
419
+ raise error
420
+ end
421
+ full_message = build_message(message, "<?> was thrown when nothing was expected", $1.intern)
422
+ flunk(full_message)
423
+ end
424
+ assert(true, "Expected nothing to be thrown")
425
+ end
426
+ end
427
+
428
+ ##
429
+ # Passes if +expected_float+ and +actual_float+ are equal
430
+ # within +delta+ tolerance.
431
+ #
432
+ # Example:
433
+ # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001
434
+
435
+ public
436
+ def assert_in_delta(expected_float, actual_float, delta, message="")
437
+ _wrap_assertion do
438
+ {expected_float => "first float", actual_float => "second float", delta => "delta"}.each do |float, name|
439
+ assert_respond_to(float, :to_f, "The arguments must respond to to_f; the #{name} did not")
440
+ end
441
+ assert_operator(delta, :>=, 0.0, "The delta should not be negative")
442
+ full_message = build_message(message, <<EOT, expected_float, actual_float, delta)
443
+ <?> and
444
+ <?> expected to be within
445
+ <?> of each other.
446
+ EOT
447
+ assert_block(full_message) { (expected_float.to_f - actual_float.to_f).abs <= delta.to_f }
448
+ end
449
+ end
450
+
451
+ ##
452
+ # Passes if the method send returns a true value.
453
+ #
454
+ # +send_array+ is composed of:
455
+ # * A receiver
456
+ # * A method
457
+ # * Arguments to the method
458
+ #
459
+ # Example:
460
+ # assert_send [[1, 2], :include?, 4]
461
+
462
+ public
463
+ def assert_send(send_array, message="")
464
+ _wrap_assertion do
465
+ assert_instance_of(Array, send_array, "assert_send requires an array of send information")
466
+ assert(send_array.size >= 2, "assert_send requires at least a receiver and a message name")
467
+ full_message = build_message(message, <<EOT, send_array[0], AssertionMessage.literal(send_array[1].to_s), send_array[2..-1])
468
+ <?> expected to respond to
469
+ <?(?)> with a true value.
470
+ EOT
471
+ assert_block(full_message) { send_array[0].__send__(send_array[1], *send_array[2..-1]) }
472
+ end
473
+ end
474
+
475
+ ##
476
+ # Builds a failure message. +head+ is added before the +template+ and
477
+ # +arguments+ replaces the '?'s positionally in the template.
478
+
479
+ public
480
+ def build_message(head, template=nil, *arguments)
481
+ template &&= template.chomp
482
+ return AssertionMessage.new(head, template, arguments)
483
+ end
484
+
485
+ private
486
+ def _wrap_assertion
487
+ @_assertion_wrapped ||= false
488
+ unless (@_assertion_wrapped)
489
+ @_assertion_wrapped = true
490
+ begin
491
+ add_assertion
492
+ return yield
493
+ ensure
494
+ @_assertion_wrapped = false
495
+ end
496
+ else
497
+ return yield
498
+ end
499
+ end
500
+
501
+ ##
502
+ # Called whenever an assertion is made. Define this in classes that
503
+ # include Test::Unit::Assertions to record assertion counts.
504
+
505
+ private
506
+ def add_assertion
507
+ end
508
+
509
+ ##
510
+ # Select whether or not to use the pretty-printer. If this option is set
511
+ # to false before any assertions are made, pp.rb will not be required.
512
+
513
+ public
514
+ def self.use_pp=(value)
515
+ AssertionMessage.use_pp = value
516
+ end
517
+
518
+ # :stopdoc:
519
+
520
+ class AssertionMessage
521
+ @use_pp = true
522
+ class << self
523
+ attr_accessor :use_pp
524
+ end
525
+
526
+ class Literal
527
+ def initialize(value)
528
+ @value = value
529
+ end
530
+
531
+ def inspect
532
+ @value.to_s
533
+ end
534
+ end
535
+
536
+ class Template
537
+ def self.create(string)
538
+ parts = (string ? string.scan(/(?=[^\\])\?|(?:\\\?|[^\?])+/m) : [])
539
+ self.new(parts)
540
+ end
541
+
542
+ attr_reader :count
543
+
544
+ def initialize(parts)
545
+ @parts = parts
546
+ @count = parts.find_all{|e| e == '?'}.size
547
+ end
548
+
549
+ def result(parameters)
550
+ raise "The number of parameters does not match the number of substitutions." if(parameters.size != count)
551
+ params = parameters.dup
552
+ @parts.collect{|e| e == '?' ? params.shift : e.gsub(/\\\?/m, '?')}.join('')
553
+ end
554
+ end
555
+
556
+ def self.literal(value)
557
+ Literal.new(value)
558
+ end
559
+
560
+ def initialize(head, template_string, parameters)
561
+ @head = head
562
+ @template_string = template_string
563
+ @parameters = parameters
564
+ end
565
+
566
+ def convert(object)
567
+ case object
568
+ when Exception
569
+ <<EOM.chop
570
+ Class: <#{convert(object.class)}>
571
+ Message: <#{convert(object.message)}>
572
+ ---Backtrace---
573
+ #{filter_backtrace(object.backtrace).join("\n")}
574
+ ---------------
575
+ EOM
576
+ else
577
+ if(self.class.use_pp)
578
+ begin
579
+ require 'pp'
580
+ rescue LoadError
581
+ self.class.use_pp = false
582
+ return object.inspect
583
+ end unless(defined?(PP))
584
+ PP.pp(object, '').chomp
585
+ else
586
+ object.inspect
587
+ end
588
+ end
589
+ end
590
+
591
+ def template
592
+ @template ||= Template.create(@template_string)
593
+ end
594
+
595
+ def add_period(string)
596
+ (string =~ /\.\Z/ ? string : string + '.')
597
+ end
598
+
599
+ def to_s
600
+ message_parts = []
601
+ if (@head)
602
+ head = @head.to_s
603
+ unless(head.empty?)
604
+ message_parts << add_period(head)
605
+ end
606
+ end
607
+ tail = template.result(@parameters.collect{|e| convert(e)})
608
+ message_parts << tail unless(tail.empty?)
609
+ message_parts.join("\n")
610
+ end
611
+
612
+ MICRONAUTUNIT_FILE_SEPARATORS = %r{[\\/:]}
613
+ MICRONAUTUNIT_PREFIX = __FILE__.split(MICRONAUTUNIT_FILE_SEPARATORS)[0..-3]
614
+ MICRONAUTUNIT_RB_FILE = /\.rb\Z/
615
+
616
+ def filter_backtrace(backtrace, prefix=nil)
617
+ return ["No backtrace"] unless(backtrace)
618
+ split_p = if(prefix)
619
+ prefix.split(MICRONAUTUNIT_FILE_SEPARATORS)
620
+ else
621
+ MICRONAUTUNIT_PREFIX
622
+ end
623
+ match = proc do |e|
624
+ split_e = e.split(MICRONAUTUNIT_FILE_SEPARATORS)[0, split_p.size]
625
+ next false unless(split_e[0..-2] == split_p[0..-2])
626
+ split_e[-1].sub(MICRONAUTUNIT_RB_FILE, '') == split_p[-1]
627
+ end
628
+ return backtrace unless(backtrace.detect(&match))
629
+ found_prefix = false
630
+ new_backtrace = backtrace.reverse.reject do |e|
631
+ if(match[e])
632
+ found_prefix = true
633
+ true
634
+ elsif(found_prefix)
635
+ false
636
+ else
637
+ true
638
+ end
639
+ end.reverse
640
+ new_backtrace = (new_backtrace.empty? ? backtrace : new_backtrace)
641
+ new_backtrace = new_backtrace.reject(&match)
642
+ new_backtrace.empty? ? backtrace : new_backtrace
643
+ end
644
+
645
+ end
646
+
647
+ # :startdoc:
648
+
649
+ end
650
+ end
651
+ end