in reply to Re^3: RFC: Test::Contract - extensible object-oriented runtime check series
in thread RFC: Test::Contract - extensible object-oriented runtime check series
I'd say type checks as well as normal assertions and unit tests are there to ensure a piece of code works correctly (or, more precisely, fails loudly under known failure modes). This is indeed enough for the majority of cases. A contract on the other hand is there to ensure a different piece of code works correctly (in the same sense). Just like I don't need a contract to make myself do something for myself. However, if other people are involved, agreement on what is to be done is desirable.
At such a high level, I'm not sure I can produce actual code examples, but I'll try to minimize the hand-waving.
Ex. 1 A normal croak() would interrupt execution on the first error it sees. Fine for the most part. However, more than once I've seen monstrous, ad-hoc, ill-defined "error collector" classes that are there to ensure all possible errors are reported for a complex input. E.g. all necessary id's are present, they exist in the DB, they actually belong to the current user and allow for the requested operation. Maybe a credit card validation on top of that. Test::Contract could just be a drop-in replacement, but not tied to one project, having an out of the box arsenal of checks, and some concise syntactic sugar.
Ex. 2 Say we have a web-service that takes a lot of parameters and outputs a JSON. Not quite uncommon these days... Now on the other end we have some poor guy/gal who needs to figure out why their call of our web-service doesn't work. I think it would be nice to let them know all the problems we see with their input and not just one error. This is for test/dev environment, of course, the production will just say "failed to process request" (and log a handy validation report!). UPD: Here!
Ex. 3 Say we have a unit-test suite written for a Foo::Bar::PP module. Now some other person is willing to make Foo::Bar::XS (or God forbid Foo::Bar::Tiny that utilizes half of CPAN) and claim it's a cleaner, faster drop-in replacement. Of course, they could copy-and-paste the original test suite to make sure it works, or monkey-patch it to use their module instead of the original, or write their own.... Or, using Test::Contract, create a generic test suite that would chew a given module and certify it as a Foo::Bar substitute. UPD: Here!
Ex. 4 Say we have a framework (ouch) or generally some complex system allowing to load user plug-ins and/or different back-end implementations. Of course, we can just shift the blame to whoever authorized loading those untrusted blobs into our beautiful, carefully designed system. However, providing a micro-test hooked to the loading process seems like a more responsible approach.
Maybe this is going to make a good start for my example/ directory. And btw thanks for mentioning PerlX::Assert, going to study it now.
|
---|