Class: Test::Mini::Assertions

Inherits:
Object
  • Object
show all
Defined in:
lib/Test/Mini/Assertions.pm

Overview

Basic Assertions for Test::Mini.

Exported Functions (collapse)

Class Method Summary (collapse)

Class Method Details

+ import($class)

Pulls all of the test-related methods into the calling package.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/Test/Mini/Assertions.pm', line 67

sub import {
    my ($class) = @_;
    my $caller = caller;

    no strict 'refs';
    *{"$caller\::count_assertions"} = \&_count_assertions;
    *{"$caller\::reset_assertions"} = \&_reset_assertions;

    my @asserts = grep { /^(assert|refute|skip$|flunk$)/ && defined &{$_} } keys %{"$class\::"};

    for my $assertion (@asserts) {
        *{"$caller\::$assertion"} = \&{$assertion};
    }
}

Instance Method Details

- assert($test, $msg)

Asserts that $test is truthy, and throws a Exception::Assert if that assertion fails.

Examples:

assert 1;

assert 'true', 'Truth should shine clear';

Parameters:

  • $test

    The value to test.

  • (String) $msg

    An optional description.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/Test/Mini/Assertions.pm', line 101

sub assert ($;$) {
    my ($test, $msg) = @_;
    $msg ||= 'Assertion failed; no message given.';
    $msg = $msg->() if ref $msg eq 'CODE';

    $assertion_count++;

    return 1 if $test;

    Test::Mini::Exception::Assert->throw(
        message        => $msg,
        ignore_package => [__PACKAGE__],
    );
}

- assert_block($block, $msg)

Deprecated.

This assertion offers little advantage over the base #assert. This will be removed in v2.0.0.

Asserts that the given code reference returns a truthy value.

Examples:

assert_block { 'true' };

assert_block \&some_sub, 'expected better from &some_sub';

Parameters:

  • (CODE) $block

    The code reference to test.

  • (String) $msg

    An optional description.



144
145
146
147
148
149
150
151
# File 'lib/Test/Mini/Assertions.pm', line 144

sub assert_block (&;$) {
    my ($block, $msg) = @_;
    warn '#assert_block is deprecated; please use #assert instead.';
    ($msg, $block) = ($block, $msg) if $msg && ref $block ne 'CODE';
    $msg = message('Expected block to return true value', $msg);
    assert_instance_of($block, 'CODE');
    assert($block->(), $msg);
}

- assert_can($obj, $method, $msg) Also known as: assert_responds_to

Verifies that the given $obj is capable of responding to the given $method name.

Examples:

assert_can $date, 'day_of_week';

assert_can $time, 'seconds', '$time cannot respond to #seconds';

Parameters:

  • $obj

    The object being tested.

  • (String) $method

    The method name being checked for.

  • (String) $msg

    An optional description.



185
186
187
188
189
# File 'lib/Test/Mini/Assertions.pm', line 185

sub assert_can ($$;$) {
    my ($obj, $method, $msg) = @_;
    $msg = message("Expected @{[inspect($obj)]} (@{[ref $obj || 'SCALAR']}) to respond to #$method", $msg);
    assert($obj->can($method), $msg);
}

- assert_contains($collection, $obj, $msg) Also known as: assert_includes

Verifies that the given $collection contains the given $obj as a member.

Examples:

assert_contains [qw/ 1 2 3 /], 2;

assert_contains { a => 'b' }, 'a';  # 'b' also contained

assert_contains 'expectorate', 'xp';

assert_contains Collection->new(1, 2, 3), 2;  # if Collection->contains(2)

