Class::Contract has always bothered me as way too much Kool-Aid to drink in one sitting.
I completely agree. Having the ability to apply pre/post/invariant functionality to normal Perl classes has been on my to do list for years. Still waiting for a visit from the spare time fairy ;)
Cutting DBC down to its Best Trick: inheritable
invariants. And an invariant is just a test before or after a function
call. All the rest of Class::Contract, the enforcement, the new OO syntax...
that can all be thrown out. If you want all that, use a different module.
So what you're left with is...
use Test::Contract; use Test::More;
sub add { pre { is( @_, 2, 'got two arguments' ) }
my $sum = $_[0] + $_[1]; return $sum;
post { unlike( $ret, qr/\D/ ) } }
...and the rest is a little clever filtering.
Ah. The infamous "trivial matter of programming" :-)
I've thought it might be nice to be able to separate out the pre-post conditions from the actual subroutines in question and apply them in an AOPish manner.... but as I said before --- never had the time to think about it in detail.
Ooooh! I just had a great idea. Use "TEST { ... }" instead of "TEST: { ... }"
in Test::AtRuntime. If the user has Filter::Simple, use that to strip out
the TEST blocks. Otherwise, its a function call to TEST() passing in a code
ref which it would run or not run based on if we're testing or not. Except
now there's a dependency on Sub::Uplevel. :(
Neato - but I have to admit I'm in the "source filters are evil" camp :-) Roll on Perl6 and decent macros!
- I think the idea of being able to run tests as assertions is a cute one worth exploring. Just having a T::B subclass that died rather than log anything would be a boon. Giving us all the goodness of the T::B based functions for normal assertions.
Carp::Assert::More.
The advantage would be to avoid a parallel evolution of similar groups of functionality in the Test:: and Carp::Assert:: hierarchies.
[snip]Or even more trivially, take Test::AtRuntime and swap out Test::Builder::ok() with something that dies on failure.
I was thinking about the ability to have an assertion block - so you could do (something like):
ASSERT { isa_ok($_[0], 'Foo'); ok( $_[1], 'non-false value'); };
and get a single die reporting all failing tests in the block. So it would need something a little more sneaky than overriding T::B::ok.
Adrian