minitest 5.11.2

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