Parameters:

  • (Array|Hash|String|#contains) $collection

    The collection to test.

  • $obj

    The needle to find.

  • (String) $msg

    An optional description.



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/Test/Mini/Assertions.pm', line 222

sub assert_contains ($$;$) {
    my ($collection, $obj, $msg) = @_;
    my $m = message("Expected @{[inspect($collection)]} to contain @{[inspect($obj)]}", $msg);
    if (ref $collection eq 'ARRAY') {
        my $search = any {defined $obj ? $_ eq $obj : defined $_ } @$collection;
        assert($search, $m);
    }
    elsif (ref $collection eq 'HASH') {
        &assert_contains([%$collection], $obj, $msg);
    }
    elsif (ref $collection) {
        assert_can($collection, 'contains');
        assert($collection->contains($obj), $m);
    }
    else {
        assert(index($collection, $obj) != -1, $m);
    }
}

- assert_defined($obj, $msg) Also known as: refute_undef

Validates that the given $obj is defined.

Examples:

assert_defined $value;  # if defined $value

Parameters:

  • $obj

    The value to check.

  • (String) $msg

    An optional description.



282
283
284
285
286
# File 'lib/Test/Mini/Assertions.pm', line 282

sub assert_defined ($;$) {
    my ($obj, $msg) = @_;
    $msg = message("Expected @{[inspect($obj)]} to be defined", $msg);
    assert(defined $obj, $msg);
}

- assert_dies($sub, $error, $msg)

Tests that the supplied code block dies, and fails if it succeeds. If $error is provided, the error message in $@ must contain it.

Examples:

assert_dies { die 'LAGHLAGHLAGHL' };

assert_dies { die 'Failure on line 27 in Foo.pm' } 'line 27';

Parameters:

  • (CODE) $sub

    The code that should die.

  • (String) $error

    The (optional) error substring expected.

  • (String) $msg

    An optional description.



303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/Test/Mini/Assertions.pm', line 303

sub assert_dies (&;$$) {
    my ($sub, $error, $msg) = @_;
    $error = '' unless defined $error;

    $msg = message("Expected @{[inspect($sub)]} to die matching /$error/", $msg);
    my ($full_error, $dies);
    {
        local $@;
        $dies = not eval { $sub->(); return 1; };
        $full_error = $@;
    }
    assert($dies, $msg);
    assert_contains("$full_error", $error);
}

- assert_empty($collection, $msg)

Verifies the emptiness of a collection.

Examples:

assert_empty [];

assert_empty {};

assert_empty '';

assert_empty Collection->new();  # if Collection->new()->is_empty()

Parameters:

  • (Array|Hash|String|#is_empty) $collection

    The collection under scrutiny.

  • (String) $msg

    An optional description.



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/Test/Mini/Assertions.pm', line 331

sub assert_empty ($;$) {
    my ($collection, $msg) = @_;
    $msg = message("Expected @{[inspect($collection)]} to be empty", $msg);
    if (ref $collection eq 'ARRAY') {
        refute(@$collection, $msg);
    }
    elsif (ref $collection eq 'HASH') {
        refute(keys %$collection, $msg);
    }
    elsif (ref $collection) {
        assert_can($collection, 'is_empty');
        assert($collection->is_empty(), $msg);
    }
    else {
        refute(length $collection, $msg);
    }
}

- assert_equal($actual, $expected, $msg) Also known as: assert_eq

Checks two given arguments for equality.

Examples:

assert_equal 3.000, 3;

assert_equal lc('FOO'), 'foo';

assert_equal [qw/ 1 2 3 /], [ 1, 2, 3 ];

assert_equal { a => 'eh' }, { a => 'eh' };

assert_equal Class->new(), $expected;  # if $expected->equals(Class->new())

Parameters:

  • $actual

    The value under test.

  • $expected

    The expected value.

  • (String) $msg

    An optional description.



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
# File 'lib/Test/Mini/Assertions.pm', line 404

sub assert_equal ($$;$) {
    my ($actual, $expected, $msg) = @_;
    $msg = message("Got @{[inspect($actual)]}\nnot @{[inspect($expected)]}", $msg);

    my @expected = ($expected);
    my @actual   = ($actual);

    my $passed = 1;

    while ($passed && (@actual || @expected)) {
        ($actual, $expected) = (shift(@actual), shift(@expected));

        next if ref $actual && ref $expected && refaddr($actual) == refaddr($expected);

        if (UNIVERSAL::can($expected, 'equals')) {
            $passed = $expected->equals($actual);
        }
        elsif (ref $actual eq 'ARRAY' && ref $expected eq 'ARRAY') {
            $passed = (@$actual == @$expected);
            unshift @actual, @$actual;
            unshift @expected, @$expected;
        }
        elsif (ref $actual eq 'HASH' && ref $expected eq 'HASH') {
            $passed = (keys %$actual == keys %$expected);
            unshift @actual,   map {$_, $actual->{$_}  } sort keys %$actual;
            unshift @expected, map {$_, $expected->{$_}} sort keys %$expected;
        }
        elsif (ref $actual && ref $expected) {
            $passed = (ref $actual eq ref $expected);
            unshift @actual,   [ deref($actual)   ];
            unshift @expected, [ deref($expected) ];
        }
        elsif (looks_like_number($actual) && looks_like_number($expected)) {
            $passed = ($actual == $expected);
        }
        elsif (defined $actual && defined $expected) {
            $passed = ($actual eq $expected);
        }
        else {
            $passed = !(defined $actual || defined $expected);
        }
    }

    assert($passed, $msg);
}

- assert_in_delta($actual, $expected, $delta, $msg)

Checks that the difference between $actual and $expected is less than $delta.

Examples:

assert_in_delta 1.001, 1;

assert_in_delta 104, 100, 5;

Parameters:

  • (Number) $actual

    The tested value.

  • (Number) $expected

    The static value.

  • (Number) $delta

    The expected delta. Defaults to 0.001.

  • (String) $msg

    An optional description.



524
525
526
527
528
529
530
# File 'lib/Test/Mini/Assertions.pm', line 524

sub assert_in_delta ($$;$$) {
    my ($actual, $expected, $delta, $msg) = @_;
    $delta = 0.001 unless defined $delta;
    my $n = abs($actual - $expected);
    $msg = message("Expected $actual - $expected ($n) to be < $delta", $msg);
    assert($delta >= $n, $msg);
}

- assert_in_epsilon($actual, $expected, $epsilon, $msg)

Checks that the difference between $actual and $expected is less than a given fraction of the smaller of the two numbers.

Examples:

assert_in_epsilon 22.0 / 7.0, Math::Trig::pi;

assert_in_epsilon 220, 200, 0.10

Parameters:

  • (Number) $actual

    The tested value.

  • (Number) $expected

    The static value.

  • (Number) $epsilon

    The expected tolerance factor. Defaults to 0.001.

  • (String) $msg

    An optional description.



565
566
567
568
569
570
571
572
573
574
# File 'lib/Test/Mini/Assertions.pm', line 565

sub assert_in_epsilon ($$;$$) {
    my ($actual, $expected, $epsilon, $msg) = @_;
    $epsilon = 0.001 unless defined $epsilon;
    assert_in_delta(
        $actual,
        $expected,
        min(abs($actual), abs($expected)) * $epsilon,
        $msg,
    );
}

- assert_instance_of($obj, $type, $msg)

Validates that the given object is an instance of $type.

Examples:

assert_instance_of MyApp::Person->new(), 'MyApp::Person';

Parameters:

  • $obj

    The instance to check.

  • (Class) $type

    The type to expect.

  • (String) $msg

    An optional description.

See Also:



618
619
620
621
622
# File 'lib/Test/Mini/Assertions.pm', line 618

sub assert_instance_of ($$;$) {
    my ($obj, $type, $msg) = @_;
    $msg = message("Expected @{[inspect($obj)]} to be an instance of $type, not @{[ref $obj]}", $msg);
    assert(ref $obj eq $type, $msg);
}

- assert_is_a($obj, $type, $msg) Also known as: assert_isa

Validates that $obj inherits from $type.

Examples:

assert_is_a 'Employee', 'Employee';

assert_is_a Employee->new(), 'Employee';

assert_is_a 'Employee', 'Person'; # assuming Employee->isa('Person')

assert_is_a Employee->new(), 'Person';

Parameters:

  • $obj

    The instance or class to check.

  • (Class) $type

    The expected superclass.

  • (String) $msg

    An optional description.



638
639
640
641
642
# File 'lib/Test/Mini/Assertions.pm', line 638

sub assert_is_a($$;$) {
    my ($obj, $type, $msg) = @_;
    $msg = message("Expected @{[inspect($obj)]} to inherit from $type", $msg);
    assert($obj->isa($type), $msg);
}

- assert_match($string, $pattern, $msg)

Validates that the given $string matches the given $pattern.

Examples:

assert_match 'Four score and seven years ago...', qr/score/;

Parameters:

  • (String) $string

    The string to match.

  • (Regex) $pattern

    The regular expression to match against.

  • (String) $msg

    An optional description.



656
657
658
659
660
# File 'lib/Test/Mini/Assertions.pm', line 656

sub assert_match ($$;$) {
    my ($string, $pattern, $msg) = @_;
    $msg = message("Expected qr/$pattern/ to match against @{[inspect($string)]}", $msg);
    assert($string =~ $pattern, $msg);
}

- assert_undef($obj, $msg) Also known as: refute_defined

Validates that the given $obj is undefined.

Examples:

assert_undef $value;  # if not defined $value

Parameters:

  • $obj

    The value to check.

  • (String) $msg

    An optional description.



693
694
695
696
697
# File 'lib/Test/Mini/Assertions.pm', line 693

sub assert_undef ($;$) {
    my ($obj, $msg) = @_;
    $msg = message("Expected @{[inspect($obj)]} to be undefined", $msg);
    refute(defined $obj, $msg);
}

- flunk($msg)

Causes the current test to exit immediately with a failing status.

Parameters:

  • (String) $msg

    An optional description.



717
718
719
720
721
# File 'lib/Test/Mini/Assertions.pm', line 717

sub flunk (;$) {
    my ($msg) = @_;
    $msg = 'Epic failure' unless defined $msg;
    assert(0, $msg);
}

- refute($test, $msg)

Asserts that $test is falsey, and throws a Exception::Assert if that assertion fails.

Examples:

refute 0;

refute undef, 'Deny the untruths';

Parameters:

  • $test

    The value to test.

  • (String) $msg

    An optional description.



126
127
128
129
130
# File 'lib/Test/Mini/Assertions.pm', line 126

sub refute ($;$) {
    my ($test, $msg) = @_;
    $msg ||= 'Refutation failed; no message given.';
    return assert(!$test, $msg);
}

- refute_block($block, $msg)

Deprecated.

This assertion offers little advantage over the base #refute. This will be removed in v2.0.0.

Asserts that the given code reference returns a falsey value.

Examples:

refute_block { '' };

refute_block \&some_sub, 'expected worse from &some_sub';

Parameters:

  • (CODE) $block

    The code reference to test.

  • (String) $msg

    An optional description.



165
166
167
168
169
170
171
172
# File 'lib/Test/Mini/Assertions.pm', line 165

sub refute_block (&;$) {
    my ($block, $msg) = @_;
    warn '#refute_block is deprecated; please use #refute instead.';
    ($msg, $block) = ($block, $msg) if $msg && ref $block ne 'CODE';
    $msg = message('Expected block to return false value', $msg);
    assert_instance_of($block, 'CODE');
    refute($block->(), $msg);
}

- refute_can($obj, $method, $msg) Also known as: refute_responds_to

Verifies that the given $obj is not capable of responding to the given $method name.

Examples:

refute_can $date, 'to_time';

refute_can $time, 'day', '$time cannot respond to #day';

Parameters:

  • $obj

    The object being tested.

  • (String) $method

    The method name being checked.

  • (String) $msg

    An optional description.



202
203
204
205
206
# File 'lib/Test/Mini/Assertions.pm', line 202

sub refute_can ($$;$) {
    my ($obj, $method, $msg) = @_;
    $msg = message("Expected @{[inspect($obj)]} (@{[ref $obj || 'SCALAR']}) to not respond to #$method", $msg);
    refute($obj->can($method), $msg);
}

- refute_contains($collection, $obj, $msg)

Verifies that the given $collection does not contain the given $obj as a member.

Examples:

refute_contains [qw/ 1 2 3 /], 5;

refute_contains { a => 'b' }, 'x';

refute_contains 'expectorate', 'spec';

refute_contains Collection->new(1, 2, 3), 5;  # unless Collection->contains(5)

Parameters:

  • (Array|Hash|String|#contains) $collection

    The collection to test.

  • $obj

    The needle to look for.

  • (String) $msg

    An optional description.



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/Test/Mini/Assertions.pm', line 256

sub refute_contains ($$;$) {
    my ($collection, $obj, $msg) = @_;
    my $m = message("Expected @{[inspect($collection)]} to not contain @{[inspect($obj)]}", $msg);
    if (ref $collection eq 'ARRAY') {
        my $search = any {defined $obj ? $_ eq $obj : defined $_ } @$collection;
        refute($search, $m);
    }
    elsif (ref $collection eq 'HASH') {
        &refute_contains([%$collection], $obj, $msg);
    }
    elsif (ref $collection) {
        assert_can($collection, 'contains');
        refute($collection->contains($obj), $m);
    }
    else {
        refute(index($collection, $obj) != -1, $m);
    }
}

- refute_empty($collection, $msg)

Verifies the non-emptiness of a collection.

Examples:

refute_empty [ 1 ];

refute_empty { a => 1 };

refute_empty 'full';

refute_empty Collection->new();  # unless Collection->new()->is_empty()

Parameters:

  • (Array|Hash|String|#is_empty) $collection

    The collection under scrutiny.

  • (String) $msg

    An optional description.



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/Test/Mini/Assertions.pm', line 362

sub refute_empty ($;$) {
    my ($collection, $msg) = @_;
    $msg = message("Expected @{[inspect($collection)]} to not be empty", $msg);
    if (ref $collection eq 'ARRAY') {
        assert(@$collection, $msg);
    }
    elsif (ref $collection eq 'HASH') {
        assert(keys %$collection, $msg);
    }
    elsif (ref $collection) {
        assert_can($collection, 'is_empty');
        refute($collection->is_empty(), $msg);
    }
    else {
        assert(length $collection, $msg);
    }
}

- refute_equal($actual, $unexpected, $msg) Also known as: refute_eq

Checks two given arguments for inequality.

Examples:

refute_equal 3.001, 3;

refute_equal lc('FOOL'), 'foo';

refute_equal [qw/ 1 23 /], [ 1, 2, 3 ];

refute_equal { a => 'ae' }, { a => 'eh' };

refute_equal Class->new(), $expected;  # unless $expected->equals(Class->new())

Parameters:

  • $actual

    The value under test.

  • $expected

    The tested value.

  • (String) $msg

    An optional description.



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/Test/Mini/Assertions.pm', line 466

sub refute_equal ($$;$) {
    my ($actual, $unexpected, $msg) = @_;
    $msg = message("The given values were unexpectedly equal", $msg);

    my @unexpected = ($unexpected);
    my @actual   = ($actual);

    my $passed = 1;

    while ($passed && (@actual || @unexpected)) {
        ($actual, $unexpected) = (shift(@actual), shift(@unexpected));

        next if ref $actual && ref $unexpected && refaddr($actual) == refaddr($unexpected);

        if (UNIVERSAL::can($unexpected, 'equals')) {
            $passed = $unexpected->equals($actual);
        }
        elsif (ref $actual eq 'ARRAY' && ref $unexpected eq 'ARRAY') {
            $passed = (@$actual == @$unexpected);
            unshift @actual, @$actual;
            unshift @unexpected, @$unexpected;
        }
        elsif (ref $actual eq 'HASH' && ref $unexpected eq 'HASH') {
            $passed = (keys %$actual == keys %$unexpected);
            unshift @actual, %$actual;
            unshift @unexpected, %$unexpected;
        }
        elsif (ref $actual && ref $unexpected) {
            $passed = (ref $actual eq ref $unexpected);
            unshift @actual,     [ deref($actual)   ];
            unshift @unexpected, [ deref($unexpected) ];
        }
        elsif (looks_like_number($actual) && looks_like_number($unexpected)) {
            $passed = ($actual == $unexpected);
        }
        elsif (defined $actual && defined $unexpected) {
            $passed = ($actual eq $unexpected);
        }
        else {
            $passed = !(defined $actual || defined $unexpected);
        }
    }

    refute($passed, $msg);
}

- refute_in_delta($actual, $expected, $delta, $msg)

Checks that the difference between $actual and $expected is greater than $delta.

Examples:

refute_in_delta 1.002, 1;

refute_in_delta 106, 100, 5;

Parameters:

  • (Number) $actual

    The tested value.

  • (Number) $expected

    The static value.

  • (Number) $delta

    The delta $actual and $expected are expected to differ by. Defaults to 0.001.

  • (String) $msg

    An optional description.



545
546
547
548
549
550
551
# File 'lib/Test/Mini/Assertions.pm', line 545

sub refute_in_delta ($$;$$) {
    my ($actual, $expected, $delta, $msg) = @_;
    $delta = 0.001 unless defined $delta;
    my $n = abs($actual - $expected);
    $msg = message("Expected $actual - $expected ($n) to be > $delta", $msg);
    refute($delta >= $n, $msg);
}

- refute_in_epsilon($actual, $expected, $epsilon, $msg)

Checks that the difference between $actual and $expected is greater than a given fraction of the smaller of the two numbers.

Examples:

refute_in_epsilon 21.0 / 7.0, Math::Trig::pi;

refute_in_epsilon 220, 200, 0.20

Parameters:

  • (Number) $actual

    The tested value.

  • (Number) $expected

    The static value.

  • (Number) $epsilon

    The factor by which $actual and $expected are expected to differ by. Defaults to 0.001.

  • (String) $msg

    An optional description.



589
590
591
592
593
594
595
596
597
598
# File 'lib/Test/Mini/Assertions.pm', line 589

sub refute_in_epsilon ($$;$$) {
    my ($actual, $expected, $epsilon, $msg) = @_;
    $epsilon = 0.001 unless defined $epsilon;
    refute_in_delta(
        $actual,
        $expected,
        min(abs($actual), abs($expected)) * $epsilon,
        $msg,
    );
}

- refute_match($string, $pattern, $msg)

Validates that the given $string does not match the given $pattern.

Examples:

refute_match 'Four score and seven years ago...', qr/score/;

Parameters:

  • (String) $string

    The string to match.

  • (Regex) $pattern

    The regular expression to match against.

  • (String) $msg

    An optional description.



670
671
672
673
674
# File 'lib/Test/Mini/Assertions.pm', line 670

sub refute_match ($$;$) {
    my ($string, $pattern, $msg) = @_;
    $msg = message("Expected qr/$pattern/ to fail to match against @{[inspect($string)]}", $msg);
    refute($string =~ $pattern, $msg);
}

- skip($msg)

Allows the current test to be bypassed with an indeterminate status.

Parameters:

  • (String) $msg

    An optional description.



705
706
707
708
709
710
711
712
713
# File 'lib/Test/Mini/Assertions.pm', line 705

sub skip (;$) {
    my ($msg) = @_;
    $msg = 'Test skipped; no message given.' unless defined $msg;
    $msg = $msg->() if ref $msg eq 'CODE';
    Test::Mini::Exception::Skip->throw(
        message        => $msg,
        ignore_package => [__PACKAGE__],
    );
}