2009/1/23 Eric Wilhelm <scratchcomput...@gmail.com>: > # from Ovid > # on Thursday 22 January 2009 15:01: > >>For example, with your code (as I understand it): >> >> test { >> my $manager = Feed::Manager->new($some_uri); >> foreach my $resource ($manager->resources) { >> ok my $result = $manager->get($resource), "$resource should >> work"; } >> } >> >>Imagine that the Feed::Manager connects to an outside resource I don't >> have control over and one day they add a new resource. I now have a >> new test and need to know that something has changed. > > What is it that you need to know in this case? That resources() is > returning a new value? If $manager->get($resource) worked, do you need > to know that there are more? > > If so, you're using the plan as something like a stand-in for the > assertion: > > my @resources = $manager->resources; > is(scalar(@resources), 12, "have 12 resources"); > > And actually, you probably want to assert something like: > > my @resources = $manager->resources; > is_deeply([sort(@resources)], \...@expect_resources); > > Which fails more descriptively than a plan failure. > > But all this test() function does -- accounting for perl 5 > limitations -- is to run a block of who-cares-how-many assertions and > guarantee that the block returns. It only emulates is_deeply() in that > regard (and without messing with tap it would simply emit a single ok.) > > A function which takes a list would be a different thing. > > test_list(\...@resources, sub { > my $resource = shift; > ok my $result = $manager->get($resource), "$resource should work"; } > }); > > And this, too, could be fully planned before running by ending with > now_run_them() sort of a thing. > > Or, again with the details: perhaps a pre-pass would cripple the test() > and test_list() &c functions to merely *count* their number (and number > of arguments). One could then hard-code an assertion into the top of > the file. > > As for skipping and todoing -- the block control is now owned by the > function rather than the interpreter root. One could even have a set > of test {} calls within a block where the skip setting merely instructs > the test calls to not execute their blocks. In which case you wouldn't > have to count the number of tests being skipped. (But you would have > to ensure that your code-to-skip gets inside the blocks -- because > everything has trade-offs.) > > This does reverse the ownership of control flow. So, I guess I'm > basically saying that you simply need to code your tests in a purely > functional way to avoid the halting problem. A quick review of S04 > doesn't seem to say that we're getting much to do with introspecting > blocks, but I'm pretty sure Perl 6 will allow us to declare subroutines > which take blocks and lists (or iterators) with less hassle than Perl 5
Purely functional programming is still Turing complete and so subject to the halting problem. > And yes, iterators reintroduce the halting problem because everything > has trade-offs. Nonetheless, you can still magically deduce that we're > done_testing() because if any test{} didn't return we hit exit() or > whatever in the middle. You can also potentially produce some > semblance of a progress report. > > I don't know if this all means that you need nested tap, or even Perl 6. > I do hope it points to what might be possible and even maybe relatively > easy. > > Certainly, I find that the numeric plan is clunky and no_plan is too > unguarded. The done() is a step. The numeric plan is not strictly > necessary and I think any assertion it performs can be achieved (with > better diagnostics) by actually asserting that what you intend to do is > done as intended. Maybe that logical transformation from one number to > @things and @stuff is not for everyone or is considered overly > prescriptive, but there's more than one way to do it and perhaps even > three. What happens if both the thing _and_ the assertion that the thing should be don't run? The point is that you want to declare your intention independently from taking the action. If you declare the plan alongside performing it, then your planning becomes subject to bugs. If you retrospectively deduce the plan on the basis of the actions you see performed then you will always conclude that everything went as planned, F > --Eric > -- > "It is a mistake to allow any mechanical object to realize that you are > in a hurry." > --Ralph's Observation > --------------------------------------------------- > http://scratchcomputing.com > --------------------------------------------------- >