#16 Make reporter class output redirectable

open
nobody
None
5
2008-12-21
2007-12-29
Anonymous
No

Suggestion: Add a method paint($str) that prints it argument.
Subclasses can override this method to print to other destinations.

(An alternative would be to capture the outputs via output buffering, but if the outputs are sent to a browser, it will then sit idle while the tests are running and then show all results in a single large blob. For long-running tests, it's preferrable if each result gets sent as soon as it is available.)

I have added a patch file to implement the change.
Warning: the patch is entirely untested (I don't know how to run the unit tests for simpletest).
I will submit updated patch files as I find bugs.

Discussion

  • Joachim Durchholz

    Logged In: YES
    user_id=1835283
    Originator: NO

    The paint() method got added to the wrong class.
    I'll attach a corrected patch file.

    The patch is straight from the code I'm using right now in my testing environment.
    The patches are still not regression tested. They *should* work as far as I can see, but I'm far from being an expert for SimpleTest, so I'll leave that task to somebody with more knowledge :-)

    NOTE: The patch is designed so that output can be redirected by writing a subclass of Reporter.
    I don't think this is the best design. It's probably a better idea to create a new Painter class that can accept output, and have the Reporter classes accept a Painter object to print the output.
    The patch may still serve as a good starting point for implementing the change, which is why I'm going to submit it anyway :-)

     
  • Joachim Durchholz

    Logged In: YES
    user_id=1835283
    Originator: NO

    Argh... I don't see a way to upload another attachment. Submitting the patch inline...
    --- snip ---
    Index: reporter.php
    ===================================================================
    --- reporter.php (revision 2654)
    +++ reporter.php (working copy)
    @@ -40,15 +40,15 @@
    */
    function paintHeader($test_name) {
    $this->sendNoCacheHeaders();
    - print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
    - print "<html>\n<head>\n<title>$test_name</title>\n";
    - print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
    - $this->_character_set . "\">\n";
    - print "<style type=\"text/css\">\n";
    - print $this->_getCss() . "\n";
    - print "</style>\n";
    - print "</head>\n<body>\n";
    - print "<h1>$test_name</h1>\n";
    + $this->paint("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
    + $this->paint("<html>\n<head>\n<title>$test_name</title>\n");
    + $this->paint("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
    + $this->_character_set . "\">\n");
    + $this->paint("<style type=\"text/css\">\n");
    + $this->paint($this->_getCss() . "\n");
    + $this->paint("</style>\n");
    + $this->paint("</head>\n<body>\n");
    + $this->paint("<h1>$test_name</h1>\n");
    flush();
    }

    @@ -88,16 +88,16 @@
    */
    function paintFooter($test_name) {
    $colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
    - print "<div style=\"";
    - print "padding: 8px; margin-top: 1em; background-color: $colour; color: white;";
    - print "\">";
    - print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
    - print " test cases complete:\n";
    - print "<strong>" . $this->getPassCount() . "</strong> passes, ";
    - print "<strong>" . $this->getFailCount() . "</strong> fails and ";
    - print "<strong>" . $this->getExceptionCount() . "</strong> exceptions.";
    - print "</div>\n";
    - print "</body>\n</html>\n";
    + $this->paint("<div style=\"");
    + $this->paint("padding: 8px; margin-top: 1em; background-color: $colour; color: white;");
    + $this->paint("\">");
    + $this->paint($this->getTestCaseProgress() . "/" . $this->getTestCaseCount());
    + $this->paint(" test cases complete:\n");
    + $this->paint("<strong>" . $this->getPassCount() . "</strong> passes, ");
    + $this->paint("<strong>" . $this->getFailCount() . "</strong> fails and ");
    + $this->paint("<strong>" . $this->getExceptionCount() . "</strong> exceptions.");
    + $this->paint("</div>\n");
    + $this->paint("</body>\n</html>\n");
    }

    /**
    @@ -110,11 +110,11 @@
    */
    function paintFail($message) {
    parent::paintFail($message);
    - print "<span class=\"fail\">Fail</span>: ";
    + $this->paint("<span class=\"fail\">Fail</span>: ");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print implode(" -&gt; ", $breadcrumb);
    - print " -&gt; " . $this->_htmlEntities($message) . "<br />\n";
    + $this->paint(implode(" -&gt; ", $breadcrumb));
    + $this->paint(" -&gt; " . $this->_htmlEntities($message) . "<br />\n");
    }

    /**
    @@ -124,11 +124,11 @@
    */
    function paintError($message) {
    parent::paintError($message);
    - print "<span class=\"fail\">Exception</span>: ";
    + $this->paint("<span class=\"fail\">Exception</span>: ");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print implode(" -&gt; ", $breadcrumb);
    - print " -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
    + $this->paint(implode(" -&gt; ", $breadcrumb));
    + $this->paint(" -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n");
    }

    /**
    @@ -138,15 +138,15 @@
    */
    function paintException($exception) {
    parent::paintException($exception);
    - print "<span class=\"fail\">Exception</span>: ";
    + $this->paint("<span class=\"fail\">Exception</span>: ");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print implode(" -&gt; ", $breadcrumb);
    + $this->paint(implode(" -&gt; ", $breadcrumb));
    $message = 'Unexpected exception of type [' . get_class($exception) .
    '] with message ['. $exception->getMessage() .
    '] in ['. $exception->getFile() .
    ' line ' . $exception->getLine() . ']';
    - print " -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
    + $this->paint(" -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n");
    }

    /**
    @@ -156,11 +156,11 @@
    */
    function paintSkip($message) {
    parent::paintSkip($message);
    - print "<span class=\"pass\">Skipped</span>: ";
    + $this->paint("<span class=\"pass\">Skipped</span>: ");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print implode(" -&gt; ", $breadcrumb);
    - print " -&gt; " . $this->_htmlEntities($message) . "<br />\n";
    + $this->paint(implode(" -&gt; ", $breadcrumb));
    + $this->paint(" -&gt; " . $this->_htmlEntities($message) . "<br />\n");
    }

    /**
    @@ -169,7 +169,7 @@
    * @access public
    */
    function paintFormattedMessage($message) {
    - print '<pre>' . $this->_htmlEntities($message) . '</pre>';
    + $this->paint('<pre>' . $this->_htmlEntities($message) . '</pre>');
    }

    /**
    @@ -212,7 +212,7 @@
    if (! SimpleReporter::inCli()) {
    header('Content-type: text/plain');
    }
    - print "$test_name\n";
    + $this->paint("$test_name\n");
    flush();
    }

    @@ -224,15 +224,15 @@
    */
    function paintFooter($test_name) {
    if ($this->getFailCount() + $this->getExceptionCount() == 0) {
    - print "OK\n";
    + $this->paint("OK\n");
    } else {
    - print "FAILURES!!!\n";
    + $this->paint("FAILURES!!!\n");
    }
    - print "Test cases run: " . $this->getTestCaseProgress() .
    + $this->paint("Test cases run: " . $this->getTestCaseProgress() .
    "/" . $this->getTestCaseCount() .
    ", Passes: " . $this->getPassCount() .
    ", Failures: " . $this->getFailCount() .
    - ", Exceptions: " . $this->getExceptionCount() . "\n";
    + ", Exceptions: " . $this->getExceptionCount() . "\n");
    }

    /**
    @@ -243,11 +243,11 @@
    */
    function paintFail($message) {
    parent::paintFail($message);
    - print $this->getFailCount() . ") $message\n";
    + $this->paint($this->getFailCount() . ") $message\n");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
    - print "\n";
    + $this->paint("\tin " . implode("\n\tin ", array_reverse($breadcrumb)));
    + $this->paint("\n");
    }

    /**
    @@ -258,11 +258,11 @@
    */
    function paintError($message) {
    parent::paintError($message);
    - print "Exception " . $this->getExceptionCount() . "!\n$message\n";
    + $this->paint("Exception " . $this->getExceptionCount() . "!\n$message\n");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
    - print "\n";
    + $this->paint("\tin " . implode("\n\tin ", array_reverse($breadcrumb)));
    + $this->paint("\n");
    }

    /**
    @@ -277,11 +277,11 @@
    '] with message ['. $exception->getMessage() .
    '] in ['. $exception->getFile() .
    ' line ' . $exception->getLine() . ']';
    - print "Exception " . $this->getExceptionCount() . "!\n$message\n";
    + $this->paint("Exception " . $this->getExceptionCount() . "!\n$message\n");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
    - print "\n";
    + $this->paint("\tin " . implode("\n\tin ", array_reverse($breadcrumb)));
    + $this->paint("\n");
    }

    /**
    @@ -291,7 +291,7 @@
    */
    function paintSkip($message) {
    parent::paintSkip($message);
    - print "Skip: $message\n";
    + $this->paint("Skip: $message\n");
    }

    /**
    @@ -300,7 +300,7 @@
    * @access public
    */
    function paintFormattedMessage($message) {
    - print "$message\n";
    + $this->paint("$message\n");
    flush();
    }
    }
    Index: scorer.php
    ===================================================================
    --- scorer.php (revision 2654)
    +++ scorer.php (working copy)
    @@ -253,7 +253,7 @@
    $this->_size = null;
    $this->_progress = 0;
    }
    -
    +
    /**
    * Gets the formatter for variables and other small
    * generic data items.
    @@ -265,6 +265,17 @@
    }

    /**
    + * Paints a string.
    + * Used by all functions that paint to the standard output.
    + * Should be overridden by subclasses that need to redirect
    + * standard output.
    + * @param string $str String to paint.
    + */
    + function paint ($str) {
    + print $str;
    + }
    +
    + /**
    * Paints the start of a group test. Will also paint
    * the page header and footer if this is the
    * first test. Will stash the size if the first
    Index: test/visual_test.php
    ===================================================================
    --- test/visual_test.php (revision 2651)
    +++ test/visual_test.php (working copy)
    @@ -408,19 +408,19 @@

    function paintPass($message) {
    parent::paintPass($message);
    - print "<span class=\"pass\">Pass</span>: ";
    + $this->paint("<span class=\"pass\">Pass</span>: ");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print implode(" -&gt; ", $breadcrumb);
    - print " -&gt; " . htmlentities($message) . "<br />\n";
    + $this->paint(implode(" -&gt; ", $breadcrumb));
    + $this->paint(" -&gt; " . htmlentities($message) . "<br />\n");
    }

    function paintSignal($type, &$payload) {
    - print "<span class=\"fail\">$type</span>: ";
    + $this->paint("<span class=\"fail\">$type</span>: ");
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    - print implode(" -&gt; ", $breadcrumb);
    - print " -&gt; " . htmlentities(serialize($payload)) . "<br />\n";
    + $this->paint(implode(" -&gt; ", $breadcrumb));
    + $this->paint(" -&gt; " . htmlentities(serialize($payload)) . "<br />\n");
    }
    }

    Index: xml.php

    --- xml.php (revision 2654)
    +++ xml.php (working copy)
    @@ -69,12 +69,12 @@
    */
    function paintGroupStart($test_name, $size) {
    parent::paintGroupStart($test_name, $size);
    - print $this->_getIndent();
    - print "<" . $this->_namespace . "group size=\"$size\">\n";
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "name>" .
    + $this->paint($this->_getIndent());
    + $this->paint("<" . $this->_namespace . "group size=\"$size\">\n");
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "name>" .
    $this->toParsedXml($test_name) .
    - "</" . $this->_namespace . "name>\n";
    + "</" . $this->_namespace . "name>\n");
    }

    /**
    @@ -83,8 +83,8 @@
    * @access public
    */
    function paintGroupEnd($test_name) {
    - print $this->_getIndent();
    - print "</" . $this->_namespace . "group>\n";
    + $this->paint($this->_getIndent());
    + $this->paint("</" . $this->_namespace . "group>\n");
    parent::paintGroupEnd($test_name);
    }

    @@ -95,12 +95,12 @@
    */
    function paintCaseStart($test_name) {
    parent::paintCaseStart($test_name);
    - print $this->_getIndent();
    - print "<" . $this->_namespace . "case>\n";
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "name>" .
    + $this->paint($this->_getIndent());
    + $this->paint("<" . $this->_namespace . "case>\n");
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "name>" .
    $this->toParsedXml($test_name) .
    - "</" . $this->_namespace . "name>\n";
    + "</" . $this->_namespace . "name>\n");
    }

    /**
    @@ -109,8 +109,8 @@
    * @access public
    */
    function paintCaseEnd($test_name) {
    - print $this->_getIndent();
    - print "</" . $this->_namespace . "case>\n";
    + $this->paint($this->_getIndent());
    + $this->paint("</" . $this->_namespace . "case>\n");
    parent::paintCaseEnd($test_name);
    }

    @@ -121,12 +121,12 @@
    */
    function paintMethodStart($test_name) {
    parent::paintMethodStart($test_name);
    - print $this->_getIndent();
    - print "<" . $this->_namespace . "test>\n";
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "name>" .
    + $this->paint($this->_getIndent());
    + $this->paint("<" . $this->_namespace . "test>\n");
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "name>" .
    $this->toParsedXml($test_name) .
    - "</" . $this->_namespace . "name>\n";
    + "</" . $this->_namespace . "name>\n");
    }

    /**
    @@ -136,8 +136,8 @@
    * @access public
    */
    function paintMethodEnd($test_name) {
    - print $this->_getIndent();
    - print "</" . $this->_namespace . "test>\n";
    + $this->paint($this->_getIndent());
    + $this->paint("</" . $this->_namespace . "test>\n");
    parent::paintMethodEnd($test_name);
    }

    @@ -148,10 +148,10 @@
    */
    function paintPass($message) {
    parent::paintPass($message);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "pass>";
    - print $this->toParsedXml($message);
    - print "</" . $this->_namespace . "pass>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "pass>");
    + $this->paint($this->toParsedXml($message));
    + $this->paint("</" . $this->_namespace . "pass>\n");
    }

    /**
    @@ -161,10 +161,10 @@
    */
    function paintFail($message) {
    parent::paintFail($message);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "fail>";
    - print $this->toParsedXml($message);
    - print "</" . $this->_namespace . "fail>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "fail>");
    + $this->paint($this->toParsedXml($message));
    + $this->paint("</" . $this->_namespace . "fail>\n");
    }

    /**
    @@ -174,10 +174,10 @@
    */
    function paintError($message) {
    parent::paintError($message);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "exception>";
    - print $this->toParsedXml($message);
    - print "</" . $this->_namespace . "exception>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "exception>");
    + $this->paint($this->toParsedXml($message));
    + $this->paint("</" . $this->_namespace . "exception>\n");
    }

    /**
    @@ -187,14 +187,14 @@
    */
    function paintException($exception) {
    parent::paintException($exception);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "exception>";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "exception>");
    $message = 'Unexpected exception of type [' . get_class($exception) .
    '] with message ['. $exception->getMessage() .
    '] in ['. $exception->getFile() .
    ' line ' . $exception->getLine() . ']';
    - print $this->toParsedXml($message);
    - print "</" . $this->_namespace . "exception>\n";
    + $this->paint($this->toParsedXml($message));
    + $this->paint("</" . $this->_namespace . "exception>\n");
    }

    /**
    @@ -204,10 +204,10 @@
    */
    function paintSkip($message) {
    parent::paintSkip($message);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "skip>";
    - print $this->toParsedXml($message);
    - print "</" . $this->_namespace . "skip>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "skip>");
    + $this->paint($this->toParsedXml($message));
    + $this->paint("</" . $this->_namespace . "skip>\n");
    }

    /**
    @@ -217,10 +217,10 @@
    */
    function paintMessage($message) {
    parent::paintMessage($message);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "message>";
    - print $this->toParsedXml($message);
    - print "</" . $this->_namespace . "message>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "message>");
    + $this->paint($this->toParsedXml($message));
    + $this->paint("</" . $this->_namespace . "message>\n");
    }

    /**
    @@ -231,10 +231,10 @@
    */
    function paintFormattedMessage($message) {
    parent::paintFormattedMessage($message);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "formatted>";
    - print "<![CDATA[$message]]>";
    - print "</" . $this->_namespace . "formatted>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "formatted>");
    + $this->paint("<![CDATA[$message]]>");
    + $this->paint("</" . $this->_namespace . "formatted>\n");
    }

    /**
    @@ -245,10 +245,10 @@
    */
    function paintSignal($type, &$payload) {
    parent::paintSignal($type, $payload);
    - print $this->_getIndent(1);
    - print "<" . $this->_namespace . "signal type=\"$type\">";
    - print "<![CDATA[" . serialize($payload) . "]]>";
    - print "</" . $this->_namespace . "signal>\n";
    + $this->paint($this->_getIndent(1));
    + $this->paint("<" . $this->_namespace . "signal type=\"$type\">");
    + $this->paint("<![CDATA[" . serialize($payload) . "]]>");
    + $this->paint("</" . $this->_namespace . "signal>\n");
    }

    /**
    @@ -262,13 +262,13 @@
    if (! SimpleReporter::inCli()) {
    header('Content-type: text/xml');
    }
    - print "<?xml version=\"1.0\"";
    + $this->paint("<?xml version=\"1.0\"");
    if ($this->_namespace) {
    - print " xmlns:" . $this->_namespace .
    - "=\"www.lastcraft.com/SimpleTest/Beta3/Report\"";
    + $this->paint(" xmlns:" . $this->_namespace .
    + "=\"www.lastcraft.com/SimpleTest/Beta3/Report\"");
    }
    - print "?>\n";
    - print "<" . $this->_namespace . "run>\n";
    + $this->paint("?>\n");
    + $this->paint("<" . $this->_namespace . "run>\n");
    }

    /**
    @@ -278,7 +278,7 @@
    * @abstract
    */
    function paintFooter($test_name) {
    - print "</" . $this->_namespace . "run>\n";
    + $this->paint("</" . $this->_namespace . "run>\n");
    }
    }

     
  • Edward Z. Yang

    Edward Z. Yang - 2008-12-21

    Refiled as a patch

     
  • Edward Z. Yang

    Edward Z. Yang - 2008-12-21
    • labels: 512933 -->
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks