Perl's not the only TAP source

Steve Purkis steve at purkis.ca
Fri Apr 10 11:21:35 GMT 2009


Hi all,

As mentioned in the conversation with Gabor & Ash (which for some  
reason seems to have ended up under the wrong thread?), there's a  
problem with the way we currently determine TAP sources.

If you look at TAP::Parser::_initialize() you'll see what I mean.  The  
logic basically looks like:

	if raw tap, make a stream out of it
	if executable, execute & make a stream out of output
	if 'source', and..
		it's an object, get its stream
-->		it's a file on disk, assume it's a perl script & exec & get stream
		we dunno, so die
	if stream, just use it

This is heavily perl-oriented, which is not surprising, given TAP's  
roots.  According to the docs, this is what you need to do to run a  
ruby test script:

	prove --exec '/usr/bin/ruby -w' t/

And as Ash and I discovered, if you want to replay results  
demonstrated from TAP::Archive, you have to do something like this:

	tar xzf tap.tar.gz
	prove --exec 'cat' -Q t/

In both of these cases, wouldn't it be better if you could just say:

	prove t/

And have prove / TAP::Parser DTRT like it does with Perl scripts?  I'd  
argue that this is the way forward if we want to promote the adoption  
of TAP beyond Perl, and have prove be a bit nicer to both users &  
plugin developers.

There's a fairly easy way of doing that:  move the logic from  
TAP::Parser::initialize() to a factory class that supports plugins,  
then we'll let other people easily write extensions that make prove  
more useful.

Of course, there's a number of different ways of doing that.  I was  
thinking something along the lines of:

	TAP::Parser::SourceFactory
	# either 'registry' approach, or scan @INC & load plugins.
	# was thinking 'detectors' ala:
	# TAP::Parser::SourceDetector::Archive, etc...

	sub make_source {
		# key case to handle is: source detection
		# either leave raw tap & executable detection in
		# TAP::Parser, or move here and handle these too
	}

	sub detect_source {
		# if it's an object, just return it

		# otherwise find something that can handle it
		for each @detector {
			if $detector->detect( $source )
				return $detector->make_source( $source )
		}

		# error: can't detect source
	}

Then the currently default Perl source would just be a detector:

	TAP::Parser::SourceDetector::Perl

But we could also have the Archive & Ruby sources:

	TAP::Parser::SourceDetector::Archive
	TAP::Parser::SourceDetector::Ruby

And whatever you like:

	TAP::Parser::SourceDetector::Exec
	TAP::Parser::SourceDetector::PHP
	TAP::Parser::SourceDetector::Java
	TAP::Parser::SourceDetector::Python
	TAP::Parser::SourceDetector::HTTP (remote source?)
	etc...

You might need to introduce the idea of priority, where more than one  
detector can handle a source, but that's a ways off...

Thoughts?

+--
   Steve Purkis



More information about the tapx-dev mailing list