glv-micronaut-unit 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 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,73 @@
1
+ # micronaut-unit
2
+
3
+ Test::Unit compatibility for micronaut.
4
+
5
+ Just add this to your code:
6
+
7
+ require 'micronaut/unit'
8
+
9
+ and then you can write test classes like this:
10
+
11
+ class FooTest < Micronaut::Unit::TestCase
12
+ def test_foo
13
+ assert_equal 3, Foo::major_version
14
+ end
15
+ end
16
+
17
+ Using the `testinfo` method, you can attach metadata to the next
18
+ defined test (this works much the same way Rake's `desc` method
19
+ attaches a description string to the next defined task):
20
+
21
+ testinfo :speed => 'slow', :run => 'nightly' def
22
+ test_tarantula_multipass
23
+ # ...
24
+ end
25
+
26
+ Each instance of `Micronaut::Unit::TestCase` is equivalent to a
27
+ micronaut `describe` block, so it can also include `it` blocks,
28
+ `before` and `after` blocks, and nested `describe` blocks. Test
29
+ methods and `it` blocks can contain either assertions or `should`
30
+ expressions. `test` blocks (as found in Rails 2.x) also work.
31
+
32
+ Additionally, assertions can be used inside ordinary micronaut
33
+ examples.
34
+
35
+ ## Rationale
36
+
37
+ The point of this gem is not that I think test/unit is a better way
38
+ to write tests than the RSpec style. I admit that I'm a TDD oldtimer
39
+ who sees RSpec as mostly a cosmetic (rather than fundamental) change,
40
+ but that doesn't mean it's not an important change. My curmudgeonly
41
+ nature has its limits, and I do find specs a big improvement.
42
+
43
+ So why micronaut-unit? Three reasons:
44
+
45
+ 1. I wanted to show off the generality of Micronaut's architecture.
46
+ On the surface, Micronaut might not seem all that compelling
47
+ (since it's basically an RSpec work-alike). But it's really a
48
+ fantastic tool; it's just that the
49
+ [innovation is all under the hood][uth], in a way that makes it
50
+ easy to change the surface aspects. I hope micronaut-unit can
51
+ serve as an example for anyone who wants to experiment with new
52
+ ways of expressing tests and specs on top of Micronaut.
53
+ 2. Many projects with existing test/unit test suites might want to
54
+ benefit from Micronaut's [metadata goodness][metadata], or begin
55
+ a gradual, piecemeal change to an RSpec style. That's pretty
56
+ easy to do with micronaut-unit.
57
+ 3. Even when writing specs and examples, I frequently encounter
58
+ cases where an assertion is more expressive than a `should`
59
+ expression. It's nice just to have assertions supported within
60
+ Micronaut examples.
61
+
62
+ [uth]: http://blog.thinkrelevance.com/2009/4/1/micronaut-innovation-under-the-hood
63
+ [metadata]: http://blog.thinkrelevance.com/2009/3/26/introducing-micronaut-a-lightweight-bdd-framework
64
+
65
+ ## To Do
66
+
67
+ It would be nice to try using the assertion code from minitest,
68
+ which is much more compact and seems less coupled than that from
69
+ test/unit.
70
+
71
+ ### Copyright
72
+
73
+ Copyright (c) 2009 Glenn Vanderburg. See LICENSE for details.
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "micronaut-unit"
8
+ gem.summary = %Q{Adds test/unit compatibility to Micronaut.}
9
+ gem.email = "glv@vanderburg.org"
10
+ gem.homepage = "http://github.com/glv/micronaut-unit"
11
+ gem.authors = ["Glenn Vanderburg"]
12
+ gem.rubyforge_project = "micronaut-unit"
13
+ gem.add_dependency('spicycode-micronaut', '>= 0.2.9')
14
+ gem.has_rdoc = false
15
+ gem.files = FileList["[A-Z]*", "{bin,lib,examples}/**/*"]
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
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ require 'micronaut/rake_task'
26
+ Micronaut::RakeTask.new(:examples) do |examples|
27
+ examples.pattern = 'examples/**/*_example.rb'
28
+ examples.ruby_opts << '-Ilib -Iexamples'
29
+ end
30
+
31
+ Micronaut::RakeTask.new(:rcov) do |examples|
32
+ examples.pattern = 'examples/**/*_example.rb'
33
+ examples.rcov_opts = '-Ilib -Iexamples -x "/Library/Ruby/Gems,examples/"'
34
+ examples.rcov = true
35
+ end
36
+
37
+ task :default => :examples
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ if File.exist?('VERSION.yml')
42
+ config = YAML.load(File.read('VERSION.yml'))
43
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
44
+ else
45
+ version = ""
46
+ end
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "micronaut-unit #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
53
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 0
4
+ :minor: 2
@@ -0,0 +1,528 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ require File.expand_path(File.dirname(__FILE__) + "/example_helper")
6
+
7
+ # This is borrowed with minor changes from test/unit. I'm leaving it in test/unit format
8
+ # rather than converting to rspec-style. ---glv
9
+ class TC_Assertions < Micronaut::Unit::TestCase
10
+ AssertionFailedError = Micronaut::Unit::AssertionFailedError
11
+
12
+ def check(value, message="")
13
+ add_assertion
14
+ if (!value)
15
+ raise AssertionFailedError.new(message)
16
+ end
17
+ end
18
+
19
+ def check_assertions(expect_fail, expected_message="", return_value_expected=false)
20
+ @actual_assertion_count = 0
21
+ failed = true
22
+ actual_message = nil
23
+ @catch_assertions = true
24
+ return_value = nil
25
+ begin
26
+ return_value = yield
27
+ failed = false
28
+ rescue AssertionFailedError => error
29
+ actual_message = error.message
30
+ end
31
+ @catch_assertions = false
32
+ check(expect_fail == failed, (expect_fail ? "Should have failed, but didn't" : "Should not have failed, but did with message\n<#{actual_message}>"))
33
+ check(1 == @actual_assertion_count, "Should have made one assertion but made <#{@actual_assertion_count}>")
34
+ if (expect_fail)
35
+ case expected_message
36
+ when String
37
+ check(actual_message == expected_message, "Should have the correct message.\n<#{expected_message.inspect}> expected but was\n<#{actual_message.inspect}>")
38
+ when Regexp
39
+ check(actual_message =~ expected_message, "The message should match correctly.\n</#{expected_message.source}/> expected to match\n<#{actual_message.inspect}>")
40
+ else
41
+ check(false, "Incorrect expected message type in assert_nothing_failed")
42
+ end
43
+ else
44
+ if (!return_value_expected)
45
+ check(return_value.nil?, "Should not return a value but returned <#{return_value}>")
46
+ else
47
+ check(!return_value.nil?, "Should return a value")
48
+ end
49
+ end
50
+ return return_value
51
+ end
52
+
53
+ def check_nothing_fails(return_value_expected=false, &proc)
54
+ check_assertions(false, "", return_value_expected, &proc)
55
+ end
56
+
57
+ def check_fails(expected_message="", &proc)
58
+ check_assertions(true, expected_message, &proc)
59
+ end
60
+
61
+ def test_assert_block
62
+ check_nothing_fails {
63
+ assert_block {true}
64
+ }
65
+ check_nothing_fails {
66
+ assert_block("successful assert_block") {true}
67
+ }
68
+ check_nothing_fails {
69
+ assert_block("successful assert_block") {true}
70
+ }
71
+ check_fails("assert_block failed.") {
72
+ assert_block {false}
73
+ }
74
+ check_fails("failed assert_block") {
75
+ assert_block("failed assert_block") {false}
76
+ }
77
+ end
78
+
79
+ def test_assert
80
+ check_nothing_fails{assert("a")}
81
+ check_nothing_fails{assert(true)}
82
+ check_nothing_fails{assert(true, "successful assert")}
83
+ check_fails("<nil> is not true."){assert(nil)}
84
+ check_fails("<false> is not true."){assert(false)}
85
+ check_fails("failed assert.\n<false> is not true."){assert(false, "failed assert")}
86
+ end
87
+
88
+ def test_assert_equal
89
+ check_nothing_fails {
90
+ assert_equal("string1", "string1")
91
+ }
92
+ check_nothing_fails {
93
+ assert_equal( "string1", "string1", "successful assert_equal")
94
+ }
95
+ check_nothing_fails {
96
+ assert_equal("string1", "string1", "successful assert_equal")
97
+ }
98
+ check_fails(%Q{<"string1"> expected but was\n<"string2">.}) {
99
+ assert_equal("string1", "string2")
100
+ }
101
+ check_fails(%Q{failed assert_equal.\n<"string1"> expected but was\n<"string2">.}) {
102
+ assert_equal("string1", "string2", "failed assert_equal")
103
+ }
104
+ check_fails(%Q{<"1"> expected but was\n<1>.}) do
105
+ assert_equal("1", 1)
106
+ end
107
+ end
108
+
109
+ def test_assert_raise
110
+ return_value = nil
111
+ check_nothing_fails(true) {
112
+ return_value = assert_raise(RuntimeError) {
113
+ raise "Error"
114
+ }
115
+ }
116
+ check(return_value.kind_of?(Exception), "Should have returned the exception from a successful assert_raise")
117
+ check(return_value.message == "Error", "Should have returned the correct exception from a successful assert_raise")
118
+ check_nothing_fails(true) {
119
+ assert_raise(ArgumentError, "successful assert_raise") {
120
+ raise ArgumentError.new("Error")
121
+ }
122
+ }
123
+ check_nothing_fails(true) {
124
+ assert_raise(RuntimeError) {
125
+ raise "Error"
126
+ }
127
+ }
128
+ check_nothing_fails(true) {
129
+ assert_raise(RuntimeError, "successful assert_raise") {
130
+ raise "Error"
131
+ }
132
+ }
133
+ check_fails("<RuntimeError> exception expected but none was thrown.") {
134
+ assert_raise(RuntimeError) {
135
+ 1 + 1
136
+ }
137
+ }
138
+ check_fails(%r{\Afailed assert_raise.\n<ArgumentError> exception expected but was\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
139
+ assert_raise(ArgumentError, "failed assert_raise") {
140
+ raise "Error"
141
+ }
142
+ }
143
+ check_fails("Should expect a class of exception, Object.\n<false> is not true.") {
144
+ assert_nothing_raised(Object) {
145
+ 1 + 1
146
+ }
147
+ }
148
+
149
+ exceptions = [ArgumentError, TypeError]
150
+ modules = [Math, Comparable]
151
+ rescues = exceptions + modules
152
+ exceptions.each do |exc|
153
+ check_nothing_fails(true) {
154
+ return_value = assert_raise(*rescues) {
155
+ raise exc, "Error"
156
+ }
157
+ }
158
+ check(return_value.instance_of?(exc), "Should have returned #{exc} but was #{return_value.class}")
159
+ check(return_value.message == "Error", "Should have returned the correct exception from a successful assert_raise")
160
+ end
161
+ modules.each do |mod|
162
+ check_nothing_fails(true) {
163
+ return_value = assert_raise(*rescues) {
164
+ raise Exception.new("Error").extend(mod)
165
+ }
166
+ }
167
+ check(mod === return_value, "Should have returned #{mod}")
168
+ check(return_value.message == "Error", "Should have returned the correct exception from a successful assert_raise")
169
+ end
170
+ check_fails("<[ArgumentError, TypeError, Math, Comparable]> exception expected but none was thrown.") {
171
+ assert_raise(*rescues) {
172
+ 1 + 1
173
+ }
174
+ }
175
+ check_fails(%r{\Afailed assert_raise.
176
+ <\[ArgumentError, TypeError\]> exception expected but was
177
+ Class: <RuntimeError>
178
+ Message: <"Error">
179
+ ---Backtrace---
180
+ .+
181
+ ---------------\Z}m) {
182
+ assert_raise(ArgumentError, TypeError, "failed assert_raise") {
183
+ raise "Error"
184
+ }
185
+ }
186
+ end
187
+
188
+ def test_assert_instance_of
189
+ check_nothing_fails {
190
+ assert_instance_of(String, "string")
191
+ }
192
+ check_nothing_fails {
193
+ assert_instance_of(String, "string", "successful assert_instance_of")
194
+ }
195
+ check_nothing_fails {
196
+ assert_instance_of(String, "string", "successful assert_instance_of")
197
+ }
198
+ check_fails(%Q{<"string"> expected to be an instance of\n<Hash> but was\n<String>.}) {
199
+ assert_instance_of(Hash, "string")
200
+ }
201
+ check_fails(%Q{failed assert_instance_of.\n<"string"> expected to be an instance of\n<Hash> but was\n<String>.}) {
202
+ assert_instance_of(Hash, "string", "failed assert_instance_of")
203
+ }
204
+ end
205
+
206
+ def test_assert_nil
207
+ check_nothing_fails {
208
+ assert_nil(nil)
209
+ }
210
+ check_nothing_fails {
211
+ assert_nil(nil, "successful assert_nil")
212
+ }
213
+ check_nothing_fails {
214
+ assert_nil(nil, "successful assert_nil")
215
+ }
216
+ check_fails(%Q{<nil> expected but was\n<"string">.}) {
217
+ assert_nil("string")
218
+ }
219
+ check_fails(%Q{failed assert_nil.\n<nil> expected but was\n<"string">.}) {
220
+ assert_nil("string", "failed assert_nil")
221
+ }
222
+ end
223
+
224
+ def test_assert_not_nil
225
+ check_nothing_fails{assert_not_nil(false)}
226
+ check_nothing_fails{assert_not_nil(false, "message")}
227
+ check_fails("<nil> expected to not be nil."){assert_not_nil(nil)}
228
+ check_fails("message.\n<nil> expected to not be nil.") {assert_not_nil(nil, "message")}
229
+ end
230
+
231
+ def test_assert_kind_of
232
+ check_nothing_fails {
233
+ assert_kind_of(Module, Array)
234
+ }
235
+ check_nothing_fails {
236
+ assert_kind_of(Object, "string", "successful assert_kind_of")
237
+ }
238
+ check_nothing_fails {
239
+ assert_kind_of(Object, "string", "successful assert_kind_of")
240
+ }
241
+ check_nothing_fails {
242
+ assert_kind_of(Comparable, 1)
243
+ }
244
+ check_fails(%Q{<"string">\nexpected to be kind_of?\n<Class> but was\n<String>.}) {
245
+ assert_kind_of(Class, "string")
246
+ }
247
+ check_fails(%Q{failed assert_kind_of.\n<"string">\nexpected to be kind_of?\n<Class> but was\n<String>.}) {
248
+ assert_kind_of(Class, "string", "failed assert_kind_of")
249
+ }
250
+ end
251
+
252
+ def test_assert_match
253
+ check_nothing_fails {
254
+ assert_match(/strin./, "string")
255
+ }
256
+ check_nothing_fails {
257
+ assert_match("strin", "string")
258
+ }
259
+ check_nothing_fails {
260
+ assert_match(/strin./, "string", "successful assert_match")
261
+ }
262
+ check_nothing_fails {
263
+ assert_match(/strin./, "string", "successful assert_match")
264
+ }
265
+ check_fails(%Q{<"string"> expected to be =~\n</slin./>.}) {
266
+ assert_match(/slin./, "string")
267
+ }
268
+ check_fails(%Q{<"string"> expected to be =~\n</strin\\./>.}) {
269
+ assert_match("strin.", "string")
270
+ }
271
+ check_fails(%Q{failed assert_match.\n<"string"> expected to be =~\n</slin./>.}) {
272
+ assert_match(/slin./, "string", "failed assert_match")
273
+ }
274
+ end
275
+
276
+ def test_assert_same
277
+ thing = "thing"
278
+ check_nothing_fails {
279
+ assert_same(thing, thing)
280
+ }
281
+ check_nothing_fails {
282
+ assert_same(thing, thing, "successful assert_same")
283
+ }
284
+ check_nothing_fails {
285
+ assert_same(thing, thing, "successful assert_same")
286
+ }
287
+ thing2 = "thing"
288
+ check_fails(%Q{<"thing">\nwith id <#{thing.__id__}> expected to be equal? to\n<"thing">\nwith id <#{thing2.__id__}>.}) {
289
+ assert_same(thing, thing2)
290
+ }
291
+ check_fails(%Q{failed assert_same.\n<"thing">\nwith id <#{thing.__id__}> expected to be equal? to\n<"thing">\nwith id <#{thing2.__id__}>.}) {
292
+ assert_same(thing, thing2, "failed assert_same")
293
+ }
294
+ end
295
+
296
+ def test_assert_nothing_raised
297
+ check_nothing_fails {
298
+ assert_nothing_raised {
299
+ 1 + 1
300
+ }
301
+ }
302
+ check_nothing_fails {
303
+ assert_nothing_raised("successful assert_nothing_raised") {
304
+ 1 + 1
305
+ }
306
+ }
307
+ check_nothing_fails {
308
+ assert_nothing_raised("successful assert_nothing_raised") {
309
+ 1 + 1
310
+ }
311
+ }
312
+ check_nothing_fails {
313
+ begin
314
+ assert_nothing_raised(RuntimeError, StandardError, Comparable, "successful assert_nothing_raised") {
315
+ raise ZeroDivisionError.new("ArgumentError")
316
+ }
317
+ rescue ZeroDivisionError
318
+ end
319
+ }
320
+ check_fails("Should expect a class of exception, Object.\n<false> is not true.") {
321
+ assert_nothing_raised(Object) {
322
+ 1 + 1
323
+ }
324
+ }
325
+ check_fails(%r{\AException raised:\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
326
+ assert_nothing_raised {
327
+ raise "Error"
328
+ }
329
+ }
330
+ check_fails(%r{\Afailed assert_nothing_raised\.\nException raised:\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
331
+ assert_nothing_raised("failed assert_nothing_raised") {
332
+ raise "Error"
333
+ }
334
+ }
335
+ check_fails(%r{\AException raised:\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
336
+ assert_nothing_raised(StandardError, RuntimeError) {
337
+ raise "Error"
338
+ }
339
+ }
340
+ check_fails("Failure.") do
341
+ assert_nothing_raised do
342
+ flunk("Failure")
343
+ end
344
+ end
345
+ end
346
+
347
+ def test_flunk
348
+ check_fails("Flunked.") {
349
+ flunk
350
+ }
351
+ check_fails("flunk message.") {
352
+ flunk("flunk message")
353
+ }
354
+ end
355
+
356
+ def test_assert_not_same
357
+ thing = "thing"
358
+ thing2 = "thing"
359
+ check_nothing_fails {
360
+ assert_not_same(thing, thing2)
361
+ }
362
+ check_nothing_fails {
363
+ assert_not_same(thing, thing2, "message")
364
+ }
365
+ check_fails(%Q{<"thing">\nwith id <#{thing.__id__}> expected to not be equal? to\n<"thing">\nwith id <#{thing.__id__}>.}) {
366
+ assert_not_same(thing, thing)
367
+ }
368
+ check_fails(%Q{message.\n<"thing">\nwith id <#{thing.__id__}> expected to not be equal? to\n<"thing">\nwith id <#{thing.__id__}>.}) {
369
+ assert_not_same(thing, thing, "message")
370
+ }
371
+ end
372
+
373
+ def test_assert_not_equal
374
+ check_nothing_fails {
375
+ assert_not_equal("string1", "string2")
376
+ }
377
+ check_nothing_fails {
378
+ assert_not_equal("string1", "string2", "message")
379
+ }
380
+ check_fails(%Q{<"string"> expected to be != to\n<"string">.}) {
381
+ assert_not_equal("string", "string")
382
+ }
383
+ check_fails(%Q{message.\n<"string"> expected to be != to\n<"string">.}) {
384
+ assert_not_equal("string", "string", "message")
385
+ }
386
+ end
387
+
388
+ def test_assert_no_match
389
+ check_nothing_fails{assert_no_match(/sling/, "string")}
390
+ check_nothing_fails{assert_no_match(/sling/, "string", "message")}
391
+ check_fails(%Q{The first argument to assert_no_match should be a Regexp.\n<"asdf"> expected to be an instance of\n<Regexp> but was\n<String>.}) do
392
+ assert_no_match("asdf", "asdf")
393
+ end
394
+ check_fails(%Q{</string/> expected to not match\n<"string">.}) do
395
+ assert_no_match(/string/, "string")
396
+ end
397
+ check_fails(%Q{message.\n</string/> expected to not match\n<"string">.}) do
398
+ assert_no_match(/string/, "string", "message")
399
+ end
400
+ end
401
+
402
+ def test_assert_throws
403
+ check_nothing_fails {
404
+ assert_throws(:thing, "message") {
405
+ throw :thing
406
+ }
407
+ }
408
+ check_fails("message.\n<:thing> expected to be thrown but\n<:thing2> was thrown.") {
409
+ assert_throws(:thing, "message") {
410
+ throw :thing2
411
+ }
412
+ }
413
+ check_fails("message.\n<:thing> should have been thrown.") {
414
+ assert_throws(:thing, "message") {
415
+ 1 + 1
416
+ }
417
+ }
418
+ end
419
+
420
+ def test_assert_nothing_thrown
421
+ check_nothing_fails {
422
+ assert_nothing_thrown("message") {
423
+ 1 + 1
424
+ }
425
+ }
426
+ check_fails("message.\n<:thing> was thrown when nothing was expected.") {
427
+ assert_nothing_thrown("message") {
428
+ throw :thing
429
+ }
430
+ }
431
+ end
432
+
433
+ def test_assert_operator
434
+ check_nothing_fails {
435
+ assert_operator("thing", :==, "thing", "message")
436
+ }
437
+ check_fails(%Q{<0.15>\ngiven as the operator for #assert_operator must be a Symbol or #respond_to?(:to_str).}) do
438
+ assert_operator("thing", 0.15, "thing")
439
+ end
440
+ check_fails(%Q{message.\n<"thing1"> expected to be\n==\n<"thing2">.}) {
441
+ assert_operator("thing1", :==, "thing2", "message")
442
+ }
443
+ end
444
+
445
+ def test_assert_respond_to
446
+ check_nothing_fails {
447
+ assert_respond_to("thing", :to_s, "message")
448
+ }
449
+ check_nothing_fails {
450
+ assert_respond_to("thing", "to_s", "message")
451
+ }
452
+ check_fails("<0.15>\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to?(:to_str).") {
453
+ assert_respond_to("thing", 0.15)
454
+ }
455
+ check_fails("message.\n<:symbol>\nof type <Symbol>\nexpected to respond_to?<:non_existent>.") {
456
+ assert_respond_to(:symbol, :non_existent, "message")
457
+ }
458
+ end
459
+
460
+ def test_assert_in_delta
461
+ check_nothing_fails {
462
+ assert_in_delta(1.4, 1.4, 0)
463
+ }
464
+ check_nothing_fails {
465
+ assert_in_delta(0.5, 0.4, 0.1, "message")
466
+ }
467
+ check_nothing_fails {
468
+ float_thing = Object.new
469
+ def float_thing.to_f
470
+ 0.2
471
+ end
472
+ assert_in_delta(0.1, float_thing, 0.1)
473
+ }
474
+ check_fails("message.\n<0.5> and\n<0.4> expected to be within\n<0.05> of each other.") {
475
+ assert_in_delta(0.5, 0.4, 0.05, "message")
476
+ }
477
+ check_fails(%r{The arguments must respond to to_f; the first float did not\.\n<.+>\nof type <Object>\nexpected to respond_to\?<:to_f>.}) {
478
+ assert_in_delta(Object.new, 0.4, 0.1)
479
+ }
480
+ check_fails("The delta should not be negative.\n<-0.1> expected to be\n>=\n<0.0>.") {
481
+ assert_in_delta(0.5, 0.4, -0.1, "message")
482
+ }
483
+ end
484
+
485
+ def test_assert_send
486
+ object = Object.new
487
+ class << object
488
+ private
489
+ def return_argument(argument, bogus)
490
+ return argument
491
+ end
492
+ end
493
+ check_nothing_fails {
494
+ assert_send([object, :return_argument, true, "bogus"], "message")
495
+ }
496
+ check_fails(%r{\Amessage\.\n<.+> expected to respond to\n<return_argument\(\[false, "bogus"\]\)> with a true value.\Z}) {
497
+ assert_send([object, :return_argument, false, "bogus"], "message")
498
+ }
499
+ end
500
+
501
+ def test_condition_invariant
502
+ object = Object.new
503
+ def object.inspect
504
+ @changed = true
505
+ end
506
+ def object.==(other)
507
+ @changed ||= false
508
+ return (!@changed)
509
+ end
510
+ check_nothing_fails {
511
+ assert_equal(object, object, "message")
512
+ }
513
+ end
514
+
515
+ def add_failure(message, location=caller)
516
+ if (!@catch_assertions)
517
+ super
518
+ end
519
+ end
520
+
521
+ def add_assertion
522
+ if (!@catch_assertions)
523
+ super
524
+ else
525
+ @actual_assertion_count += 1
526
+ end
527
+ end
528
+ end