http://qs1969.pair.com?node_id=593113

palette has asked for the wisdom of the Perl Monks concerning the following question:

I want to have a unit test case to check 'either or' value for a variable

is($var1,"can be either a or b","test passed");

How can this be done using Test::More
  • Comment on 'either or' value unit test case in Test::Simple or Test::More

Replies are listed 'Best First'.
Re: 'either or' value unit test case in Test::Simple or Test::More
by ikegami (Patriarch) on Jan 05, 2007 at 14:34 UTC
    # Test::Simple or Test::More ok($var eq 'a' || $var eq 'b', "test name");

    Update: map will help you avoid evaluating the expression twice. (Be careful about context.)
    ( Oops, added missing parens. Thanks shenme )

    # Test::Simple or Test::More ok((map { $_ eq 'a' || $_ eq 'b' } $var), "test name");

    Update: Or you could use a regexp.

    # Test::More like($var, qr/^(?:a|b)\z/, "test name");
Re: 'either or' value unit test case in Test::Simple or Test::More
by imp (Priest) on Jan 05, 2007 at 14:54 UTC
    You could use Test::Deep.
    use strict; use warnings; use Test::More tests => 1; use Test::Deep; cmp_deeply([1], subsetof(1,2,3));
Re: 'either or' value unit test case in Test::Simple or Test::More
by shmem (Chancellor) on Jan 05, 2007 at 14:48 UTC
    Use
    ok( $var1 eq 'foo' || $var1 eq 'bar', 'either foo or bar');

    i.e. make an expression that checks $var1 against both posibilities, and evaluates to either some true or some false value. Don't use

    is( $var1 eq 'foo' ? 1 : $var1 eq 'bar'? 1 : undef, 1, 'either foo or +bar');

    - that is syntax is explicitly discouraged in the docs. Thanks to ikegami for pointing that out via /msg.

    --shmem

    update: removed cluttered ternary op suggestion, incorporated ikegami's /msg.

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: 'either or' value unit test case in Test::Simple or Test::More
by Anonymous Monk on Jan 05, 2007 at 14:45 UTC
    ok( grep { $var1 eq $_ } qw[ a b ] , 'test name' );
Re: 'either or' value unit test case in Test::Simple or Test::More
by Tanktalus (Canon) on Jan 05, 2007 at 15:42 UTC

    Here's one that works in theory, but, in practice, doesn't. (I wonder if the Test::Builder owner would want to fix this ... probably not.)

    use Quantum::Superpositions; is($var, any('a', 'b'), "it's a or b");
    The idea is that you should be able to do this comparison ... but Test::Builder::_unoverload_str is used to convert the object that any returns into a string ... and that kills all the magic.

Re: 'either or' value unit test case in Test::Simple or Test::More
by grinder (Bishop) on Jan 05, 2007 at 16:23 UTC

    I would write that as separate pass calls, which allows you to see which one matched.

    if ($var eq 'a') { pass( 'var is an a' ); } elsif ($var eq 'b') { pass( 'var is a b' ); } else { fail( "var was $var" ); }

    Be careful here and don't go too tricky in the code flow, otherwise you may end up with a pass() in one branch, and nothing in the other, which will lead to strange off-by-one errors in the test plan. KISS.

    • another intruder with the mooring in the heart of the Perl

      What about an overkill abstract solution?

      # is_one_of($val, \@list); sub is_one_of { my $val = shift; my $list = shift; my $test_name = "$val is not one of @$list"; for (@$list) { pass($test_name), return if $val eq $_; } diag "never saw [$val] in [@$list]"; fail($test_name); }

      And then palette may say:

      is_one_of($var, [ qw(a b) ]);

      Update: fixed after grinder's commentreturn and diag added.

        If $list winds up with duplicate values that match $val, your plan is in big trouble. I would change that to

        for (@$list) { if ($val eq $_) { pass($test_name); return; } } diag "never saw [$val] in [@$list]"; fail($test_name);

        • another intruder with the mooring in the heart of the Perl