Matthew Astley <[EMAIL PROTECTED]> writes:
> On Tue, Mar 06, 2001 at 11:59:40AM +0000, Piers Cawley wrote:
> > Matthew Astley <[EMAIL PROTECTED]> writes:
>
> [comparisons]
>
> > I'd definitely rather do the Right Thing. And the Right Thing is to
> > use the appropriate comparators.
>
> Exactly. It's inconvenient, but Right.
>
>
> > > Yes, that does it for me too, except my next reaction was "Ah, so we
> > > can reuse the routines that 'sort' takes?" .. then "oh, the sense is
> > > wrong".
> >
> > Hmm... can't see anything wrong with doing:
> >
> > T:U:A:CodeRef::do_assert {
> > my $self = shift;
> > local($a, $b) = @_[0,1];
> > ...
> > }
>
> Well it's not much use in do_assert, although if it were in the
> opposite one then it would make sense to be symmetrical.
I've just noticed we've changed the name of the message. In the code
it's C<do_assertion>
>
> > Which would mean that the kind of blocks that sort takes would work
> > with the CodeRef assertions. But that could be taken to be rather more
> > DWIM magic than is good for a framework. Especially one that's
> > claiming to be all grown up and OO.
>
> I'm inclined to give sort-blocks separate namespace, and this is a
> good reason. It doesn't take too much sugar...
>
> $self->assert(new Test::Unit::Assertion::SortBlock sub { $a cmp $b },
>
> also the arguments can then be tailored, so while
>
> , $foo, $bar)
>
> would be quite restrictive,
>
> , [$foo, $bar], [$wibble, $spong])
>
> would be quite powerful. Mixing the two would be confusing!
>
> (spot the solution looking for a problem again, though)
I think you're adding complexity where there's no need for it.
$self->assert(sub {...}, [$foo, $bar], [$wibble, $spong])
will already work. Given that we've already got $a and $b as special
cased variable names, then being nice and assigning the first two
values in @_ to $a and $b means that we allow MTOWTDI without forcing
the user to instantiate another class and they get to do:
$self->assert(sub {$a eq $b}, $foo, $bar);
or
$self->assert(sub {$_[0] eq $_[1]}, $foo, $bar);
as they choose and it Just Works. Which is nice.
> > > Is it too complicated to allow our coderef objects to implement a
> > > "do_failif" method instead of the "do_assert" ?
> >
> > The problem I see with 'do_failif' and an associated 'failif'
> > mechanism is that of deriving meaningful failure messages for
> > arbitrary coderefs. Not that this would necessarily be a problem...
>
> You code can still die ... ahhh. I've been doing quite a lot of "eval
> this code and make sure it dies with an error matching qr//"
>
> I suspect this, like Adam says, is a time to roll my own assertion
> classes outside the T:U namespace.
"I want this assertion to fail. If you don't fail, die." Um...
> > > I think if we could generalise this nicely it would also solve the
> > > negative regexps problem.
> >
> > Good point.
> >
> > sub T::U::Assertion::Regexp::do_failif {
> > my $self = shift;
> > my $target = shift;
> > $target !~ /$$self/ or
> > $self->fail("'$target' matched /$$self/ unexpectedly\n");
> > }
>
> I think I was after
>
> sub T::U::Assertion::NRegexp::do_failif {
So, you want to create a new kind of assertion class, with a different
interface, and I'm supposed to know which method to call depending on
what class the assertion is. And because both sorts of class are going
to be built from a regular expression, there's no good way for the
automagic object builder to work out which class to automagically
build.
Whereas, adding 'do_failif' to the interface of an Assertion with the
assumption that it's equivalent to asserting that the 'assertion'
returns false will work for any possible Assertion subclass.
I think I know which I prefer.
> the way I was thinki ^ ng the two would be alternatives. If you pass
> a Regexp to assert, how does it know whether that's positive or
> negative?
Exactly.
However, if you do
$self->assert(qr/.../, $string_to_match); # $string_to_match must match
or
$self->nassert(qr/.../, $string_to_not_match);
then it'll know which method of the assertion object to call.
And if you are going to use the same assertion object repeatedly you
only have to make an assertion object once for a given pattern and you
can use it or its negation as often as you want.
> Problem is, a Regexp seems to be a blessed thingie already, but I
> find any module file or comprehensive docs. Not that I looked _very_
> hard.
There isn't one. But see Test::Unit::Assertion::Regexp for a way of
using it as the basis of an object.
> > 'failif' or 'nassert'?
>
> or 'tressa'? Or is that too FORTRAN? (FORTRAN? I first bumped into
> that with shell script...)
I really don't like tressa. And having looked at '$self->failif' and
'$self->nassert' when I was writing up those two code examples, I
think I prefer nassert. But I don't really like that either.
Suggestions welcome..
> > Hmm... getting meaningful error messages for coderefs is still tricky,
> > but then it was never actively easy and the 'this sub with these
> > arguments unexpectly returned true' style of default error message
> > should be enough for the user to work out what's going on.
>
> Unexpectedly returned true .. your average error message is 'true', so
> this would actually suit me much better.
>
> However, last time I suggested such a feature you reminded me that the
> package can 'die "foo"' just as well as 'return "foo"'.
Good point, though I don't think it was me that reminded you. I'm
thinking of 'nassert' as syntactic sugar for negative pattern matches
(since you could alway do qr/(?!PATTERN)/ to say "Must not match
pattern". Of course, you could also do it with:
$self->assert(sub {shift !~ /PATTERN/}, $foo)
But then you don't get the default failure message of
T:U:Assertion::Regexp. And providing a sensible message at this point
is a PITA and leads to far too much 'bad' code reuse via cut & paste.
--
Piers
_______________________________________________
Perlunit-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/perlunit-devel