Kevin Connor <[EMAIL PROTECTED]> writes:
> I posted this to the bug forum but thought I should do it here too.
>
> Summary: When the condition is blank (empty string), the test will pass
> although it shouldn't. m// returns an empty string on no match.
>
> JUnit 3.5 has
> assert(message, condition);
>
> perlUnit .13 has
> assert(condition, message);
>
> There's a problem with empty string parameters and that's probably why
> the parameters were
> reversed. However, I ran into the problem using the current order.
>
> Using the fail-example provided, the test that fails is "born" =~
> /loose/.
> assert("born" =~ /loose/, "Born to lose ...");
> For some reason this works as expected.
> However, the following doesn't (the Test::Unit::TestCase variation):
> $self->assert("born" =~ /loose/, "Born to lose ...");
> but this will:
> $self->assert(scalar "born" =~ /loose/, "Born to lose ...");
>
> The doc for m// states "if there is no match, a false value ("") is
> returned". This being an empty string results in only the message being
> passed as a parameter which is always true and so the test doesn't fail
> as it should.
Err... you're wrong. The important section of the docs reads:
If the `/g' option is not used, `m//' in list
context returns a list consisting of the
subexpressions matched by the parentheses in the
pattern, i.e., (`$1', `$2', `$3'...). (Note that
here `$1' etc. are also set, and that this differs
from Perl 4's behavior.) When there are no
parentheses in the pattern, the return value is
the list `(1)' for success. With or without
parentheses, an empty list is returned upon
failure.
And what do you know, we're in a list context. Which means that
assert("born" =~ /loose/, "Born to lose");
becomes
assert((), "Born to lose")
which in turn becomes
assert("Born to lose")
And, in a boolean context, "Born to lose" is true. So the test passes.
Which is bad. And which is why the latest version in CVS uses typed
assertions to allow us to do:
$self->assert(qr/loose/, "born");
(Sadly this version doesn't yet allow us to add a message, but that's
easily fixable...)
> Anyway, this is a bad situation. Maybe assert should have a prototype
> requiring two params? If the condition is second the test will always
> fail if no message is given. I think this is preferable to the current
> state where the test will pass if there's an empty condition and a given
> message when it should fail.
You can't prototype methods in Perl. Which is a shame, as even runtime
enforcement (which is all that would be possible with current Perl)
would be good. (You could probably do something with subroutine
attribs, but that'd be scary...)
--
Piers
_______________________________________________
Perlunit-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/perlunit-devel