minitest 4.7.5 → 5.0.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.
@@ -0,0 +1,643 @@
1
+ require "rbconfig"
2
+
3
+ module Minitest
4
+ ##
5
+ # Minitest Assertions. All assertion methods accept a +msg+ which is
6
+ # printed if the assertion fails.
7
+
8
+ module Assertions
9
+ UNDEFINED = Object.new # :nodoc:
10
+
11
+ def UNDEFINED.inspect # :nodoc:
12
+ "UNDEFINED" # again with the rdoc bugs... :(
13
+ end
14
+
15
+ ##
16
+ # Returns the diff command to use in #diff. Tries to intelligently
17
+ # figure out what diff to use.
18
+
19
+ def self.diff
20
+ @diff = if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ &&
21
+ system("diff.exe", __FILE__, __FILE__)) then
22
+ "diff.exe -u"
23
+ elsif Minitest::Test.maglev? then
24
+ "diff -u"
25
+ elsif system("gdiff", __FILE__, __FILE__)
26
+ "gdiff -u" # solaris and kin suck
27
+ elsif system("diff", __FILE__, __FILE__)
28
+ "diff -u"
29
+ else
30
+ nil
31
+ end unless defined? @diff
32
+
33
+ @diff
34
+ end
35
+
36
+ ##
37
+ # Set the diff command to use in #diff.
38
+
39
+ def self.diff= o
40
+ @diff = o
41
+ end
42
+
43
+ ##
44
+ # Returns a diff between +exp+ and +act+. If there is no known
45
+ # diff command or if it doesn't make sense to diff the output
46
+ # (single line, short output), then it simply returns a basic
47
+ # comparison between the two.
48
+
49
+ def diff exp, act
50
+ require "tempfile"
51
+
52
+ expect = mu_pp_for_diff exp
53
+ butwas = mu_pp_for_diff act
54
+ result = nil
55
+
56
+ need_to_diff =
57
+ Minitest::Assertions.diff &&
58
+ (expect.include?("\n") ||
59
+ butwas.include?("\n") ||
60
+ expect.size > 30 ||
61
+ butwas.size > 30 ||
62
+ expect == butwas)
63
+
64
+ return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless
65
+ need_to_diff
66
+
67
+ Tempfile.open("expect") do |a|
68
+ a.puts expect
69
+ a.flush
70
+
71
+ Tempfile.open("butwas") do |b|
72
+ b.puts butwas
73
+ b.flush
74
+
75
+ result = `#{Minitest::Assertions.diff} #{a.path} #{b.path}`
76
+ result.sub!(/^\-\-\- .+/, "--- expected")
77
+ result.sub!(/^\+\+\+ .+/, "+++ actual")
78
+
79
+ if result.empty? then
80
+ klass = exp.class
81
+ result = [
82
+ "No visible difference in the #{klass}#inspect output.\n",
83
+ "You should look at the implementation of #== on ",
84
+ "#{klass} or its members.\n",
85
+ expect,
86
+ ].join
87
+ end
88
+ end
89
+ end
90
+
91
+ result
92
+ end
93
+
94
+ ##
95
+ # This returns a human-readable version of +obj+. By default
96
+ # #inspect is called. You can override this to use #pretty_print
97
+ # if you want.
98
+
99
+ def mu_pp obj
100
+ s = obj.inspect
101
+ s = s.encode Encoding.default_external if defined? Encoding
102
+ s
103
+ end
104
+
105
+ ##
106
+ # This returns a diff-able human-readable version of +obj+. This
107
+ # differs from the regular mu_pp because it expands escaped
108
+ # newlines and makes hex-values generic (like object_ids). This
109
+ # uses mu_pp to do the first pass and then cleans it up.
110
+
111
+ def mu_pp_for_diff obj
112
+ mu_pp(obj).gsub(/\\n/, "\n").gsub(/:0x[a-fA-F0-9]{4,}/m, ':0xXXXXXX')
113
+ end
114
+
115
+ ##
116
+ # Fails unless +test+ is truthy.
117
+
118
+ def assert test, msg = nil
119
+ msg ||= "Failed assertion, no message given."
120
+ self.assertions += 1
121
+ unless test then
122
+ msg = msg.call if Proc === msg
123
+ raise Minitest::Assertion, msg
124
+ end
125
+ true
126
+ end
127
+
128
+ ##
129
+ # Fails unless +obj+ is empty.
130
+
131
+ def assert_empty obj, msg = nil
132
+ msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" }
133
+ assert_respond_to obj, :empty?
134
+ assert obj.empty?, msg
135
+ end
136
+
137
+ ##
138
+ # Fails unless <tt>exp == act</tt> printing the difference between
139
+ # the two, if possible.
140
+ #
141
+ # If there is no visible difference but the assertion fails, you
142
+ # should suspect that your #== is buggy, or your inspect output is
143
+ # missing crucial details.
144
+ #
145
+ # For floats use assert_in_delta.
146
+ #
147
+ # See also: Minitest::Assertions.diff
148
+
149
+ def assert_equal exp, act, msg = nil
150
+ msg = message(msg, "") { diff exp, act }
151
+ assert exp == act, msg
152
+ end
153
+
154
+ ##
155
+ # For comparing Floats. Fails unless +exp+ and +act+ are within +delta+
156
+ # of each other.
157
+ #
158
+ # assert_in_delta Math::PI, (22.0 / 7.0), 0.01
159
+
160
+ def assert_in_delta exp, act, delta = 0.001, msg = nil
161
+ n = (exp - act).abs
162
+ msg = message(msg) {
163
+ "Expected |#{exp} - #{act}| (#{n}) to be <= #{delta}"
164
+ }
165
+ assert delta >= n, msg
166
+ end
167
+
168
+ ##
169
+ # For comparing Floats. Fails unless +exp+ and +act+ have a relative
170
+ # error less than +epsilon+.
171
+
172
+ def assert_in_epsilon a, b, epsilon = 0.001, msg = nil
173
+ assert_in_delta a, b, [a.abs, b.abs].min * epsilon, msg
174
+ end
175
+
176
+ ##
177
+ # Fails unless +collection+ includes +obj+.
178
+
179
+ def assert_includes collection, obj, msg = nil
180
+ msg = message(msg) {
181
+ "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}"
182
+ }
183
+ assert_respond_to collection, :include?
184
+ assert collection.include?(obj), msg
185
+ end
186
+
187
+ ##
188
+ # Fails unless +obj+ is an instance of +cls+.
189
+
190
+ def assert_instance_of cls, obj, msg = nil
191
+ msg = message(msg) {
192
+ "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}"
193
+ }
194
+
195
+ assert obj.instance_of?(cls), msg
196
+ end
197
+
198
+ ##
199
+ # Fails unless +obj+ is a kind of +cls+.
200
+
201
+ def assert_kind_of cls, obj, msg = nil
202
+ msg = message(msg) {
203
+ "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }
204
+
205
+ assert obj.kind_of?(cls), msg
206
+ end
207
+
208
+ ##
209
+ # Fails unless +matcher+ <tt>=~</tt> +obj+.
210
+
211
+ def assert_match matcher, obj, msg = nil
212
+ msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" }
213
+ assert_respond_to matcher, :"=~"
214
+ matcher = Regexp.new Regexp.escape matcher if String === matcher
215
+ assert matcher =~ obj, msg
216
+ end
217
+
218
+ ##
219
+ # Fails unless +obj+ is nil
220
+
221
+ def assert_nil obj, msg = nil
222
+ msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
223
+ assert obj.nil?, msg
224
+ end
225
+
226
+ ##
227
+ # For testing with binary operators. Eg:
228
+ #
229
+ # assert_operator 5, :<=, 4
230
+
231
+ def assert_operator o1, op, o2 = UNDEFINED, msg = nil
232
+ return assert_predicate o1, op, msg if UNDEFINED == o2
233
+ msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
234
+ assert o1.__send__(op, o2), msg
235
+ end
236
+
237
+ ##
238
+ # Fails if stdout or stderr do not output the expected results.
239
+ # Pass in nil if you don't care about that streams output. Pass in
240
+ # "" if you require it to be silent. Pass in a regexp if you want
241
+ # to pattern match.
242
+ #
243
+ # NOTE: this uses #capture_io, not #capture_subprocess_io.
244
+ #
245
+ # See also: #assert_silent
246
+
247
+ def assert_output stdout = nil, stderr = nil
248
+ out, err = capture_io do
249
+ yield
250
+ end
251
+
252
+ err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr
253
+ out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout
254
+
255
+ y = send err_msg, stderr, err, "In stderr" if err_msg
256
+ x = send out_msg, stdout, out, "In stdout" if out_msg
257
+
258
+ (!stdout || x) && (!stderr || y)
259
+ end
260
+
261
+ ##
262
+ # For testing with predicates. Eg:
263
+ #
264
+ # assert_predicate str, :empty?
265
+ #
266
+ # This is really meant for specs and is front-ended by assert_operator:
267
+ #
268
+ # str.must_be :empty?
269
+
270
+ def assert_predicate o1, op, msg = nil
271
+ msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" }
272
+ assert o1.__send__(op), msg
273
+ end
274
+
275
+ ##
276
+ # Fails unless the block raises one of +exp+. Returns the
277
+ # exception matched so you can check the message, attributes, etc.
278
+
279
+ def assert_raises *exp
280
+ msg = "#{exp.pop}.\n" if String === exp.last
281
+
282
+ begin
283
+ yield
284
+ rescue Minitest::Skip => e
285
+ return e if exp.include? Minitest::Skip
286
+ raise e
287
+ rescue Exception => e
288
+ expected = exp.any? { |ex|
289
+ if ex.instance_of? Module then
290
+ e.kind_of? ex
291
+ else
292
+ e.instance_of? ex
293
+ end
294
+ }
295
+
296
+ assert expected, proc {
297
+ exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not")
298
+ }
299
+
300
+ return e
301
+ end
302
+
303
+ exp = exp.first if exp.size == 1
304
+
305
+ flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised."
306
+ end
307
+
308
+ ##
309
+ # Fails unless +obj+ responds to +meth+.
310
+
311
+ def assert_respond_to obj, meth, msg = nil
312
+ msg = message(msg) {
313
+ "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
314
+ }
315
+ assert obj.respond_to?(meth), msg
316
+ end
317
+
318
+ ##
319
+ # Fails unless +exp+ and +act+ are #equal?
320
+
321
+ def assert_same exp, act, msg = nil
322
+ msg = message(msg) {
323
+ data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
324
+ "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data
325
+ }
326
+ assert exp.equal?(act), msg
327
+ end
328
+
329
+ ##
330
+ # +send_ary+ is a receiver, message and arguments.
331
+ #
332
+ # Fails unless the call returns a true value
333
+
334
+ def assert_send send_ary, m = nil
335
+ recv, msg, *args = send_ary
336
+ m = message(m) {
337
+ "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
338
+ assert recv.__send__(msg, *args), m
339
+ end
340
+
341
+ ##
342
+ # Fails if the block outputs anything to stderr or stdout.
343
+ #
344
+ # See also: #assert_output
345
+
346
+ def assert_silent
347
+ assert_output "", "" do
348
+ yield
349
+ end
350
+ end
351
+
352
+ ##
353
+ # Fails unless the block throws +sym+
354
+
355
+ def assert_throws sym, msg = nil
356
+ default = "Expected #{mu_pp(sym)} to have been thrown"
357
+ caught = true
358
+ catch(sym) do
359
+ begin
360
+ yield
361
+ rescue ThreadError => e # wtf?!? 1.8 + threads == suck
362
+ default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
363
+ rescue ArgumentError => e # 1.9 exception
364
+ default += ", not #{e.message.split(/ /).last}"
365
+ rescue NameError => e # 1.8 exception
366
+ default += ", not #{e.name.inspect}"
367
+ end
368
+ caught = false
369
+ end
370
+
371
+ assert caught, message(msg) { default }
372
+ end
373
+
374
+ ##
375
+ # Captures $stdout and $stderr into strings:
376
+ #
377
+ # out, err = capture_io do
378
+ # puts "Some info"
379
+ # warn "You did a bad thing"
380
+ # end
381
+ #
382
+ # assert_match %r%info%, out
383
+ # assert_match %r%bad%, err
384
+ #
385
+ # NOTE: For efficiency, this method uses StringIO and does not
386
+ # capture IO for subprocesses. Use #capture_subprocess_io for
387
+ # that.
388
+
389
+ def capture_io
390
+ require 'stringio'
391
+
392
+ captured_stdout, captured_stderr = StringIO.new, StringIO.new
393
+
394
+ orig_stdout, orig_stderr = $stdout, $stderr
395
+ $stdout, $stderr = captured_stdout, captured_stderr
396
+
397
+ yield
398
+
399
+ return captured_stdout.string, captured_stderr.string
400
+ ensure
401
+ $stdout = orig_stdout
402
+ $stderr = orig_stderr
403
+ end
404
+
405
+ ##
406
+ # Captures $stdout and $stderr into strings, using Tempfile to
407
+ # ensure that subprocess IO is captured as well.
408
+ #
409
+ # out, err = capture_subprocess_io do
410
+ # system "echo Some info"
411
+ # system "echo You did a bad thing 1>&2"
412
+ # end
413
+ #
414
+ # assert_match %r%info%, out
415
+ # assert_match %r%bad%, err
416
+ #
417
+ # NOTE: This method is approximately 10x slower than #capture_io so
418
+ # only use it when you need to test the output of a subprocess.
419
+
420
+ def capture_subprocess_io
421
+ require 'tempfile'
422
+
423
+ captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
424
+
425
+ orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
426
+ $stdout.reopen captured_stdout
427
+ $stderr.reopen captured_stderr
428
+
429
+ yield
430
+
431
+ $stdout.rewind
432
+ $stderr.rewind
433
+
434
+ return captured_stdout.read, captured_stderr.read
435
+ ensure
436
+ captured_stdout.unlink
437
+ captured_stderr.unlink
438
+ $stdout.reopen orig_stdout
439
+ $stderr.reopen orig_stderr
440
+ end
441
+
442
+ ##
443
+ # Returns details for exception +e+
444
+
445
+ def exception_details e, msg
446
+ [
447
+ "#{msg}",
448
+ "Class: <#{e.class}>",
449
+ "Message: <#{e.message.inspect}>",
450
+ "---Backtrace---",
451
+ "#{Minitest::filter_backtrace(e.backtrace).join("\n")}",
452
+ "---------------",
453
+ ].join "\n"
454
+ end
455
+
456
+ ##
457
+ # Fails with +msg+
458
+
459
+ def flunk msg = nil
460
+ msg ||= "Epic Fail!"
461
+ assert false, msg
462
+ end
463
+
464
+ ##
465
+ # Returns a proc that will output +msg+ along with the default message.
466
+
467
+ def message msg = nil, ending = ".", &default
468
+ proc {
469
+ msg = msg.call.chomp(".") if Proc === msg
470
+ custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty?
471
+ "#{custom_message}#{default.call}#{ending}"
472
+ }
473
+ end
474
+
475
+ ##
476
+ # used for counting assertions
477
+
478
+ def pass msg = nil
479
+ assert true
480
+ end
481
+
482
+ ##
483
+ # Fails if +test+ is truthy.
484
+
485
+ def refute test, msg = nil
486
+ msg ||= "Failed refutation, no message given"
487
+ not assert(! test, msg)
488
+ end
489
+
490
+ ##
491
+ # Fails if +obj+ is empty.
492
+
493
+ def refute_empty obj, msg = nil
494
+ msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
495
+ assert_respond_to obj, :empty?
496
+ refute obj.empty?, msg
497
+ end
498
+
499
+ ##
500
+ # Fails if <tt>exp == act</tt>.
501
+ #
502
+ # For floats use refute_in_delta.
503
+
504
+ def refute_equal exp, act, msg = nil
505
+ msg = message(msg) {
506
+ "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}"
507
+ }
508
+ refute exp == act, msg
509
+ end
510
+
511
+ ##
512
+ # For comparing Floats. Fails if +exp+ is within +delta+ of +act+.
513
+ #
514
+ # refute_in_delta Math::PI, (22.0 / 7.0)
515
+
516
+ def refute_in_delta exp, act, delta = 0.001, msg = nil
517
+ n = (exp - act).abs
518
+ msg = message(msg) {
519
+ "Expected |#{exp} - #{act}| (#{n}) to not be <= #{delta}"
520
+ }
521
+ refute delta >= n, msg
522
+ end
523
+
524
+ ##
525
+ # For comparing Floats. Fails if +exp+ and +act+ have a relative error
526
+ # less than +epsilon+.
527
+
528
+ def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
529
+ refute_in_delta a, b, a * epsilon, msg
530
+ end
531
+
532
+ ##
533
+ # Fails if +collection+ includes +obj+.
534
+
535
+ def refute_includes collection, obj, msg = nil
536
+ msg = message(msg) {
537
+ "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}"
538
+ }
539
+ assert_respond_to collection, :include?
540
+ refute collection.include?(obj), msg
541
+ end
542
+
543
+ ##
544
+ # Fails if +obj+ is an instance of +cls+.
545
+
546
+ def refute_instance_of cls, obj, msg = nil
547
+ msg = message(msg) {
548
+ "Expected #{mu_pp(obj)} to not be an instance of #{cls}"
549
+ }
550
+ refute obj.instance_of?(cls), msg
551
+ end
552
+
553
+ ##
554
+ # Fails if +obj+ is a kind of +cls+.
555
+
556
+ def refute_kind_of cls, obj, msg = nil
557
+ msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
558
+ refute obj.kind_of?(cls), msg
559
+ end
560
+
561
+ ##
562
+ # Fails if +matcher+ <tt>=~</tt> +obj+.
563
+
564
+ def refute_match matcher, obj, msg = nil
565
+ msg = message(msg) {"Expected #{mu_pp matcher} to not match #{mu_pp obj}"}
566
+ assert_respond_to matcher, :"=~"
567
+ matcher = Regexp.new Regexp.escape matcher if String === matcher
568
+ refute matcher =~ obj, msg
569
+ end
570
+
571
+ ##
572
+ # Fails if +obj+ is nil.
573
+
574
+ def refute_nil obj, msg = nil
575
+ msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
576
+ refute obj.nil?, msg
577
+ end
578
+
579
+ ##
580
+ # Fails if +o1+ is not +op+ +o2+. Eg:
581
+ #
582
+ # refute_operator 1, :>, 2 #=> pass
583
+ # refute_operator 1, :<, 2 #=> fail
584
+
585
+ def refute_operator o1, op, o2 = UNDEFINED, msg = nil
586
+ return refute_predicate o1, op, msg if UNDEFINED == o2
587
+ msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}"}
588
+ refute o1.__send__(op, o2), msg
589
+ end
590
+
591
+ ##
592
+ # For testing with predicates.
593
+ #
594
+ # refute_predicate str, :empty?
595
+ #
596
+ # This is really meant for specs and is front-ended by refute_operator:
597
+ #
598
+ # str.wont_be :empty?
599
+
600
+ def refute_predicate o1, op, msg = nil
601
+ msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" }
602
+ refute o1.__send__(op), msg
603
+ end
604
+
605
+ ##
606
+ # Fails if +obj+ responds to the message +meth+.
607
+
608
+ def refute_respond_to obj, meth, msg = nil
609
+ msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
610
+
611
+ refute obj.respond_to?(meth), msg
612
+ end
613
+
614
+ ##
615
+ # Fails if +exp+ is the same (by object identity) as +act+.
616
+
617
+ def refute_same exp, act, msg = nil
618
+ msg = message(msg) {
619
+ data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
620
+ "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data
621
+ }
622
+ refute exp.equal?(act), msg
623
+ end
624
+
625
+ ##
626
+ # Skips the current run. If run in verbose-mode, the skipped run
627
+ # gets listed at the end of the run but doesn't cause a failure
628
+ # exit code.
629
+
630
+ def skip msg = nil, bt = caller
631
+ msg ||= "Skipped, no message given"
632
+ @skip = true
633
+ raise Minitest::Skip, msg, bt
634
+ end
635
+
636
+ ##
637
+ # Was this testcase skipped? Meant for #teardown.
638
+
639
+ def skipped?
640
+ defined?(@skip) and @skip
641
+ end
642
+ end
643
+ end