NAME

    Test::Toolbox - tools for testing

SYNOPSIS

     # load module
     use Test::Toolbox;
     
     # plan tests
     rtplan 43;
     
     # or, plan tests, but die on the first failure
     rtplan 43, autodie=>1;
     
     # basic test
     rtok 'my test name', $success;
    
     # test for failure if you prefer
     rtok 'test name', $success, should=>0;
    
     # two values should equal each other
     rtcomp 'test name', $val, $other_val;
     
     # two values should not equal each other
     rtcomp 'test name', $val, $other_val, should=>0;
     
     # run some code which should succeed
     # note that the second param is undef
     rteval 'test name', undef, sub { mysub() };
     
     # run some code which should cause a specific error code
     rteval 'test name', 'file-open-failed', sub { mysub() };
     
     # check that $@ has a specific error code
     rtid 'test name', $@, 'missing-keys';
     
     # much more

OVERVIEW

    Test::Toolbox provides (as you might guess) tools for automated
    testing. Test::Toolbox is much like some other testing modules, such as
    Test::More and Test::Simple. Test::Toolbox provides a different flavor
    of tests which may or may not actually be to your preference.

    The tools in Test::Toolbox have a standard format. Commands start with
    (the command (of course), followed by the test name. Then there is
    usually the value being tested, or values being compared, then other
    options. So, for example, this command checks compares two values:

     rtcomp 'test name', $val, $other_val;

    In some cases it's preferable to flip the logic of the test, so that,
    for example, two values should not be the same. In that case, you can
    add the should option:

     rtcomp 'test name', $val, $other_val, should=>0;

    All test commands require a test name as the first param.

Meta commands

 go_script_dir()

    go_script_dir() changes to the directory that the script is running in.
    This can be handy of your test script needs to read files that are part
    of your tests. go_script_dir() takes no params:

     go_script_dir();

 rtplan()

    rtplan() indicates how many tests you plan on running. Like with other
    test modules, failing to run exactly that many tests is itself
    considered on error. So, this command plans on running exactly 43
    tests.

     rtplan 43;

    You might prefer that your script dies on the first failure. In that
    case add the autodie option:

     rtplan 43, autodie=>1;

 rtcounts()

    rtcounts() returns a hashref of the test counts so far. The hashref has
    the following elements:

      * success: number of successful tests so far.

      * fail: number of failed tests so far.

      * sofar: total number of tests so far.

      * planned: total number of planned tests.

Test commands

 rtok()

    rtok() is the basic command of Test::Toolbox. It requires two params,
    the name of the test, and a scalar indicating success (true) or failure
    (false). So, this simple command indicates a successful test:

     rtok 'my test', 1;

    You might prefer to flip the logic, so that false indicates success.
    For that, use the should option:

     rtok 'my test', $val, should=>0;

    All other test command call rtok().

 rtcomp()

    rtcomp() compares the string value of two values. It sets success if
    they are the same, failure if thet are different. Its simplest use
    would be like this:

     rtcomp 'my test', $first, $second;

    As with other commands, you can flip the logic of the command so that
    success is if they are not the same:

     rtcomp 'my test', $first, $second, should=>0;

    rtcomp() interprets undef as matching undef, so the following test
    would would be successful.

     rtcomp 'my test', undef, undef;

    rtcomp() takes several options.

      * collapse

      If this option is true, then the strings are collapsed before they
      are compared. So, for example, the following test would succeed:

       rtcomp 'my test', ' Fred ', 'Fred', collapse=>1;

      * nospace

      nospace removes all spaces before comparing strings. So this test
      would succeed:

       rtcomp 'my test', 'Fr   ed', 'Fred', nospace=>1;

      * case_insensitive

      The case_insensitive option indicates to compare the values case
      insensitively. So, the following test would be successful.

 rtelcount

    Checks if an array has the correct number of elements. The first param
    is an integer 0 or greater. The second param is an array reference. So,
    the following test would pass:

     rtelcount 'my test', 3, \@arr;

 rtarr

    rtarr compares two arrays. In its simplest use, the test passes if they
    are identical:

     @first = qw{Larry Curly Moe};
     @second = qw{Larry Curly Moe};
     rtarr 'my test', \@first, \@second;

    Like with rtcomp, two undefs are considered the same, so the following
    test would pass.

     @first = ('Larry', 'Moe', 'Curly', undef);
     @second = ('Larry', 'Moe', 'Curly', undef);
     rtarr 'my test', \@first, \@second;

    rtarr takes several options.

      * order_insensitive

      If the order_insensitive option is true, then the arrays are
      considered the same even if the elements are not in the same order.
      So the following test would pass:

       @first = ('Curly', 'Larry', 'Moe');
       @second = ('Larry', 'Moe', 'Curly');
       rtarr 'my test', \@first, \@second, order_insensitive=>1;

      * case_insensitive

      If the case_insensitive option is true, then the elements are
      compared case insensitively. So the following test would pass:

       @first = ('CURLY', 'LARRY', undef, 'MOE');
       @second = ('Curly', 'Larry', undef, 'Moe');
       rtarr 'my test', \@first, \@second, case_insensitive=>1;

 rthash

    rthash checks is two hashes contain the same keys and values. The
    following test would pass. Keep in mind that hashes don't have the
    concept of order, so it doesn't matter that the hashes are created with
    differently ordered keys.

     %first = ( Curly=>'big hair', Moe=>'flat hair', Schemp=>undef);
     %second = ( Moe=>'flat hair', Schemp=>undef, Curly=>'big hair');
     rthash 'my test', \%first, \%second;

    rthash doesn't currently have a case_insensitive option. That will
    probably be added in future releases.

 rtisa

    rtisa tests if a given value is of the given class. For example, the
    following test would pass.

     $val = [];
     rtisa 'my test', $val, 'ARRAY';

    The second value can be either the name of the class or an example of
    the class, so the following test would also pass.

     $val = [];
     rtisa 'my test', $val, [];

    If the class is undef or an empty string, then rtisa returns true if
    the given object is not a reference.

     $val = 'whatever';
     rtisa 'my test', $val, '';

 rtbool

    rtbool checks if two values have the same boolean value, that is, if
    they are both true or both false. Booleans are checked in the perlish
    sense, so the values don't have to be the same, they just have to have
    the same perlish boolean values. Here are some examples.

     rtbool 'my test', 'whatever', 'dude'; # passes
     rtbool 'my test', 'whatever', 1;      # passes
     rtbool 'my test', 'whatever', undef;  # fails
     rtbool 'my test', 0, undef;           # passes

 rtdef

    rtdef tests if the given value is defined. The second param is the
    value being tested, the third param is if the value should be defined
    or not. So, the following tests would pass.

     rtdef 'my test', 'hello', 1;
     rtdef 'my test', undef, 0;

    The third param must be defined.

 rtrx

    rtrx tests if the given value matches the given regular expression. The
    following test would pass.

     rtrx 'my test', 'Fred', 'red';

    If you want to get fancy with your regular expressions, use qr// to
    create the regexes as you pass them in. The following test is an
    example.

     rtrx 'my test', 'Fred', qr/RED$/i;

 rtfile

    rtfile tests if the given file path exists. In its simplest use, rtfile
    takes just the name of the file and the path:

     rtfile 'my test', '/tmp/log.txt';

    You can use the should option to test if the file doesn't exist:

     rtfile 'my test', '/tmp/log.txt', should=>0;

Message ID tests

    The following tests checking for errors that begin with an error code,
    followed by a colon, followed by plain language. For example:

     croak 'error-opening-log-file: error opening log file';

    Note that the error ID must be followed by a colon.

 rtid()

    rtid() checks if the given string starts with the given id. For
    example, to test is $! starts with the id 'error-opening-log-file' you
    would use this command:

     rtid 'my test', $!, 'error-opening-log-file';

 rteval()

    rteval() allows you to test some code then check for an error id, all
    in one easy command. rteval runs the given subroutine in an eval{}
    block, then tests Here's an (admittedly contrived) example:

     rteval
       'my test',
       sub { die 'error-opening-log-file: whatever' },
       'error-opening-log-file';

    If your subroutine is really long, you might prefer to put the id as
    the first param, then the sub. rteval() provides some forgivness in
    that regard: if the second param is a sub, then the first param is
    assumed to be the id. So the following example works the same as the
    above example:

     rteval
       'my test',
       'error-opening-log-file',
       sub { die 'error-opening-log-file: whatever' };

    If the sub is supposed to work, you can put undef for the expected
    code:

     rteval
       'my test',
       sub { my $val = 1 },
       undef;

TERMS AND CONDITIONS

    Copyright (c) 2016 by Miko O'Sullivan. All rights reserved. This
    program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself. This software comes with NO
    WARRANTY of any kind.

AUTHOR

    Miko O'Sullivan miko@idocs.com

VERSION

    Version: 0.01

HISTORY

      * Version 0.01 Aug 21, 2016

      Initial release.

      * Version 0.02 Aug 23, 2016

      Fixed dependency problem. Should not have been using String::Util.