summaryrefslogtreecommitdiff
path: root/test/testunit/test_assertions.rb
blob: ab92bcfc6d1f9e8b08dbfe63e42b46bc7b1b0b03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit'

module Test
  module Unit
    class TC_Assertions < TestCase
      def check(value, message="")
        add_assertion
        if (!value)
          raise AssertionFailedError.new(message)
        end
      end

      def check_assertions(expect_fail, expected_message="", return_value_expected=false)
        @actual_assertion_count = 0
        failed = true
        actual_message = nil
        @catch_assertions = true
        return_value = nil
        begin
          return_value = yield
          failed = false
        rescue AssertionFailedError => error
          actual_message = error.message
        end
        @catch_assertions = false
        check(expect_fail == failed, (expect_fail ? "Should have failed, but didn't" : "Should not have failed, but did with message\n<#{actual_message}>"))
        check(1 == @actual_assertion_count, "Should have made one assertion but made <#{@actual_assertion_count}>")
        if (expect_fail)
          case expected_message
            when String
              check(actual_message == expected_message, "Should have the correct message.\n<#{expected_message.inspect}> expected but was\n<#{actual_message.inspect}>")
            when Regexp
              check(actual_message =~ expected_message, "The message should match correctly.\n</#{expected_message.source}/> expected to match\n<#{actual_message.inspect}>")
            else
              check(false, "Incorrect expected message type in assert_nothing_failed")
          end
        else
          if (!return_value_expected)
            check(return_value.nil?, "Should not return a value but returned <#{return_value}>")
          else
            check(!return_value.nil?, "Should return a value")
          end
        end
        return return_value
      end
      
      def check_nothing_fails(return_value_expected=false, &proc)
        check_assertions(false, "", return_value_expected, &proc)
      end
      
      def check_fails(expected_message="", &proc)
        check_assertions(true, expected_message, &proc)
      end
      
      def test_assert_block
        check_nothing_fails {
          assert_block {true}
        }
        check_nothing_fails {
          assert_block("successful assert_block") {true}
        }
        check_nothing_fails {
          assert_block("successful assert_block") {true}
        }
        check_fails("assert_block failed.") {
          assert_block {false}
        }
        check_fails("failed assert_block") {
          assert_block("failed assert_block") {false}
        }
      end
      
      def test_assert
        check_nothing_fails{assert("a")}
        check_nothing_fails{assert(true)}
        check_nothing_fails{assert(true, "successful assert")}
        check_fails("<nil> is not true."){assert(nil)}
        check_fails("<false> is not true."){assert(false)}
        check_fails("failed assert.\n<false> is not true."){assert(false, "failed assert")}
      end
      
      def test_assert_equal
        check_nothing_fails {
          assert_equal("string1", "string1")
        }
        check_nothing_fails {
          assert_equal( "string1", "string1", "successful assert_equal")
        }
        check_nothing_fails {
          assert_equal("string1", "string1", "successful assert_equal")
        }
        check_fails(%Q{<"string1"> expected but was\n<"string2">.}) {
          assert_equal("string1", "string2")
        }
        check_fails(%Q{failed assert_equal.\n<"string1"> expected but was\n<"string2">.}) {
          assert_equal("string1", "string2", "failed assert_equal")
        }
        check_fails(%Q{<"1"> expected but was\n<1>.}) do
          assert_equal("1", 1)
        end
      end
      
      def test_assert_raises
        return_value = nil
        check_nothing_fails(true) {
          return_value = assert_raises(RuntimeError) {
            raise "Error"
          }
        }
        check(return_value.kind_of?(Exception), "Should have returned the exception from a successful assert_raises")
        check(return_value.message == "Error", "Should have returned the correct exception from a successful assert_raises")
        check_nothing_fails(true) {
          assert_raises(ArgumentError, "successful assert_raises") {
            raise ArgumentError.new("Error")
          }
        }
        check_nothing_fails(true) {
          assert_raises(RuntimeError) {
            raise "Error"
          }
        }
        check_nothing_fails(true) {
          assert_raises(RuntimeError, "successful assert_raises") {
            raise "Error"
          }
        }
        check_fails("<RuntimeError> exception expected but none was thrown.") {
          assert_raises(RuntimeError) {
            1 + 1
          }
        }
        check_fails(%r{\Afailed assert_raises.\n<ArgumentError> exception expected but was\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
          assert_raises(ArgumentError, "failed assert_raises") {
            raise "Error"
          }
        }
      end
      
      def test_assert_instance_of
        check_nothing_fails {
          assert_instance_of(String, "string")
        }
        check_nothing_fails {
          assert_instance_of(String, "string", "successful assert_instance_of")
        }
        check_nothing_fails {
          assert_instance_of(String, "string", "successful assert_instance_of")
        }
        check_fails(%Q{<"string"> expected to be an instance of\n<Hash> but was\n<String>.}) {
          assert_instance_of(Hash, "string")
        }
        check_fails(%Q{failed assert_instance_of.\n<"string"> expected to be an instance of\n<Hash> but was\n<String>.}) {
          assert_instance_of(Hash, "string", "failed assert_instance_of")
        }
      end
      
      def test_assert_nil
        check_nothing_fails {
          assert_nil(nil)
        }
        check_nothing_fails {
          assert_nil(nil, "successful assert_nil")
        }
        check_nothing_fails {
          assert_nil(nil, "successful assert_nil")
        }
        check_fails(%Q{<nil> expected but was\n<"string">.}) {
          assert_nil("string")
        }
        check_fails(%Q{failed assert_nil.\n<nil> expected but was\n<"string">.}) {
          assert_nil("string", "failed assert_nil")
        }
      end
      
      def test_assert_kind_of
        check_nothing_fails {
          assert_kind_of(Module, Array)
        }
        check_nothing_fails {
          assert_kind_of(Object, "string", "successful assert_kind_of")
        }
        check_nothing_fails {
          assert_kind_of(Object, "string", "successful assert_kind_of")
        }
        check_nothing_fails {
          assert_kind_of(Comparable, 1)
        }
        check_fails(%Q{<"string">\nexpected to be kind_of?<Class>.}) {
          assert_kind_of(Class, "string")
        }
        check_fails(%Q{failed assert_kind_of.\n<"string">\nexpected to be kind_of?<Class>.}) {
          assert_kind_of(Class, "string", "failed assert_kind_of")
        }
      end
      
      def test_assert_match
        check_nothing_fails {
          assert_match(/strin./, "string")
        }
        check_nothing_fails {
          assert_match("strin", "string")
        }
        check_nothing_fails {
          assert_match(/strin./, "string", "successful assert_match")
        }
        check_nothing_fails {
          assert_match(/strin./, "string", "successful assert_match")
        }
        check_fails(%Q{<"string"> expected to be =~\n</slin./>.}) {
          assert_match(/slin./, "string")
        }
        check_fails(%Q{<"string"> expected to be =~\n</strin\\./>.}) {
          assert_match("strin.", "string")
        }
        check_fails(%Q{failed assert_match.\n<"string"> expected to be =~\n</slin./>.}) {
          assert_match(/slin./, "string", "failed assert_match")
        }
      end
      
      def test_assert_same
        thing = "thing"
        check_nothing_fails {
          assert_same(thing, thing)
        }
        check_nothing_fails {
          assert_same(thing, thing, "successful assert_same")
        }
        check_nothing_fails {
          assert_same(thing, thing, "successful assert_same")
        }
        thing2 = "thing"
        check_fails(%Q{<"thing">\nwith id <#{thing.__id__}> expected to be equal? to\n<"thing">\nwith id <#{thing2.__id__}>.}) {
          assert_same(thing, thing2)
        }
        check_fails(%Q{failed assert_same.\n<"thing">\nwith id <#{thing.__id__}> expected to be equal? to\n<"thing">\nwith id <#{thing2.__id__}>.}) {
          assert_same(thing, thing2, "failed assert_same")
        }
      end
      
      def test_assert_nothing_raised
        check_nothing_fails {
          assert_nothing_raised {
            1 + 1
          }
        }
        check_nothing_fails {
          assert_nothing_raised("successful assert_nothing_raised") {
            1 + 1
          }
        }
        check_nothing_fails {
          assert_nothing_raised("successful assert_nothing_raised") {
            1 + 1
          }
        }
        check_nothing_fails {
          begin
            assert_nothing_raised(RuntimeError, StandardError, "successful assert_nothing_raised") {
              raise ZeroDivisionError.new("ArgumentError")
            }
          rescue ZeroDivisionError
          end
        }
        check_fails(%r{\AException raised:\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
          assert_nothing_raised {
            raise "Error"
          }
        }
        check_fails(%r{\Afailed assert_nothing_raised\.\nException raised:\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
          assert_nothing_raised("failed assert_nothing_raised") {
            raise "Error"
          }
        }
        check_fails(%r{\AException raised:\nClass: <RuntimeError>\nMessage: <"Error">\n---Backtrace---\n.+\n---------------\Z}m) {
          assert_nothing_raised(StandardError, RuntimeError) {
            raise "Error"
          }
        }
        check_fails("Failure.") do
          assert_nothing_raised do
            flunk("Failure")
          end
        end
      end
      
      def test_flunk
        check_fails("Flunked.") {
          flunk
        }
        check_fails("flunk message.") {
          flunk("flunk message")
        }
      end
      
      def test_assert_not_same
        thing = "thing"
        thing2 = "thing"
        check_nothing_fails {
          assert_not_same(thing, thing2)
        }
        check_nothing_fails {
          assert_not_same(thing, thing2, "message")
        }
        check_fails(%Q{<"thing">\nwith id <#{thing.__id__}> expected to not be equal? to\n<"thing">\nwith id <#{thing.__id__}>.}) {
          assert_not_same(thing, thing)
        }
        check_fails(%Q{message.\n<"thing">\nwith id <#{thing.__id__}> expected to not be equal? to\n<"thing">\nwith id <#{thing.__id__}>.}) {
          assert_not_same(thing, thing, "message")
        }
      end
      
      def test_assert_not_equal
        check_nothing_fails {
          assert_not_equal("string1", "string2")
        }
        check_nothing_fails {
          assert_not_equal("string1", "string2", "message")
        }
        check_fails(%Q{<"string"> expected to be != to\n<"string">.}) {
          assert_not_equal("string", "string")
        }
        check_fails(%Q{message.\n<"string"> expected to be != to\n<"string">.}) {
          assert_not_equal("string", "string", "message")
        }
      end
      
      def test_assert_no_match
        check_nothing_fails {
          assert_no_match(/sling/, "string")
        }
        check_nothing_fails {
          assert_no_match(/sling/, "string", "message")
        }
        check_fails(%Q{</string/> expected to not match\n<"string">.}) {
          assert_no_match(/string/, "string")
        }
        check_fails(%Q{message.\n</string/> expected to not match\n<"string">.}) {
          assert_no_match(/string/, "string", "message")
        }
      end
      
      def test_assert_throws
        check_nothing_fails {
          assert_throws(:thing, "message") {
            throw :thing
          }
        }
        check_fails("message.\n<:thing> expected to be thrown but\n<:thing2> was thrown.") {
          assert_throws(:thing, "message") {
            throw :thing2
          }
        }
        check_fails("message.\n<:thing> should have been thrown.") {
          assert_throws(:thing, "message") {
            1 + 1
          }
        }
      end
      
      def test_assert_nothing_thrown
        check_nothing_fails {
          assert_nothing_thrown("message") {
            1 + 1
          }
        }
        check_fails("message.\n<:thing> was thrown when nothing was expected.") {
          assert_nothing_thrown("message") {
            throw :thing
          }
        }
      end
      
      def test_assert_operator
        check_nothing_fails {
          assert_operator("thing", :==, "thing", "message")
        }
        check_fails(%Q{<0.15>\ngiven as the operator for #assert_operator must be a Symbol or #respond_to?(:to_str).}) do
          assert_operator("thing", 0.15, "thing")
        end
        check_fails(%Q{message.\n<"thing1"> expected to be\n==\n<"thing2">.}) {
          assert_operator("thing1", :==, "thing2", "message")
        }
      end
      
      def test_assert_respond_to
        check_nothing_fails {
          assert_respond_to("thing", :to_s, "message")
        }
        check_nothing_fails {
          assert_respond_to("thing", "to_s", "message")
        }
        check_fails("<0.15>\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to?(:to_str).") {
          assert_respond_to("thing", 0.15)
        }
        check_fails("message.\n<:symbol>\nof type <Symbol>\nexpected to respond_to?<:non_existent>.") {
          assert_respond_to(:symbol, :non_existent, "message")
        }
      end
      
      def test_assert_in_delta
        check_nothing_fails {
          assert_in_delta(1.4, 1.4, 0)
        }
        check_nothing_fails {
          assert_in_delta(0.5, 0.4, 0.1, "message")
        }
        check_nothing_fails {
          float_thing = Object.new
          def float_thing.to_f
            0.2
          end
          assert_in_delta(0.1, float_thing, 0.1)
        }
        check_fails("message.\n<0.5> and\n<0.4> expected to be within\n<0.05> of each other.") {
          assert_in_delta(0.5, 0.4, 0.05, "message")
        }
        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>.}) {
          assert_in_delta(Object.new, 0.4, 0.1)
        }
        check_fails("The delta should not be negative.\n<-0.1> expected to be\n>=\n<0.0>.") {
          assert_in_delta(0.5, 0.4, -0.1, "message")
        }
      end
      
      def test_assert_send
        object = Object.new
        class << object
          private
          def return_argument(argument, bogus)
            return argument
          end
        end
        check_nothing_fails {
          assert_send([object, :return_argument, true, "bogus"], "message")
        }
        check_fails(%r{\Amessage\.\n<.+> expected to respond to\n<return_argument\(\[false, "bogus"\]\)> with a true value.\Z}) {
          assert_send([object, :return_argument, false, "bogus"], "message")
        }
      end
      
      def test_condition_invariant
        object = Object.new
        def object.inspect
          @changed = true
        end
        def object.==(other)
          @changed ||= false
          return (!@changed)
        end
        check_nothing_fails {
          assert_equal(object, object, "message")
        }
      end
  
      def add_failure(message, location=caller)
        if (!@catch_assertions)
          super
        end
      end
      
      def add_assertion
        if (!@catch_assertions)
          super
        else
          @actual_assertion_count += 1
        end
      end
    end
  end
end