On 09/04/07, Andy Armstrong <[EMAIL PROTECTED]> wrote:
On 8 Apr 2007, at 22:41, Fergal Daly wrote:
> Yes I did. If you want your structured (or any) diagnostics to be
> associated correctly and you want to allow forking you have to tag
> each line with test numbers. If forking is deemed not important then
> tagging them is not necessary.

But for the severalth time you can have your stream multiplexer thing
but not in the TAP parser.

Does it need to be in the parser? No

Just to be clear, multiplexing is only needed for forks. Given that, I
can't see a nice way for a program to be outputting TAP and then for
it to fork and for 2 processes with the same stdout to start
outputting TAP wrapped in some external multiplex format and for the
consumer to switch from parsing-TAP-mode to demuxing-mode. Can you
explain how that would work?

Might it be useful as a standalone module? Yes
Would it complicate the parser considerably? You betcha

Any way of doing blocks complicates the parser but once you have that,
unambiuously assigning test numbers to all lines is trivial.

>> A TAP stream that doesn't use blocks is unchanged by my proposal -
>> 100% backwards compatible because it's identical.
>
> But a TAP stream that outputs blocks cannot be parsed at all by an
> older parser, it will completely ignore any "not ok"s in the output.

See also: quite a lot else that's new in TAP.

What is that supposed to mean - screw backwards compatiilty? The
YAMLish extension goes to some lengths to preserve backwards
compatibility.

>> > - makes test-numbering non-unique (current TAP parser emits
>> > warnings/errors referring to test numbers)
>>
>> We can construct a hierarchical test number that looks just like
>> yours.
>
> Exactly! So why not just do that to start with and leave out all
> the rest...

Because my 'all the rest' is smaller than your 'all the rest'. It's
extremely simple to add begin / end to TAP::Parser - it doesn't make
the code significantly less clean.

Except it's not smaller!

Are we talking about the same things?

Both of them mess with the plan, in addition,

Mine
- changes the definition of test numbers from [1-9]\d* to [1-9][\d.]+

Yours
- adds 2 keywords
- indented lines are no longer ignored

The YAML proposal uses --- and ... to protect it from other random
stuff that may rely on TAP ignoring indentation, yours has no such
protection

The code to infer scope from a dotted test number is more complex
than the code to push and pop context when the parser sees begin /
end. Generating a dotted test number by walking up the scope stack
prepending test numbers is trivial.

Your imaginary code for my proposal is too complex? Well my imaginary
code for your proposal uses far too much memory and has a security
hole, so I win!

Seriously, it's _all_ pretty trivial.

But that's as nothing compared with the upheaval that would be
necessary to allow a single parser instance to handle interleaved TAP
from multiple, overlapping tests. 'So what' you may say. 'Implement
stream demuxing outside the parser'. Well, er, no - because then we'd
be decoding the test numbering scheme in two places and attaching two
different sets of semantics to those numbers depending on whether
we're unzipping streams or parsing nested tests.

Putting words in my mouth and then proving me wrong - what's next?

I don't think we're talking about the same thing. You talk about a
different behaviour between unzipping streams and nested tests but
there is no unzipping because there is only 1 destination. I want 2
zipped streams to look just like nested tests. What I don't want is to
wait for 1 stream to finish before another starts.

No matter how you do blocks you end up with a set of nested results
(the nested equivalent of Test::Harness::Results). Your proposal says
we must fill in this nested set of result strictly in order, we cannot
accept result 2.3.4.1 until 2.3.3 is finished . My proposal is to
accept result 2.3.4.1 even if  2.3.3 isn't finished.

It makes no sense to conflate the two functions of identifying tests
within a hierarchy and tagging data from multiple sources line-by-
line to mux onto a single pipe. The tag-mux-demux-untag thing can and
should be entirely separate from TAP.

>> > - makes it impossible to fork/thread
>>
>> Until you expand on your proposal to explain how you're going to
>> associate structured diagnostics with a particular test so does
>> yours.
>
> As above, if you care about forking and diagnostics (structured or
> otherwise) you have to tag each diag line with a test number. If you
> don't care about diagnostics and just want to track results then
> forking is supported in the basic suggestion.

Sheesh.

Ah that's what's next :)


> So the essential difference is that with my way you can forget about
> forking for now but you still the option to support it later on. With
> your way, support for forking can not be added later because a test's
> position in the output stream now has a meaning.

Of course it can be added later. It's not even part of TAP. The fact
that it /can/ be added later demonstrates why not building that
mechanism in to TAP is a /good/ thing.

As I said above, you have not yet explained how.

There are different ways to multiplex multiple streams. We're
proposing line by line tagging - but you could equally well employ a
binary protocol that alternated fixed size chunks from the various
input streams.

That's another reason why this mechanism should not be part of TAP.

>> The idea that a TAP stream may in fact be multiple streams that have
>> been mixed together complicates the TAP parser hugely to provide
>> hard-
>> to-test functionality that may not be of interest to the majority of
>> users.
>
> Adding blocks at all complicates the parser. I don't see how
> unambiguously identifying the test that produced every line adds more
> complication than having the parser maintain a stack of blocks.

But you're undertaking that the parser should at some point in the
future be able to handle jumbled up TAP streams from multiple
sources. That complicates things considerably.

>> At the risk of repeating myself (again) any mux / demux can take
>> place at a lower level in a notional TAP protocol stack - it doesn't
>> have to be part of TAP.
>
> You're right, it doesn't have to be, however if you can get it for
> free along with another useful feature, why not take it?

But it's not even vaguely free.

> What benefits do you get from implementing blocks your way vs my way?
> The only one I've seen is that it is easier to concatenate 2 saved TAP
> streams (but not so easy that it's just a matter of cat 1.tap 2.tap >
> combined.tap so you'll want a tool to do it anyway),

* ease of concatenation of TAP

Yes, easy to do it by hand but who is going to be concatenating TAP
files by hand?

* blocks are named - good for UIs

This is an omission on my part, I put comments beside block beginnings
and endings and left out the titles. As I said to Michael much earlier
in the thread, each block is a test and so has a name. The wiki has
been updated.

* ease of implementation

imaginary ease of imaginary implementation

* lack of threat of being co-opted into crackpot stream jumbling scheme

B*alls. Now, can we please stick to polite, rational arguments from here on?

* readability -> whitespace indenting V forest of numbers (debatable,
my pref)

I prefer indenting too but this proposal came from trying to change
things as little as possible and indenting has risks.

* ease of editing - both manual and automatic - fewer numbers to keep
in sync

When does anyone manually or programmatically edit more than a few lines of TAP?

* law of least surprises - that TAP is structured like code easy to
understand

law of least surprises - I upgraded some modules and now this tests is
failing because Test::Harness is confused by my previously ignored
whitepace prefixed output.

* easier to generate (the producer doesn't need to carry a prefix
around or walk
   the stack to find it)

You'll have to choose between that and indentation that follows the
nesting, you can't have both.

* can wrap TAP <= v12 without having to transform it - that's a biggy

Is this not a repeat of the concatenation one? If not, what does
"wrap" mean, who does it and why?

F


--
Andy Armstrong, hexten.net


Reply via email to