Time to play devil's advocate ;-)
I'm not convinced that this new Test::Unit::Assertion::* stuff is
TSTTCPW. Admittedly this may well be because I'm missing some crucial
advantage it gives ...
What are our goals? In no particular order:
1) We would like the option of having the failure reports give us a
listing of the assertion code that failed.
2) We would like a nice syntax for matching against regexps.
3) We (well, I, and maybe Matthew from the sound of it) would like
some shorthand for string and numeric equality assertions that
automatically generates a failure message of the form
"Got `$foo', expected `$bar'".
4) We would like to be able to create new types of assertion. We
were maybe a bit short on examples of this, but fortunately I have
a very real need for one right now: I'm coding a new dynamic
graphics generation suite using gimp-Perl, and I need to be able
to be able to assert that an image generated looks exactly the
same as one in a given filename (i.e. the fixture is image files).
5) These assertion extensions must be createable from within
"user-space" (i.e. outside Test::Unit::*). In fact, if we satisfy
requirements 2) and 3), I can't think of a reason why we would
want to extend *inside* Test::Unit::*.
Hope I haven't missed any.
I'm not entirely convinced of the value of goal 1) -- I would have
thought a decent failure message would be usually be adequate. If
not, we can always figure out the file and line-number where the
assertion is made, and pass that back to the runner to do as it
pleases with (fire up a viewer at that line etc.).
So, I propose that the following is TSTTCPW:
- Pass the location (file/line) of failed assertion code to the
listeners via the add_failure() method. This is very easy to
implement, satisfies goal 1), and has the advantages that a) our
assertion code doesn't get mangled by B::Deparse if we choose to
view it, and b) we can also choose how much context surrounding
the code we want to see. The latter is advantageous for longer
test_*() methods.
- Add assert_match() and assert_no_match() methods (except with much
better names) to T::U::A for regexp matching. This is trivial to
do -- I've already done it, give or take -- and satisfies goal 2).
- Add versions of ok() for string/numeric comparison, defaulting to
sensible failure messages. [I'm still dying to know if using eq
for numeric comparison ever breaks ...] Again, trivial, and I've
basically done it already. This satisfies goal 3).
- Leave the user to code their own extended assertion techniques
separately. We don't have to do anything at all, and it satisfies
goals 4) and 5). Here's how I might do it for image comparison:
package MyAssert::Images;
sub assert_images_equal {
my $self = shift;
my ($image, $filename, $failure_message) = @_;
# compare $image image object with image saved in $filename
$failure_message ||= "image not equal to image in file $filename";
$self->fail($failure_message) unless $is_equal;
}
package My::ImageTestCase;
use My::ImageGenerator;
use base qw(MyAssert::Images);
sub test_button_generator {
my $self = shift;
my $button = generate_button( ... );
$self->assert_images_equal($button, $filename1);
my $icon = generate_icon( ... );
$self->assert_images_equal($icon, $filename2);
}
This is all ridiculously simple, and AFAICS, works.
Now you have to shoot me down in flames and persuade me why your way
is better ;-)
Adam
_______________________________________________
Perlunit-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/perlunit-devel