| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 | 
							- <?php
 - 
 - require_once 'Sweety/Runner.php';
 - require_once 'Sweety/TestLocator.php';
 - require_once 'Sweety/Reporter.php';
 - 
 - /**
 -  * Base functionality for the Sweety_Runner.
 -  * @package Sweety
 -  * @author Chris Corbyn
 -  */
 - abstract class Sweety_Runner_AbstractTestRunner implements Sweety_Runner
 - {
 -  
 -  /**
 -   * The reporter used for showing progress.
 -   * @var Sweety_Reporter
 -   * @access private
 -   */
 -  private $_reporter;
 -  
 -   /**
 -    * TestLocator strategies.
 -    * @var Sweety_TestLocator[]
 -    * @access private
 -    */
 -   private $_testLocators = array();
 -    
 -   /**
 -    * Regular expression for classes which should be ignored.
 -    * @var string
 -    * @access private
 -    */
 -   private $_ignoredClassRegex = '/^$/D';
 -   
 -   /**
 -    * Set the reporter used for showing results.
 -    * @param Sweety_Reporter $reporter
 -    */
 -   public function setReporter(Sweety_Reporter $reporter)
 -   {
 -     $this->_reporter = $reporter;
 -   }
 -   
 -   /**
 -    * Get the reporter used for showing results.
 -    * @return Sweety_Reporter
 -    */
 -   public function getReporter()
 -   {
 -     return $this->_reporter;
 -   }
 -   
 -   /**
 -    * Register a test locator instance.
 -    * @param Sweety_TestLocator $locator
 -    */
 -   public function registerTestLocator(Sweety_TestLocator $locator)
 -   {
 -     $this->_testLocators[] = $locator;
 -   }
 -   
 -   /**
 -    * Set the regular expression used to filter out certain class names.
 -    * @param string $ignoredClassRegex
 -    */
 -   public function setIgnoredClassRegex($ignoredClassRegex)
 -   {
 -     $this->_ignoredClassRegex = $ignoredClassRegex;
 -   }
 -   
 -   /**
 -    * Get the filtering regular expression for ignoring certain classes.
 -    * @return string
 -    */
 -   public function getIgnoredClassRegex()
 -   {
 -     return $this->_ignoredClassRegex;
 -   }
 -    
 -   /**
 -    * Run a single test case with the given name, using the provided output format.
 -    * @param string $testName
 -    * @param string $format (xml, text or html)
 -    * @return int
 -    */
 -   public function runTestCase($testName, $format = Sweety_Runner::REPORT_TEXT)
 -   {
 -     foreach ($this->_testLocators as $locator)
 -     {
 -       if ($locator->includeTest($testName))
 -       {
 -         break;
 -       }
 -     }
 -     
 -     $testClass = new ReflectionClass($testName);
 -     if ($testClass->getConstructor())
 -     {
 -       //We don't want test output to be cached
 -       if (!SimpleReporter::inCli())
 -       {
 -         header("Cache-Control: no-cache, must-revalidate");
 -         header("Pragma: no-cache");
 -         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
 -       }
 -       
 -       switch ($format)
 -       {
 -         case Sweety_Runner::REPORT_HTML:
 -           $reporter = new HtmlReporter();
 -           break;
 -         case Sweety_Runner::REPORT_XML:
 -           if (!SimpleReporter::inCli())
 -           {
 -             header("Content-Type: text/xml"); //Sigh! SimpleTest (skip() issues).
 -           }
 -           $reporter = new XmlReporter();
 -           break;
 -         case Sweety_Runner::REPORT_TEXT:
 -         default:
 -           $reporter = new TextReporter();
 -           break;
 -       }
 -       $test = $testClass->newInstance();
 -       return $test->run($reporter) ? 0 : 1;
 -     }
 -     
 -     return 1;
 -   }
 -   
 -   /**
 -    * Use strategies to find tests which are runnable.
 -    * @param string[] $dirs
 -    * @return string[]
 -    */
 -   protected function findTests($dirs = array())
 -   {
 -     $tests = array();
 -     foreach ($this->_testLocators as $locator)
 -     {
 -       $tests += $locator->getTests($dirs);
 -     }
 -     return $tests;
 -   }
 -   
 -   /**
 -    * Parse an XML response from a test case an report to the reporter.
 -    * @param string $xml
 -    * @param string $testCase
 -    */
 -   protected function parseXml($xml, $testCase)
 -   {
 -     $reporter = $this->_reporter->getReporterFor($testCase);
 -     if (!$reporter->isStarted())
 -     {
 -       $reporter->start();
 -     }
 -     
 -     $xml = str_replace("\0", '?', trim($xml));
 -     $xml = preg_replace('/[^\x01-\x7F]/e', 'sprintf("&#%d;", ord("$0"));', $xml); //Do something better?
 -     if (!empty($xml))
 -     {
 -       $document = @simplexml_load_string($xml);
 -       if ($document)
 -       {
 -         $this->_parseDocument($document, $testCase, $reporter);
 -         $reporter->finish();
 -         return;
 -       }
 -     }
 -     
 -     $reporter->reportException(
 -       'Invalid XML response: ' .
 -       trim(strip_tags(
 -         preg_replace('/^\s*<\?xml.+<\/(?:name|pass|fail|exception)>/s', '', $xml)
 -         )),
 -       $testCase
 -       );
 -   }
 -   
 -   /**
 -    * Parse formatted test output.
 -    * @param SimpleXMLElement The node containing the output
 -    * @param string $path to this test method
 -    * @access private
 -    */
 -   private function _parseFormatted(SimpleXMLElement $formatted, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     $reporter->reportOutput((string)$formatted, $path);
 -   }
 -   
 -   /**
 -    * Parse test output.
 -    * @param SimpleXMLElement The node containing the output
 -    * @param string $path to this test method
 -    * @access private
 -    */
 -   private function _parseMessage(SimpleXMLElement $message, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     $reporter->reportOutput((string)$message, $path);
 -   }
 -   
 -   /**
 -    * Parse a test failure.
 -    * @param SimpleXMLElement The node containing the fail
 -    * @param string $path to this test method
 -    * @access private
 -    */
 -   private function _parseFailure(SimpleXMLElement $failure, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     $reporter->reportFail((string)$failure, $path);
 -   }
 -   
 -   /**
 -    * Parse an exception.
 -    * @param SimpleXMLElement The node containing the exception
 -    * @param string $path to this test method
 -    * @access private
 -    */
 -   private function _parseException(SimpleXMLElement $exception, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     $reporter->reportException((string)$exception, $path);
 -   }
 -   
 -   /**
 -    * Parse a pass.
 -    * @param SimpleXMLElement The node containing this pass.
 -    * @param string $path to this test method
 -    * @access private
 -    */
 -   private function _parsePass(SimpleXMLElement $pass, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     $reporter->reportPass((string)$pass, $path);
 -   }
 -   
 -   /**
 -    * Parse a single test case.
 -    * @param SimpleXMLElement The node containing the test case
 -    * @param string $path to this test case
 -    * @access private
 -    */
 -   private function _parseTestCase(SimpleXMLElement $testCase, $path = '',
 -     Sweety_Reporter $reporter)
 -   { 
 -     foreach ($testCase->xpath('./test') as $testMethod)
 -     {
 -       $testMethodName = (string) $this->_firstNodeValue($testMethod->xpath('./name'));
 -       
 -       foreach ($testMethod->xpath('./formatted') as $formatted)
 -       {
 -         $this->_parseFormatted(
 -           $formatted, $path . ' -> ' . $testMethodName, $reporter);
 -       }
 -       
 -       foreach ($testMethod->xpath('./message') as $message)
 -       {
 -         $this->_parseMessage(
 -           $message, $path . ' -> ' . $testMethodName, $reporter);
 -       }
 -       
 -       foreach ($testMethod->xpath('./fail') as $failure)
 -       {
 -         $this->_parseFailure(
 -           $failure, $path . ' -> ' . $testMethodName, $reporter);
 -       }
 -       
 -       foreach ($testMethod->xpath('./exception') as $exception)
 -       {
 -         $this->_parseException(
 -           $exception, $path . ' -> ' . $testMethodName, $reporter);
 -       }
 -       
 -       foreach ($testMethod->xpath('./pass') as $pass)
 -       {
 -         $this->_parsePass($pass, $path . ' -> ' . $testMethodName, $reporter);
 -       }
 -       
 -       $stdout = trim((string) $testMethod);
 -       if ($stdout)
 -       {
 -         $reporter->reportOutput($stdout, $path . ' -> ' . $testMethodName);
 -       }
 -     }
 -   }
 -   
 -   /**
 -    * Parse the results of all tests.
 -    * @param SimpleXMLElement The node containing the tests
 -    * @param string $path to the tests
 -    * @access private
 -    */
 -   private function _parseResults(SimpleXMLElement $document, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     $groups = $document->xpath('./group');
 -     if (!empty($groups))
 -     { 
 -       foreach ($groups as $group)
 -       { 
 -         $groupName = (string) $this->_firstNodeValue($group->xpath('./name'));
 -         $this->_parseResults($group, $path . ' -> ' . $groupName, $reporter);
 -       }
 -     }
 -     else
 -     {
 -       foreach ($document->xpath('./case') as $testCase)
 -       {
 -         $this->_parseTestCase($testCase, $path, $reporter);
 -       }
 -     }
 -   }
 -   
 -   /**
 -    * Parse the entire SimpleTest XML document from a test case.
 -    * @param SimpleXMLElement $document to parse
 -    * @param string $path to the test
 -    * @access private
 -    */
 -   private function _parseDocument(SimpleXMLElement $document, $path = '',
 -     Sweety_Reporter $reporter)
 -   {
 -     if ($everything = $this->_firstNodeValue($document->xpath('/run')))
 -     {
 -       $this->_parseResults($everything, $path, $reporter);
 -     }
 -     elseif ($skip = $this->_firstNodeValue($document->xpath('/skip')))
 -     {
 -       $reporter->reportSkip((string) $skip, $path);
 -     }
 -   }
 -   
 -   protected function _sort($a, $b)
 -   {
 -     $apkg = preg_replace('/_[^_]+$/D', '', $a);
 -     $bpkg = preg_replace('/_[^_]+$/D', '', $b);
 -     if ($apkg == $bpkg)
 -     {
 -       if ($a == $b)
 -       {
 -         return 0;
 -       }
 -       else
 -       {
 -         return ($a > $b) ? 1 : -1;
 -       }
 -     }
 -     else
 -     {
 -       return ($apkg > $bpkg) ? 1 : -1;
 -     }
 -   }
 -   
 -   private function _firstNodeValue($nodeSet)
 -   {
 -     $first = array_shift($nodeSet);
 -     return $first;
 -   }
 -   
 - }
 
 
  |