From 294375082275acd679afa94fab5e6c62fe124475 Mon Sep 17 00:00:00 2001 From: Shish Date: Fri, 9 Mar 2012 23:08:58 +0000 Subject: [PATCH] upgrade simpletest library, hopefully get rid of deprecation warnings... --- .../HELP_MY_TESTS_DONT_WORK_ANYMORE | 55 +- contrib/simpletest/simpletest/LICENSE | 0 contrib/simpletest/simpletest/README | 76 +- contrib/simpletest/simpletest/VERSION | 2 +- contrib/simpletest/simpletest/arguments.php | 224 ++++ .../simpletest/simpletest/authentication.php | 91 +- contrib/simpletest/simpletest/autorun.php | 70 +- contrib/simpletest/simpletest/browser.php | 388 ++++--- contrib/simpletest/simpletest/collector.php | 30 +- .../simpletest/simpletest/compatibility.php | 49 +- contrib/simpletest/simpletest/cookies.php | 158 +-- .../simpletest/default_reporter.php | 104 +- contrib/simpletest/simpletest/detached.php | 38 +- contrib/simpletest/simpletest/docs.zip | Bin 129563 -> 0 bytes contrib/simpletest/simpletest/dumper.php | 137 ++- contrib/simpletest/simpletest/eclipse.php | 140 +-- contrib/simpletest/simpletest/encoding.php | 349 +++--- contrib/simpletest/simpletest/errors.php | 143 +-- contrib/simpletest/simpletest/exceptions.php | 50 +- contrib/simpletest/simpletest/expectation.php | 371 +++--- .../simpletest/extensions/pear_test_case.php | 28 +- .../extensions/phpunit_test_case.php | 96 -- .../simpletest/extensions/testdox.php | 23 +- .../simpletest/extensions/testdox/test.php | 13 +- contrib/simpletest/simpletest/form.php | 206 ++-- contrib/simpletest/simpletest/frames.php | 246 ++-- contrib/simpletest/simpletest/http.php | 366 +++--- contrib/simpletest/simpletest/invoker.php | 38 +- .../simpletest/simpletest/mock_objects.php | 1004 +++++++++-------- contrib/simpletest/simpletest/page.php | 685 ++--------- .../simpletest/{parser.php => php_parser.php} | 728 ++++++++---- contrib/simpletest/simpletest/recorder.php | 101 ++ .../simpletest/simpletest/reflection_php4.php | 4 +- .../simpletest/simpletest/reflection_php5.php | 96 +- contrib/simpletest/simpletest/remote.php | 68 +- contrib/simpletest/simpletest/reporter.php | 116 +- contrib/simpletest/simpletest/scorer.php | 266 ++--- contrib/simpletest/simpletest/selector.php | 42 +- .../simpletest/simpletest/shell_tester.php | 73 +- contrib/simpletest/simpletest/simpletest.php | 271 ++--- contrib/simpletest/simpletest/socket.php | 168 ++- contrib/simpletest/simpletest/tag.php | 591 ++++++---- contrib/simpletest/simpletest/test.zip | Bin 67459 -> 0 bytes contrib/simpletest/simpletest/test_case.php | 254 ++--- contrib/simpletest/simpletest/tidy_parser.php | 382 +++++++ contrib/simpletest/simpletest/unit_tester.php | 139 ++- contrib/simpletest/simpletest/url.php | 266 +++-- contrib/simpletest/simpletest/user_agent.php | 166 ++- contrib/simpletest/simpletest/web_tester.php | 613 +++++----- contrib/simpletest/simpletest/xml.php | 242 ++-- 50 files changed, 5376 insertions(+), 4390 deletions(-) mode change 100644 => 100755 contrib/simpletest/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE mode change 100644 => 100755 contrib/simpletest/simpletest/LICENSE mode change 100644 => 100755 contrib/simpletest/simpletest/README mode change 100644 => 100755 contrib/simpletest/simpletest/VERSION create mode 100755 contrib/simpletest/simpletest/arguments.php mode change 100644 => 100755 contrib/simpletest/simpletest/compatibility.php mode change 100644 => 100755 contrib/simpletest/simpletest/detached.php delete mode 100644 contrib/simpletest/simpletest/docs.zip mode change 100644 => 100755 contrib/simpletest/simpletest/dumper.php mode change 100644 => 100755 contrib/simpletest/simpletest/exceptions.php mode change 100644 => 100755 contrib/simpletest/simpletest/expectation.php mode change 100644 => 100755 contrib/simpletest/simpletest/extensions/pear_test_case.php delete mode 100644 contrib/simpletest/simpletest/extensions/phpunit_test_case.php mode change 100644 => 100755 contrib/simpletest/simpletest/extensions/testdox.php mode change 100644 => 100755 contrib/simpletest/simpletest/extensions/testdox/test.php mode change 100644 => 100755 contrib/simpletest/simpletest/frames.php mode change 100644 => 100755 contrib/simpletest/simpletest/invoker.php mode change 100644 => 100755 contrib/simpletest/simpletest/mock_objects.php mode change 100644 => 100755 contrib/simpletest/simpletest/page.php rename contrib/simpletest/simpletest/{parser.php => php_parser.php} (51%) mode change 100644 => 100755 create mode 100644 contrib/simpletest/simpletest/recorder.php mode change 100644 => 100755 contrib/simpletest/simpletest/reporter.php mode change 100644 => 100755 contrib/simpletest/simpletest/selector.php mode change 100644 => 100755 contrib/simpletest/simpletest/socket.php delete mode 100644 contrib/simpletest/simpletest/test.zip create mode 100755 contrib/simpletest/simpletest/tidy_parser.php mode change 100644 => 100755 contrib/simpletest/simpletest/unit_tester.php mode change 100644 => 100755 contrib/simpletest/simpletest/xml.php diff --git a/contrib/simpletest/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE b/contrib/simpletest/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE old mode 100644 new mode 100755 index 8ac9cf2a..a65e83e8 --- a/contrib/simpletest/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE +++ b/contrib/simpletest/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE @@ -5,13 +5,64 @@ written with earlier versions will fail with the newest ones. The most dramatic changes are in the alpha releases. Here is a list of possible problems and their fixes... +assertText() no longer finds a string inside a |', '', $text); - $text = preg_replace('|]*alt\s*=\s*"([^"]*)"[^>]*>|', ' \1 ', $text); - $text = preg_replace('|]*alt\s*=\s*\'([^\']*)\'[^>]*>|', ' \1 ', $text); - $text = preg_replace('|]*alt\s*=\s*([a-zA-Z_]+)[^>]*>|', ' \1 ', $text); - $text = preg_replace('|<[^>]*>|', '', $text); - $text = SimpleHtmlSaxParser::decodeHtml($text); - $text = preg_replace('|\s+|', ' ', $text); - return trim(trim($text), "\xA0"); // TODO: The \xAO is a  . Add a test for this. - } } /** - * SAX event handler. + * SAX event handler. Maintains a list of + * open tags and dispatches them as they close. * @package SimpleTest * @subpackage WebTester - * @abstract */ -class SimpleSaxListener { - +class SimplePhpPageBuilder { + private $tags; + private $page; + private $private_content_tag; + private $open_forms = array(); + private $complete_forms = array(); + private $frameset = false; + private $loading_frames = array(); + private $frameset_nesting_level = 0; + private $left_over_labels = array(); + /** - * Sets the document to write to. + * Frees up any references so as to allow the PHP garbage + * collection from unset() to work. * @access public */ - function SimpleSaxListener() { + function free() { + unset($this->tags); + unset($this->page); + unset($this->private_content_tags); + $this->open_forms = array(); + $this->complete_forms = array(); + $this->frameset = false; + $this->loading_frames = array(); + $this->frameset_nesting_level = 0; + $this->left_over_labels = array(); } - + /** - * Start of element event. - * @param string $name Element name. - * @param hash $attributes Name value pairs. - * Attributes without content - * are marked as true. - * @return boolean False on parse error. + * This builder is always available. + * @return boolean Always true. + */ + function can() { + return true; + } + + /** + * Reads the raw content and send events + * into the page to be built. + * @param $response SimpleHttpResponse Fetched response. + * @return SimplePage Newly parsed page. + * @access public + */ + function parse($response) { + $this->tags = array(); + $this->page = $this->createPage($response); + $parser = $this->createParser($this); + $parser->parse($response->getContent()); + $this->acceptPageEnd(); + $page = $this->page; + $this->free(); + return $page; + } + + /** + * Creates an empty page. + * @return SimplePage New unparsed page. + * @access protected + */ + protected function createPage($response) { + return new SimplePage($response); + } + + /** + * Creates the parser used with the builder. + * @param SimplePhpPageBuilder $listener Target of parser. + * @return SimpleSaxParser Parser to generate + * events for the builder. + * @access protected + */ + protected function createParser(&$listener) { + return new SimpleHtmlSaxParser($listener); + } + + /** + * Start of element event. Opens a new tag. + * @param string $name Element name. + * @param hash $attributes Attributes without content + * are marked as true. + * @return boolean False on parse error. * @access public */ function startElement($name, $attributes) { + $factory = new SimpleTagBuilder(); + $tag = $factory->createTag($name, $attributes); + if (! $tag) { + return true; + } + if ($tag->getTagName() == 'label') { + $this->acceptLabelStart($tag); + $this->openTag($tag); + return true; + } + if ($tag->getTagName() == 'form') { + $this->acceptFormStart($tag); + return true; + } + if ($tag->getTagName() == 'frameset') { + $this->acceptFramesetStart($tag); + return true; + } + if ($tag->getTagName() == 'frame') { + $this->acceptFrame($tag); + return true; + } + if ($tag->isPrivateContent() && ! isset($this->private_content_tag)) { + $this->private_content_tag = &$tag; + } + if ($tag->expectEndTag()) { + $this->openTag($tag); + return true; + } + $this->acceptTag($tag); + return true; } - + /** * End of element event. * @param string $name Element name. @@ -750,15 +811,244 @@ class SimpleSaxListener { * @access public */ function endElement($name) { + if ($name == 'label') { + $this->acceptLabelEnd(); + return true; + } + if ($name == 'form') { + $this->acceptFormEnd(); + return true; + } + if ($name == 'frameset') { + $this->acceptFramesetEnd(); + return true; + } + if ($this->hasNamedTagOnOpenTagStack($name)) { + $tag = array_pop($this->tags[$name]); + if ($tag->isPrivateContent() && $this->private_content_tag->getTagName() == $name) { + unset($this->private_content_tag); + } + $this->addContentTagToOpenTags($tag); + $this->acceptTag($tag); + return true; + } + return true; } - + /** - * Unparsed, but relevant data. + * Test to see if there are any open tags awaiting + * closure that match the tag name. + * @param string $name Element name. + * @return boolean True if any are still open. + * @access private + */ + protected function hasNamedTagOnOpenTagStack($name) { + return isset($this->tags[$name]) && (count($this->tags[$name]) > 0); + } + + /** + * Unparsed, but relevant data. The data is added + * to every open tag. * @param string $text May include unparsed tags. * @return boolean False on parse error. * @access public */ function addContent($text) { + if (isset($this->private_content_tag)) { + $this->private_content_tag->addContent($text); + } else { + $this->addContentToAllOpenTags($text); + } + return true; + } + + /** + * Any content fills all currently open tags unless it + * is part of an option tag. + * @param string $text May include unparsed tags. + * @access private + */ + protected function addContentToAllOpenTags($text) { + foreach (array_keys($this->tags) as $name) { + for ($i = 0, $count = count($this->tags[$name]); $i < $count; $i++) { + $this->tags[$name][$i]->addContent($text); + } + } + } + + /** + * Parsed data in tag form. The parsed tag is added + * to every open tag. Used for adding options to select + * fields only. + * @param SimpleTag $tag Option tags only. + * @access private + */ + protected function addContentTagToOpenTags(&$tag) { + if ($tag->getTagName() != 'option') { + return; + } + foreach (array_keys($this->tags) as $name) { + for ($i = 0, $count = count($this->tags[$name]); $i < $count; $i++) { + $this->tags[$name][$i]->addTag($tag); + } + } + } + + /** + * Opens a tag for receiving content. Multiple tags + * will be receiving input at the same time. + * @param SimpleTag $tag New content tag. + * @access private + */ + protected function openTag($tag) { + $name = $tag->getTagName(); + if (! in_array($name, array_keys($this->tags))) { + $this->tags[$name] = array(); + } + $this->tags[$name][] = $tag; + } + + /** + * Adds a tag to the page. + * @param SimpleTag $tag Tag to accept. + * @access public + */ + protected function acceptTag($tag) { + if ($tag->getTagName() == "a") { + $this->page->addLink($tag); + } elseif ($tag->getTagName() == "base") { + $this->page->setBase($tag->getAttribute('href')); + } elseif ($tag->getTagName() == "title") { + $this->page->setTitle($tag); + } elseif ($this->isFormElement($tag->getTagName())) { + for ($i = 0; $i < count($this->open_forms); $i++) { + $this->open_forms[$i]->addWidget($tag); + } + $this->last_widget = $tag; + } + } + + /** + * Opens a label for a described widget. + * @param SimpleFormTag $tag Tag to accept. + * @access public + */ + protected function acceptLabelStart($tag) { + $this->label = $tag; + unset($this->last_widget); + } + + /** + * Closes the most recently opened label. + * @access public + */ + protected function acceptLabelEnd() { + if (isset($this->label)) { + if (isset($this->last_widget)) { + $this->last_widget->setLabel($this->label->getText()); + unset($this->last_widget); + } else { + $this->left_over_labels[] = SimpleTestCompatibility::copy($this->label); + } + unset($this->label); + } + } + + /** + * Tests to see if a tag is a possible form + * element. + * @param string $name HTML element name. + * @return boolean True if form element. + * @access private + */ + protected function isFormElement($name) { + return in_array($name, array('input', 'button', 'textarea', 'select')); + } + + /** + * Opens a form. New widgets go here. + * @param SimpleFormTag $tag Tag to accept. + * @access public + */ + protected function acceptFormStart($tag) { + $this->open_forms[] = new SimpleForm($tag, $this->page); + } + + /** + * Closes the most recently opened form. + * @access public + */ + protected function acceptFormEnd() { + if (count($this->open_forms)) { + $this->complete_forms[] = array_pop($this->open_forms); + } + } + + /** + * Opens a frameset. A frameset may contain nested + * frameset tags. + * @param SimpleFramesetTag $tag Tag to accept. + * @access public + */ + protected function acceptFramesetStart($tag) { + if (! $this->isLoadingFrames()) { + $this->frameset = $tag; + } + $this->frameset_nesting_level++; + } + + /** + * Closes the most recently opened frameset. + * @access public + */ + protected function acceptFramesetEnd() { + if ($this->isLoadingFrames()) { + $this->frameset_nesting_level--; + } + } + + /** + * Takes a single frame tag and stashes it in + * the current frame set. + * @param SimpleFrameTag $tag Tag to accept. + * @access public + */ + protected function acceptFrame($tag) { + if ($this->isLoadingFrames()) { + if ($tag->getAttribute('src')) { + $this->loading_frames[] = $tag; + } + } + } + + /** + * Test to see if in the middle of reading + * a frameset. + * @return boolean True if inframeset. + * @access private + */ + protected function isLoadingFrames() { + return $this->frameset and $this->frameset_nesting_level > 0; + } + + /** + * Marker for end of complete page. Any work in + * progress can now be closed. + * @access public + */ + protected function acceptPageEnd() { + while (count($this->open_forms)) { + $this->complete_forms[] = array_pop($this->open_forms); + } + foreach ($this->left_over_labels as $label) { + for ($i = 0, $count = count($this->complete_forms); $i < $count; $i++) { + $this->complete_forms[$i]->attachLabelBySelector( + new SimpleById($label->getFor()), + $label->getText()); + } + } + $this->page->setForms($this->complete_forms); + $this->page->setFrames($this->loading_frames); } } ?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/recorder.php b/contrib/simpletest/simpletest/recorder.php new file mode 100644 index 00000000..b3d0d01c --- /dev/null +++ b/contrib/simpletest/simpletest/recorder.php @@ -0,0 +1,101 @@ +time, $this->breadcrumb, $this->message) = + array(time(), $breadcrumb, $message); + } +} + +/** + * A single pass captured for later. + * @package SimpleTest + * @subpackage Extensions + */ +class SimpleResultOfPass extends SimpleResult { } + +/** + * A single failure captured for later. + * @package SimpleTest + * @subpackage Extensions + */ +class SimpleResultOfFail extends SimpleResult { } + +/** + * A single exception captured for later. + * @package SimpleTest + * @subpackage Extensions + */ +class SimpleResultOfException extends SimpleResult { } + +/** + * Array-based test recorder. Returns an array + * with timestamp, status, test name and message for each pass and failure. + * @package SimpleTest + * @subpackage Extensions + */ +class Recorder extends SimpleReporterDecorator { + public $results = array(); + + /** + * Stashes the pass as a SimpleResultOfPass + * for later retrieval. + * @param string $message Pass message to be displayed + * eventually. + */ + function paintPass($message) { + parent::paintPass($message); + $this->results[] = new SimpleResultOfPass(parent::getTestList(), $message); + } + + /** + * Stashes the fail as a SimpleResultOfFail + * for later retrieval. + * @param string $message Failure message to be displayed + * eventually. + */ + function paintFail($message) { + parent::paintFail($message); + $this->results[] = new SimpleResultOfFail(parent::getTestList(), $message); + } + + /** + * Stashes the exception as a SimpleResultOfException + * for later retrieval. + * @param string $message Exception message to be displayed + * eventually. + */ + function paintException($message) { + parent::paintException($message); + $this->results[] = new SimpleResultOfException(parent::getTestList(), $message); + } +} +?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/reflection_php4.php b/contrib/simpletest/simpletest/reflection_php4.php index 6c93915a..39801ea1 100644 --- a/contrib/simpletest/simpletest/reflection_php4.php +++ b/contrib/simpletest/simpletest/reflection_php4.php @@ -3,7 +3,7 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: reflection_php4.php 1672 2008-03-02 04:47:34Z edwardzyang $ + * @version $Id: reflection_php4.php 2011 2011-04-29 08:22:48Z pp11 $ */ /** @@ -112,7 +112,7 @@ class SimpleReflection { function isInterface() { return false; } - + /** * Scans for final methods, but as it's PHP 4 there * aren't any. diff --git a/contrib/simpletest/simpletest/reflection_php5.php b/contrib/simpletest/simpletest/reflection_php5.php index 8383bccd..43d8a7b2 100644 --- a/contrib/simpletest/simpletest/reflection_php5.php +++ b/contrib/simpletest/simpletest/reflection_php5.php @@ -3,7 +3,7 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: reflection_php5.php 1683 2008-03-05 21:57:08Z lastcraft $ + * @version $Id: reflection_php5.php 2011 2011-04-29 08:22:48Z pp11 $ */ /** @@ -12,15 +12,15 @@ * @subpackage UnitTester */ class SimpleReflection { - var $_interface; + private $interface; /** * Stashes the class/interface. * @param string $interface Class or interface * to inspect. */ - function SimpleReflection($interface) { - $this->_interface = $interface; + function __construct($interface) { + $this->interface = $interface; } /** @@ -31,10 +31,10 @@ class SimpleReflection { * @access public */ function classExists() { - if (! class_exists($this->_interface)) { + if (! class_exists($this->interface)) { return false; } - $reflection = new ReflectionClass($this->_interface); + $reflection = new ReflectionClass($this->interface); return ! $reflection->isInterface(); } @@ -45,7 +45,7 @@ class SimpleReflection { * @access public */ function classExistsSansAutoload() { - return class_exists($this->_interface, false); + return class_exists($this->interface, false); } /** @@ -55,7 +55,7 @@ class SimpleReflection { * @access public */ function classOrInterfaceExists() { - return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true); + return $this->classOrInterfaceExistsWithAutoload($this->interface, true); } /** @@ -65,7 +65,7 @@ class SimpleReflection { * @access public */ function classOrInterfaceExistsSansAutoload() { - return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false); + return $this->classOrInterfaceExistsWithAutoload($this->interface, false); } /** @@ -76,13 +76,13 @@ class SimpleReflection { * @return boolean True if interface defined. * @access private */ - function _classOrInterfaceExistsWithAutoload($interface, $autoload) { + protected function classOrInterfaceExistsWithAutoload($interface, $autoload) { if (function_exists('interface_exists')) { - if (interface_exists($this->_interface, $autoload)) { + if (interface_exists($this->interface, $autoload)) { return true; } } - return class_exists($this->_interface, $autoload); + return class_exists($this->interface, $autoload); } /** @@ -92,7 +92,7 @@ class SimpleReflection { * @access public */ function getMethods() { - return array_unique(get_class_methods($this->_interface)); + return array_unique(get_class_methods($this->interface)); } /** @@ -103,11 +103,11 @@ class SimpleReflection { * @access public */ function getInterfaces() { - $reflection = new ReflectionClass($this->_interface); + $reflection = new ReflectionClass($this->interface); if ($reflection->isInterface()) { - return array($this->_interface); + return array($this->interface); } - return $this->_onlyParents($reflection->getInterfaces()); + return $this->onlyParents($reflection->getInterfaces()); } /** @@ -131,7 +131,7 @@ class SimpleReflection { * @returns boolean True if enforced. * @access private */ - function _isInterfaceMethod($method) { + protected function isInterfaceMethod($method) { return in_array($method, $this->getInterfaceMethods()); } @@ -141,7 +141,7 @@ class SimpleReflection { * @access public */ function getParent() { - $reflection = new ReflectionClass($this->_interface); + $reflection = new ReflectionClass($this->interface); $parent = $reflection->getParentClass(); if ($parent) { return $parent->getName(); @@ -155,7 +155,7 @@ class SimpleReflection { * @access public */ function isAbstract() { - $reflection = new ReflectionClass($this->_interface); + $reflection = new ReflectionClass($this->interface); return $reflection->isAbstract(); } @@ -165,7 +165,7 @@ class SimpleReflection { * @access public */ function isInterface() { - $reflection = new ReflectionClass($this->_interface); + $reflection = new ReflectionClass($this->interface); return $reflection->isInterface(); } @@ -176,7 +176,7 @@ class SimpleReflection { * @access public */ function hasFinal() { - $reflection = new ReflectionClass($this->_interface); + $reflection = new ReflectionClass($this->interface); foreach ($reflection->getMethods() as $method) { if ($method->isFinal()) { return true; @@ -193,7 +193,7 @@ class SimpleReflection { * @returns array List of parent interface names. * @access private */ - function _onlyParents($interfaces) { + protected function onlyParents($interfaces) { $parents = array(); $blacklist = array(); foreach ($interfaces as $interface) { @@ -218,8 +218,8 @@ class SimpleReflection { * @return bool true if method is abstract, else false * @access private */ - function _isAbstractMethod($name) { - $interface = new ReflectionClass($this->_interface); + protected function isAbstractMethod($name) { + $interface = new ReflectionClass($this->interface); if (! $interface->hasMethod($name)) { return false; } @@ -232,8 +232,8 @@ class SimpleReflection { * @return bool true if method is the constructor * @access private */ - function _isConstructor($name) { - return ($name == '__construct') || ($name == $this->_interface); + protected function isConstructor($name) { + return ($name == '__construct') || ($name == $this->interface); } /** @@ -242,8 +242,8 @@ class SimpleReflection { * @return bool true if method is abstract in parent, else false * @access private */ - function _isAbstractMethodInParents($name) { - $interface = new ReflectionClass($this->_interface); + protected function isAbstractMethodInParents($name) { + $interface = new ReflectionClass($this->interface); $parent = $interface->getParentClass(); while($parent) { if (! $parent->hasMethod($name)) { @@ -263,8 +263,8 @@ class SimpleReflection { * @return bool true if method is static, else false * @access private */ - function _isStaticMethod($name) { - $interface = new ReflectionClass($this->_interface); + protected function isStaticMethod($name) { + $interface = new ReflectionClass($this->interface); if (! $interface->hasMethod($name)) { return false; } @@ -294,13 +294,19 @@ class SimpleReflection { if ($name == '__toString') { return "function $name()"; } - if ($this->_isInterfaceMethod($name) || - $this->_isAbstractMethod($name) || - $this->_isAbstractMethodInParents($name) || - $this->_isStaticMethod($name)) { - return $this->_getFullSignature($name); + + // This wonky try-catch is a work around for a faulty method_exists() + // in early versions of PHP 5 which would return false for static + // methods. The Reflection classes work fine, but hasMethod() + // doesn't exist prior to PHP 5.1.0, so we need to use a more crude + // detection method. + try { + $interface = new ReflectionClass($this->interface); + $interface->getMethod($name); + } catch (ReflectionException $e) { + return "function $name()"; } - return "function $name()"; + return $this->getFullSignature($name); } /** @@ -311,13 +317,13 @@ class SimpleReflection { * bracket. * @access private */ - function _getFullSignature($name) { - $interface = new ReflectionClass($this->_interface); + protected function getFullSignature($name) { + $interface = new ReflectionClass($this->interface); $method = $interface->getMethod($name); $reference = $method->returnsReference() ? '&' : ''; $static = $method->isStatic() ? 'static ' : ''; return "{$static}function $reference$name(" . - implode(', ', $this->_getParameterSignatures($method)) . + implode(', ', $this->getParameterSignatures($method)) . ")"; } @@ -329,7 +335,7 @@ class SimpleReflection { * a snippet of code. * @access private */ - function _getParameterSignatures($method) { + protected function getParameterSignatures($method) { $signatures = array(); foreach ($method->getParameters() as $parameter) { $signature = ''; @@ -342,8 +348,8 @@ class SimpleReflection { if ($parameter->isPassedByReference()) { $signature .= '&'; } - $signature .= '$' . $this->_suppressSpurious($parameter->getName()); - if ($this->_isOptional($parameter)) { + $signature .= '$' . $this->suppressSpurious($parameter->getName()); + if ($this->isOptional($parameter)) { $signature .= ' = null'; } $signatures[] = $signature; @@ -359,7 +365,7 @@ class SimpleReflection { * @return string Cleaner name. * @access private */ - function _suppressSpurious($name) { + protected function suppressSpurious($name) { return str_replace(array('[', ']', ' '), '', $name); } @@ -370,11 +376,11 @@ class SimpleReflection { * @return boolean True if optional. * @access private */ - function _isOptional($parameter) { + protected function isOptional($parameter) { if (method_exists($parameter, 'isOptional')) { return $parameter->isOptional(); } return false; } } -?> +?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/remote.php b/contrib/simpletest/simpletest/remote.php index 8889ed7b..4bb37b7c 100644 --- a/contrib/simpletest/simpletest/remote.php +++ b/contrib/simpletest/simpletest/remote.php @@ -3,7 +3,7 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: remote.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: remote.php 2011 2011-04-29 08:22:48Z pp11 $ */ /**#@+ @@ -20,29 +20,29 @@ require_once(dirname(__FILE__) . '/test_case.php'); * @subpackage UnitTester */ class RemoteTestCase { - var $_url; - var $_dry_url; - var $_size; - + private $url; + private $dry_url; + private $size; + /** * Sets the location of the remote test. * @param string $url Test location. * @param string $dry_url Location for dry run. * @access public */ - function RemoteTestCase($url, $dry_url = false) { - $this->_url = $url; - $this->_dry_url = $dry_url ? $dry_url : $url; - $this->_size = false; + function __construct($url, $dry_url = false) { + $this->url = $url; + $this->dry_url = $dry_url ? $dry_url : $url; + $this->size = false; } - + /** * Accessor for the test name for subclasses. * @return string Name of the test. * @access public */ function getLabel() { - return $this->_url; + return $this->url; } /** @@ -53,65 +53,63 @@ class RemoteTestCase { * @returns boolean True if no failures. * @access public */ - function run(&$reporter) { - $browser = &$this->_createBrowser(); - $xml = $browser->get($this->_url); + function run($reporter) { + $browser = $this->createBrowser(); + $xml = $browser->get($this->url); if (! $xml) { - trigger_error('Cannot read remote test URL [' . $this->_url . ']'); + trigger_error('Cannot read remote test URL [' . $this->url . ']'); return false; } - $parser = &$this->_createParser($reporter); + $parser = $this->createParser($reporter); if (! $parser->parse($xml)) { - trigger_error('Cannot parse incoming XML from [' . $this->_url . ']'); + trigger_error('Cannot parse incoming XML from [' . $this->url . ']'); return false; } return true; } - + /** * Creates a new web browser object for fetching * the XML report. * @return SimpleBrowser New browser. * @access protected */ - function &_createBrowser() { - $browser = &new SimpleBrowser(); - return $browser; + protected function createBrowser() { + return new SimpleBrowser(); } - + /** * Creates the XML parser. * @param SimpleReporter $reporter Target of test results. * @return SimpleTestXmlListener XML reader. * @access protected */ - function &_createParser(&$reporter) { - $parser = &new SimpleTestXmlParser($reporter); - return $parser; + protected function createParser($reporter) { + return new SimpleTestXmlParser($reporter); } - + /** * Accessor for the number of subtests. * @return integer Number of test cases. * @access public */ function getSize() { - if ($this->_size === false) { - $browser = &$this->_createBrowser(); - $xml = $browser->get($this->_dry_url); + if ($this->size === false) { + $browser = $this->createBrowser(); + $xml = $browser->get($this->dry_url); if (! $xml) { - trigger_error('Cannot read remote test URL [' . $this->_dry_url . ']'); + trigger_error('Cannot read remote test URL [' . $this->dry_url . ']'); return false; } - $reporter = &new SimpleReporter(); - $parser = &$this->_createParser($reporter); + $reporter = new SimpleReporter(); + $parser = $this->createParser($reporter); if (! $parser->parse($xml)) { - trigger_error('Cannot parse incoming XML from [' . $this->_dry_url . ']'); + trigger_error('Cannot parse incoming XML from [' . $this->dry_url . ']'); return false; } - $this->_size = $reporter->getTestCaseCount(); + $this->size = $reporter->getTestCaseCount(); } - return $this->_size; + return $this->size; } } ?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/reporter.php b/contrib/simpletest/simpletest/reporter.php old mode 100644 new mode 100755 index a13eff8c..bd4f3fa4 --- a/contrib/simpletest/simpletest/reporter.php +++ b/contrib/simpletest/simpletest/reporter.php @@ -3,13 +3,14 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: reporter.php 1702 2008-03-25 00:08:04Z lastcraft $ + * @version $Id: reporter.php 2005 2010-11-02 14:09:34Z lastcraft $ */ /**#@+ * include other SimpleTest class files */ require_once(dirname(__FILE__) . '/scorer.php'); +//require_once(dirname(__FILE__) . '/arguments.php'); /**#@-*/ /** @@ -19,7 +20,7 @@ require_once(dirname(__FILE__) . '/scorer.php'); * @subpackage UnitTester */ class HtmlReporter extends SimpleReporter { - var $_character_set; + private $character_set; /** * Does nothing yet. The first output will @@ -27,9 +28,9 @@ class HtmlReporter extends SimpleReporter { * by a web browser. * @access public */ - function HtmlReporter($character_set = 'ISO-8859-1') { - $this->SimpleReporter(); - $this->_character_set = $character_set; + function __construct($character_set = 'ISO-8859-1') { + parent::__construct(); + $this->character_set = $character_set; } /** @@ -43,9 +44,9 @@ class HtmlReporter extends SimpleReporter { print ""; print "\n\n$test_name\n"; print "\n"; + $this->character_set . "\">\n"; print "\n"; print "\n\n"; print "

$test_name

\n"; @@ -57,9 +58,8 @@ class HtmlReporter extends SimpleReporter { * reloaded on every request. Otherwise you could be * scratching your head over out of date test data. * @access public - * @static */ - function sendNoCacheHeaders() { + static function sendNoCacheHeaders() { if (! headers_sent()) { header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); @@ -74,7 +74,7 @@ class HtmlReporter extends SimpleReporter { * @return string CSS code as text. * @access protected */ - function _getCss() { + protected function getCss() { return ".fail { background-color: inherit; color: red; }" . ".pass { background-color: inherit; color: green; }" . " pre { background-color: lightgray; color: inherit; }"; @@ -106,7 +106,6 @@ class HtmlReporter extends SimpleReporter { * top level test. * @param string $message Failure message displayed in * the context of the other tests. - * @access public */ function paintFail($message) { parent::paintFail($message); @@ -114,7 +113,7 @@ class HtmlReporter extends SimpleReporter { $breadcrumb = $this->getTestList(); array_shift($breadcrumb); print implode(" -> ", $breadcrumb); - print " -> " . $this->_htmlEntities($message) . "
\n"; + print " -> " . $this->htmlEntities($message) . "
\n"; } /** @@ -128,7 +127,7 @@ class HtmlReporter extends SimpleReporter { $breadcrumb = $this->getTestList(); array_shift($breadcrumb); print implode(" -> ", $breadcrumb); - print " -> " . $this->_htmlEntities($message) . "
\n"; + print " -> " . $this->htmlEntities($message) . "
\n"; } /** @@ -146,9 +145,9 @@ class HtmlReporter extends SimpleReporter { '] with message ['. $exception->getMessage() . '] in ['. $exception->getFile() . ' line ' . $exception->getLine() . ']'; - print " -> " . $this->_htmlEntities($message) . "
\n"; + print " -> " . $this->htmlEntities($message) . "
\n"; } - + /** * Prints the message for skipping tests. * @param string $message Text of skip condition. @@ -160,16 +159,16 @@ class HtmlReporter extends SimpleReporter { $breadcrumb = $this->getTestList(); array_shift($breadcrumb); print implode(" -> ", $breadcrumb); - print " -> " . $this->_htmlEntities($message) . "
\n"; + print " -> " . $this->htmlEntities($message) . "
\n"; } /** - * Paints formatted text such as dumped variables. + * Paints formatted text such as dumped privateiables. * @param string $message Text to show. * @access public */ function paintFormattedMessage($message) { - print '
' . $this->_htmlEntities($message) . '
'; + print '
' . $this->htmlEntities($message) . '
'; } /** @@ -178,8 +177,8 @@ class HtmlReporter extends SimpleReporter { * @return string Browser readable message. * @access protected */ - function _htmlEntities($message) { - return htmlentities($message, ENT_COMPAT, $this->_character_set); + protected function htmlEntities($message) { + return htmlentities($message, ENT_COMPAT, $this->character_set); } } @@ -197,10 +196,9 @@ class TextReporter extends SimpleReporter { /** * Does nothing yet. The first output will * be sent on the first test start. - * @access public */ - function TextReporter() { - $this->SimpleReporter(); + function __construct() { + parent::__construct(); } /** @@ -283,7 +281,7 @@ class TextReporter extends SimpleReporter { print "\tin " . implode("\n\tin ", array_reverse($breadcrumb)); print "\n"; } - + /** * Prints the message for skipping tests. * @param string $message Text of skip condition. @@ -295,7 +293,7 @@ class TextReporter extends SimpleReporter { } /** - * Paints formatted text such as dumped variables. + * Paints formatted text such as dumped privateiables. * @param string $message Text to show. * @access public */ @@ -312,10 +310,10 @@ class TextReporter extends SimpleReporter { * @subpackage UnitTester */ class SelectiveReporter extends SimpleReporterDecorator { - var $_just_this_case = false; - var $_just_this_test = false; - var $_on; - + private $just_this_case = false; + private $just_this_test = false; + private $on; + /** * Selects the test case or group to be run, * and optionally a specific test. @@ -323,17 +321,17 @@ class SelectiveReporter extends SimpleReporterDecorator { * @param string $just_this_case Only this case or group will run. * @param string $just_this_test Only this test method will run. */ - function SelectiveReporter(&$reporter, $just_this_case = false, $just_this_test = false) { + function __construct($reporter, $just_this_case = false, $just_this_test = false) { if (isset($just_this_case) && $just_this_case) { - $this->_just_this_case = strtolower($just_this_case); - $this->_off(); + $this->just_this_case = strtolower($just_this_case); + $this->off(); } else { - $this->_on(); + $this->on(); } if (isset($just_this_test) && $just_this_test) { - $this->_just_this_test = strtolower($just_this_test); + $this->just_this_test = strtolower($just_this_test); } - $this->SimpleReporterDecorator($reporter); + parent::__construct($reporter); } /** @@ -342,8 +340,8 @@ class SelectiveReporter extends SimpleReporterDecorator { * @return boolean True if matched. * @access protected */ - function _matchesTestCase($test_case) { - return $this->_just_this_case == strtolower($test_case); + protected function matchesTestCase($test_case) { + return $this->just_this_case == strtolower($test_case); } /** @@ -354,40 +352,40 @@ class SelectiveReporter extends SimpleReporterDecorator { * @return boolean True if matched. * @access protected */ - function _shouldRunTest($test_case, $method) { - if ($this->_isOn() || $this->_matchesTestCase($test_case)) { - if ($this->_just_this_test) { - return $this->_just_this_test == strtolower($method); + protected function shouldRunTest($test_case, $method) { + if ($this->isOn() || $this->matchesTestCase($test_case)) { + if ($this->just_this_test) { + return $this->just_this_test == strtolower($method); } else { return true; } } return false; } - + /** * Switch on testing for the group or subgroup. * @access private */ - function _on() { - $this->_on = true; + protected function on() { + $this->on = true; } - + /** * Switch off testing for the group or subgroup. * @access private */ - function _off() { - $this->_on = false; + protected function off() { + $this->on = false; } - + /** * Is this group actually being tested? * @return boolean True if the current test group is active. * @access private */ - function _isOn() { - return $this->_on; + protected function isOn() { + return $this->on; } /** @@ -398,8 +396,8 @@ class SelectiveReporter extends SimpleReporterDecorator { * @access public */ function shouldInvoke($test_case, $method) { - if ($this->_shouldRunTest($test_case, $method)) { - return $this->_reporter->shouldInvoke($test_case, $method); + if ($this->shouldRunTest($test_case, $method)) { + return $this->reporter->shouldInvoke($test_case, $method); } return false; } @@ -411,10 +409,10 @@ class SelectiveReporter extends SimpleReporterDecorator { * @access public */ function paintGroupStart($test_case, $size) { - if ($this->_just_this_case && $this->_matchesTestCase($test_case)) { - $this->_on(); + if ($this->just_this_case && $this->matchesTestCase($test_case)) { + $this->on(); } - $this->_reporter->paintGroupStart($test_case, $size); + $this->reporter->paintGroupStart($test_case, $size); } /** @@ -423,9 +421,9 @@ class SelectiveReporter extends SimpleReporterDecorator { * @access public */ function paintGroupEnd($test_case) { - $this->_reporter->paintGroupEnd($test_case); - if ($this->_just_this_case && $this->_matchesTestCase($test_case)) { - $this->_off(); + $this->reporter->paintGroupEnd($test_case); + if ($this->just_this_case && $this->matchesTestCase($test_case)) { + $this->off(); } } } @@ -436,7 +434,7 @@ class SelectiveReporter extends SimpleReporterDecorator { * @subpackage UnitTester */ class NoSkipsReporter extends SimpleReporterDecorator { - + /** * Does nothing. * @param string $message Text of skip condition. diff --git a/contrib/simpletest/simpletest/scorer.php b/contrib/simpletest/simpletest/scorer.php index cc1331b8..27776f4b 100644 --- a/contrib/simpletest/simpletest/scorer.php +++ b/contrib/simpletest/simpletest/scorer.php @@ -3,7 +3,7 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: scorer.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: scorer.php 2011 2011-04-29 08:22:48Z pp11 $ */ /**#@+*/ @@ -19,20 +19,20 @@ require_once(dirname(__FILE__) . '/invoker.php'); * @abstract */ class SimpleScorer { - var $_passes; - var $_fails; - var $_exceptions; - var $_is_dry_run; + private $passes; + private $fails; + private $exceptions; + private $is_dry_run; /** * Starts the test run with no results. * @access public */ - function SimpleScorer() { - $this->_passes = 0; - $this->_fails = 0; - $this->_exceptions = 0; - $this->_is_dry_run = false; + function __construct() { + $this->passes = 0; + $this->fails = 0; + $this->exceptions = 0; + $this->is_dry_run = false; } /** @@ -43,7 +43,7 @@ class SimpleScorer { * @access public */ function makeDry($is_dry = true) { - $this->_is_dry_run = $is_dry; + $this->is_dry_run = $is_dry; } /** @@ -53,7 +53,7 @@ class SimpleScorer { * @access public */ function shouldInvoke($test_case_name, $method) { - return ! $this->_is_dry_run; + return ! $this->is_dry_run; } /** @@ -63,7 +63,7 @@ class SimpleScorer { * @return SimpleInvoker Wrapped test runner. * @access public */ - function &createInvoker(&$invoker) { + function createInvoker($invoker) { return $invoker; } @@ -75,7 +75,7 @@ class SimpleScorer { * @access public */ function getStatus() { - if ($this->_exceptions + $this->_fails > 0) { + if ($this->exceptions + $this->fails > 0) { return false; } return true; @@ -136,7 +136,7 @@ class SimpleScorer { * @access public */ function paintPass($message) { - $this->_passes++; + $this->passes++; } /** @@ -145,7 +145,7 @@ class SimpleScorer { * @access public */ function paintFail($message) { - $this->_fails++; + $this->fails++; } /** @@ -155,7 +155,7 @@ class SimpleScorer { * @access public */ function paintError($message) { - $this->_exceptions++; + $this->exceptions++; } /** @@ -164,9 +164,9 @@ class SimpleScorer { * @access public */ function paintException($exception) { - $this->_exceptions++; + $this->exceptions++; } - + /** * Prints the message for skipping tests. * @param string $message Text of skip condition. @@ -181,7 +181,7 @@ class SimpleScorer { * @access public */ function getPassCount() { - return $this->_passes; + return $this->passes; } /** @@ -190,7 +190,7 @@ class SimpleScorer { * @access public */ function getFailCount() { - return $this->_fails; + return $this->fails; } /** @@ -200,7 +200,7 @@ class SimpleScorer { * @access public */ function getExceptionCount() { - return $this->_exceptions; + return $this->exceptions; } /** @@ -213,7 +213,7 @@ class SimpleScorer { /** * Paints a formatted ASCII message such as a - * variable dump. + * privateiable dump. * @param string $message Text to display. * @access public */ @@ -239,24 +239,23 @@ class SimpleScorer { * @subpackage UnitTester */ class SimpleReporter extends SimpleScorer { - var $_test_stack; - var $_size; - var $_progress; + private $test_stack; + private $size; + private $progress; /** * Starts the display with no results in. * @access public */ - function SimpleReporter() { - $this->SimpleScorer(); - $this->_test_stack = array(); - $this->_size = null; - $this->_progress = 0; + function __construct() { + parent::__construct(); + $this->test_stack = array(); + $this->size = null; + $this->progress = 0; } - + /** - * Gets the formatter for variables and other small - * generic data items. + * Gets the formatter for small generic data items. * @return SimpleDumper Formatter. * @access public */ @@ -274,13 +273,13 @@ class SimpleReporter extends SimpleScorer { * @access public */ function paintGroupStart($test_name, $size) { - if (! isset($this->_size)) { - $this->_size = $size; + if (! isset($this->size)) { + $this->size = $size; } - if (count($this->_test_stack) == 0) { + if (count($this->test_stack) == 0) { $this->paintHeader($test_name); } - $this->_test_stack[] = $test_name; + $this->test_stack[] = $test_name; } /** @@ -291,8 +290,8 @@ class SimpleReporter extends SimpleScorer { * @access public */ function paintGroupEnd($test_name) { - array_pop($this->_test_stack); - if (count($this->_test_stack) == 0) { + array_pop($this->test_stack); + if (count($this->test_stack) == 0) { $this->paintFooter($test_name); } } @@ -306,13 +305,13 @@ class SimpleReporter extends SimpleScorer { * @access public */ function paintCaseStart($test_name) { - if (! isset($this->_size)) { - $this->_size = 1; + if (! isset($this->size)) { + $this->size = 1; } - if (count($this->_test_stack) == 0) { + if (count($this->test_stack) == 0) { $this->paintHeader($test_name); } - $this->_test_stack[] = $test_name; + $this->test_stack[] = $test_name; } /** @@ -322,9 +321,9 @@ class SimpleReporter extends SimpleScorer { * @access public */ function paintCaseEnd($test_name) { - $this->_progress++; - array_pop($this->_test_stack); - if (count($this->_test_stack) == 0) { + $this->progress++; + array_pop($this->test_stack); + if (count($this->test_stack) == 0) { $this->paintFooter($test_name); } } @@ -335,7 +334,7 @@ class SimpleReporter extends SimpleScorer { * @access public */ function paintMethodStart($test_name) { - $this->_test_stack[] = $test_name; + $this->test_stack[] = $test_name; } /** @@ -345,7 +344,7 @@ class SimpleReporter extends SimpleScorer { * @access public */ function paintMethodEnd($test_name) { - array_pop($this->_test_stack); + array_pop($this->test_stack); } /** @@ -375,7 +374,7 @@ class SimpleReporter extends SimpleScorer { * @access public */ function getTestList() { - return $this->_test_stack; + return $this->test_stack; } /** @@ -386,7 +385,7 @@ class SimpleReporter extends SimpleScorer { * @access public */ function getTestCaseCount() { - return $this->_size; + return $this->size; } /** @@ -396,16 +395,15 @@ class SimpleReporter extends SimpleScorer { * @access public */ function getTestCaseProgress() { - return $this->_progress; + return $this->progress; } /** * Static check for running in the comand line. * @return boolean True if CLI. * @access public - * @static */ - function inCli() { + static function inCli() { return php_sapi_name() == 'cli'; } } @@ -416,14 +414,14 @@ class SimpleReporter extends SimpleScorer { * @subpackage UnitTester */ class SimpleReporterDecorator { - var $_reporter; + protected $reporter; /** * Mediates between the reporter and the test case. * @param SimpleScorer $reporter Reporter to receive events. */ - function SimpleReporterDecorator(&$reporter) { - $this->_reporter = &$reporter; + function __construct($reporter) { + $this->reporter = $reporter; } /** @@ -434,7 +432,7 @@ class SimpleReporterDecorator { * @access public */ function makeDry($is_dry = true) { - $this->_reporter->makeDry($is_dry); + $this->reporter->makeDry($is_dry); } /** @@ -445,39 +443,53 @@ class SimpleReporterDecorator { * @access public */ function getStatus() { - return $this->_reporter->getStatus(); + return $this->reporter->getStatus(); + } + + /** + * The nesting of the test cases so far. Not + * all reporters have this facility. + * @return array Test list if accessible. + * @access public + */ + function getTestList() { + if (method_exists($this->reporter, 'getTestList')) { + return $this->reporter->getTestList(); + } else { + return array(); + } } /** * The reporter has a veto on what should be run. - * @param string $test_case_name name of test case. + * @param string $test_case_name Name of test case. * @param string $method Name of test method. * @return boolean True if test should be run. * @access public */ function shouldInvoke($test_case_name, $method) { - return $this->_reporter->shouldInvoke($test_case_name, $method); + return $this->reporter->shouldInvoke($test_case_name, $method); } /** - * Can wrap the invoker in preperation for running + * Can wrap the invoker in preparation for running * a test. * @param SimpleInvoker $invoker Individual test runner. * @return SimpleInvoker Wrapped test runner. * @access public */ - function &createInvoker(&$invoker) { - return $this->_reporter->createInvoker($invoker); + function createInvoker($invoker) { + return $this->reporter->createInvoker($invoker); } - + /** - * Gets the formatter for variables and other small + * Gets the formatter for privateiables and other small * generic data items. * @return SimpleDumper Formatter. * @access public */ function getDumper() { - return $this->_reporter->getDumper(); + return $this->reporter->getDumper(); } /** @@ -487,7 +499,7 @@ class SimpleReporterDecorator { * @access public */ function paintGroupStart($test_name, $size) { - $this->_reporter->paintGroupStart($test_name, $size); + $this->reporter->paintGroupStart($test_name, $size); } /** @@ -496,7 +508,7 @@ class SimpleReporterDecorator { * @access public */ function paintGroupEnd($test_name) { - $this->_reporter->paintGroupEnd($test_name); + $this->reporter->paintGroupEnd($test_name); } /** @@ -505,7 +517,7 @@ class SimpleReporterDecorator { * @access public */ function paintCaseStart($test_name) { - $this->_reporter->paintCaseStart($test_name); + $this->reporter->paintCaseStart($test_name); } /** @@ -514,7 +526,7 @@ class SimpleReporterDecorator { * @access public */ function paintCaseEnd($test_name) { - $this->_reporter->paintCaseEnd($test_name); + $this->reporter->paintCaseEnd($test_name); } /** @@ -523,7 +535,7 @@ class SimpleReporterDecorator { * @access public */ function paintMethodStart($test_name) { - $this->_reporter->paintMethodStart($test_name); + $this->reporter->paintMethodStart($test_name); } /** @@ -532,7 +544,7 @@ class SimpleReporterDecorator { * @access public */ function paintMethodEnd($test_name) { - $this->_reporter->paintMethodEnd($test_name); + $this->reporter->paintMethodEnd($test_name); } /** @@ -541,7 +553,7 @@ class SimpleReporterDecorator { * @access public */ function paintPass($message) { - $this->_reporter->paintPass($message); + $this->reporter->paintPass($message); } /** @@ -550,7 +562,7 @@ class SimpleReporterDecorator { * @access public */ function paintFail($message) { - $this->_reporter->paintFail($message); + $this->reporter->paintFail($message); } /** @@ -560,7 +572,7 @@ class SimpleReporterDecorator { * @access public */ function paintError($message) { - $this->_reporter->paintError($message); + $this->reporter->paintError($message); } /** @@ -569,16 +581,16 @@ class SimpleReporterDecorator { * @access public */ function paintException($exception) { - $this->_reporter->paintException($exception); + $this->reporter->paintException($exception); } - + /** * Prints the message for skipping tests. * @param string $message Text of skip condition. * @access public */ function paintSkip($message) { - $this->_reporter->paintSkip($message); + $this->reporter->paintSkip($message); } /** @@ -587,7 +599,7 @@ class SimpleReporterDecorator { * @access public */ function paintMessage($message) { - $this->_reporter->paintMessage($message); + $this->reporter->paintMessage($message); } /** @@ -596,7 +608,7 @@ class SimpleReporterDecorator { * @access public */ function paintFormattedMessage($message) { - $this->_reporter->paintFormattedMessage($message); + $this->reporter->paintFormattedMessage($message); } /** @@ -608,8 +620,8 @@ class SimpleReporterDecorator { * test suite. * @access public */ - function paintSignal($type, &$payload) { - $this->_reporter->paintSignal($type, $payload); + function paintSignal($type, $payload) { + $this->reporter->paintSignal($type, $payload); } } @@ -620,15 +632,15 @@ class SimpleReporterDecorator { * @subpackage UnitTester */ class MultipleReporter { - var $_reporters = array(); + private $reporters = array(); /** * Adds a reporter to the subscriber list. * @param SimpleScorer $reporter Reporter to receive events. * @access public */ - function attachReporter(&$reporter) { - $this->_reporters[] = &$reporter; + function attachReporter($reporter) { + $this->reporters[] = $reporter; } /** @@ -639,8 +651,8 @@ class MultipleReporter { * @access public */ function makeDry($is_dry = true) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->makeDry($is_dry); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->makeDry($is_dry); } } @@ -653,8 +665,8 @@ class MultipleReporter { * @access public */ function getStatus() { - for ($i = 0; $i < count($this->_reporters); $i++) { - if (! $this->_reporters[$i]->getStatus()) { + for ($i = 0; $i < count($this->reporters); $i++) { + if (! $this->reporters[$i]->getStatus()) { return false; } } @@ -669,8 +681,8 @@ class MultipleReporter { * @access public */ function shouldInvoke($test_case_name, $method) { - for ($i = 0; $i < count($this->_reporters); $i++) { - if (! $this->_reporters[$i]->shouldInvoke($test_case_name, $method)) { + for ($i = 0; $i < count($this->reporters); $i++) { + if (! $this->reporters[$i]->shouldInvoke($test_case_name, $method)) { return false; } } @@ -683,15 +695,15 @@ class MultipleReporter { * @return SimpleInvoker Wrapped test runner. * @access public */ - function &createInvoker(&$invoker) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $invoker = &$this->_reporters[$i]->createInvoker($invoker); + function createInvoker($invoker) { + for ($i = 0; $i < count($this->reporters); $i++) { + $invoker = $this->reporters[$i]->createInvoker($invoker); } return $invoker; } - + /** - * Gets the formatter for variables and other small + * Gets the formatter for privateiables and other small * generic data items. * @return SimpleDumper Formatter. * @access public @@ -707,8 +719,8 @@ class MultipleReporter { * @access public */ function paintGroupStart($test_name, $size) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintGroupStart($test_name, $size); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintGroupStart($test_name, $size); } } @@ -718,8 +730,8 @@ class MultipleReporter { * @access public */ function paintGroupEnd($test_name) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintGroupEnd($test_name); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintGroupEnd($test_name); } } @@ -729,8 +741,8 @@ class MultipleReporter { * @access public */ function paintCaseStart($test_name) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintCaseStart($test_name); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintCaseStart($test_name); } } @@ -740,8 +752,8 @@ class MultipleReporter { * @access public */ function paintCaseEnd($test_name) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintCaseEnd($test_name); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintCaseEnd($test_name); } } @@ -751,8 +763,8 @@ class MultipleReporter { * @access public */ function paintMethodStart($test_name) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintMethodStart($test_name); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintMethodStart($test_name); } } @@ -762,8 +774,8 @@ class MultipleReporter { * @access public */ function paintMethodEnd($test_name) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintMethodEnd($test_name); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintMethodEnd($test_name); } } @@ -773,8 +785,8 @@ class MultipleReporter { * @access public */ function paintPass($message) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintPass($message); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintPass($message); } } @@ -784,8 +796,8 @@ class MultipleReporter { * @access public */ function paintFail($message) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintFail($message); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintFail($message); } } @@ -796,19 +808,19 @@ class MultipleReporter { * @access public */ function paintError($message) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintError($message); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintError($message); } } - + /** * Chains to the wrapped reporter. * @param Exception $exception Exception to display. * @access public */ function paintException($exception) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintException($exception); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintException($exception); } } @@ -818,8 +830,8 @@ class MultipleReporter { * @access public */ function paintSkip($message) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintSkip($message); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintSkip($message); } } @@ -829,8 +841,8 @@ class MultipleReporter { * @access public */ function paintMessage($message) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintMessage($message); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintMessage($message); } } @@ -840,8 +852,8 @@ class MultipleReporter { * @access public */ function paintFormattedMessage($message) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintFormattedMessage($message); + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintFormattedMessage($message); } } @@ -854,9 +866,9 @@ class MultipleReporter { * test suite. * @access public */ - function paintSignal($type, &$payload) { - for ($i = 0; $i < count($this->_reporters); $i++) { - $this->_reporters[$i]->paintSignal($type, $payload); + function paintSignal($type, $payload) { + for ($i = 0; $i < count($this->reporters); $i++) { + $this->reporters[$i]->paintSignal($type, $payload); } } } diff --git a/contrib/simpletest/simpletest/selector.php b/contrib/simpletest/simpletest/selector.php old mode 100644 new mode 100755 index de044b85..ba2fed31 --- a/contrib/simpletest/simpletest/selector.php +++ b/contrib/simpletest/simpletest/selector.php @@ -3,7 +3,7 @@ * Base include file for SimpleTest. * @package SimpleTest * @subpackage WebTester - * @version $Id: selector.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: selector.php 1786 2008-04-26 17:32:20Z pp11 $ */ /**#@+ @@ -20,18 +20,22 @@ require_once(dirname(__FILE__) . '/encoding.php'); * @subpackage WebTester */ class SimpleByName { - var $_name; + private $name; /** * Stashes the name for later comparison. * @param string $name Name attribute to match. */ - function SimpleByName($name) { - $this->_name = $name; + function __construct($name) { + $this->name = $name; } + /** + * Accessor for name. + * @returns string $name Name to match. + */ function getName() { - return $this->_name; + return $this->name; } /** @@ -40,7 +44,7 @@ class SimpleByName { * @access public */ function isMatch($widget) { - return ($widget->getName() == $this->_name); + return ($widget->getName() == $this->name); } } @@ -51,14 +55,14 @@ class SimpleByName { * @subpackage WebTester */ class SimpleByLabel { - var $_label; + private $label; /** * Stashes the name for later comparison. * @param string $label Visible text to match. */ - function SimpleByLabel($label) { - $this->_label = $label; + function __construct($label) { + $this->label = $label; } /** @@ -71,7 +75,7 @@ class SimpleByLabel { if (! method_exists($widget, 'isLabel')) { return false; } - return $widget->isLabel($this->_label); + return $widget->isLabel($this->label); } } @@ -82,14 +86,14 @@ class SimpleByLabel { * @subpackage WebTester */ class SimpleById { - var $_id; + private $id; /** * Stashes the name for later comparison. * @param string $id ID atribute to match. */ - function SimpleById($id) { - $this->_id = $id; + function __construct($id) { + $this->id = $id; } /** @@ -98,7 +102,7 @@ class SimpleById { * @access public */ function isMatch($widget) { - return $widget->isId($this->_id); + return $widget->isId($this->id); } } @@ -109,14 +113,14 @@ class SimpleById { * @subpackage WebTester */ class SimpleByLabelOrName { - var $_label; + private $label; /** * Stashes the name/label for later comparison. * @param string $label Visible text to match. */ - function SimpleByLabelOrName($label) { - $this->_label = $label; + function __construct($label) { + $this->label = $label; } /** @@ -127,11 +131,11 @@ class SimpleByLabelOrName { */ function isMatch($widget) { if (method_exists($widget, 'isLabel')) { - if ($widget->isLabel($this->_label)) { + if ($widget->isLabel($this->label)) { return true; } } - return ($widget->getName() == $this->_label); + return ($widget->getName() == $this->label); } } ?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/shell_tester.php b/contrib/simpletest/simpletest/shell_tester.php index 7b98869e..9a3bd389 100644 --- a/contrib/simpletest/simpletest/shell_tester.php +++ b/contrib/simpletest/simpletest/shell_tester.php @@ -3,7 +3,7 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: shell_tester.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: shell_tester.php 2011 2011-04-29 08:22:48Z pp11 $ */ /**#@+ @@ -18,14 +18,14 @@ require_once(dirname(__FILE__) . '/test_case.php'); * @subpackage UnitTester */ class SimpleShell { - var $_output; + private $output; /** * Executes the shell comand and stashes the output. * @access public */ - function SimpleShell() { - $this->_output = false; + function __construct() { + $this->output = false; } /** @@ -37,8 +37,8 @@ class SimpleShell { * @access public */ function execute($command) { - $this->_output = false; - exec($command, $this->_output, $ret); + $this->output = false; + exec($command, $this->output, $ret); return $ret; } @@ -48,7 +48,7 @@ class SimpleShell { * @access public */ function getOutput() { - return implode("\n", $this->_output); + return implode("\n", $this->output); } /** @@ -57,7 +57,7 @@ class SimpleShell { * @access public */ function getOutputAsList() { - return $this->_output; + return $this->output; } } @@ -69,9 +69,9 @@ class SimpleShell { * @subpackage UnitTester */ class ShellTestCase extends SimpleTestCase { - var $_current_shell; - var $_last_status; - var $_last_command; + private $current_shell; + private $last_status; + private $last_command; /** * Creates an empty test case. Should be subclassed @@ -80,11 +80,11 @@ class ShellTestCase extends SimpleTestCase { * the class name if none specified. * @access public */ - function ShellTestCase($label = false) { - $this->SimpleTestCase($label); - $this->_current_shell = &$this->_createShell(); - $this->_last_status = false; - $this->_last_command = ''; + function __construct($label = false) { + parent::__construct($label); + $this->current_shell = $this->createShell(); + $this->last_status = false; + $this->last_command = ''; } /** @@ -94,10 +94,10 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function execute($command) { - $shell = &$this->_getShell(); - $this->_last_status = $shell->execute($command); - $this->_last_command = $command; - return ($this->_last_status === 0); + $shell = $this->getShell(); + $this->last_status = $shell->execute($command); + $this->last_command = $command; + return ($this->last_status === 0); } /** @@ -114,7 +114,7 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function getOutput() { - $shell = &$this->_getShell(); + $shell = $this->getShell(); return $shell->getOutput(); } @@ -124,7 +124,7 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function getOutputAsList() { - $shell = &$this->_getShell(); + $shell = $this->getShell(); return $shell->getOutputAsList(); } @@ -154,7 +154,7 @@ class ShellTestCase extends SimpleTestCase { function assertFalse($result, $message = '%s') { return $this->assert(new FalseExpectation(), $result, $message); } - + /** * Will trigger a pass if the two parameters have * the same value only. Otherwise a fail. This @@ -171,7 +171,7 @@ class ShellTestCase extends SimpleTestCase { $second, $message); } - + /** * Will trigger a pass if the two parameters have * a different value. Otherwise a fail. This @@ -199,9 +199,9 @@ class ShellTestCase extends SimpleTestCase { */ function assertExitCode($status, $message = "%s") { $message = sprintf($message, "Expected status code of [$status] from [" . - $this->_last_command . "], but got [" . - $this->_last_status . "]"); - return $this->assertTrue($status === $this->_last_status, $message); + $this->last_command . "], but got [" . + $this->last_status . "]"); + return $this->assertTrue($status === $this->last_status, $message); } /** @@ -213,7 +213,7 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function assertOutput($expected, $message = "%s") { - $shell = &$this->_getShell(); + $shell = $this->getShell(); return $this->assert( new EqualExpectation($expected), $shell->getOutput(), @@ -229,7 +229,7 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function assertOutputPattern($pattern, $message = "%s") { - $shell = &$this->_getShell(); + $shell = $this->getShell(); return $this->assert( new PatternExpectation($pattern), $shell->getOutput(), @@ -245,7 +245,7 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function assertNoOutputPattern($pattern, $message = "%s") { - $shell = &$this->_getShell(); + $shell = $this->getShell(); return $this->assert( new NoPatternExpectation($pattern), $shell->getOutput(), @@ -286,7 +286,6 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function assertFilePattern($pattern, $path, $message = "%s") { - $shell = &$this->_getShell(); return $this->assert( new PatternExpectation($pattern), implode('', file($path)), @@ -303,7 +302,6 @@ class ShellTestCase extends SimpleTestCase { * @access public */ function assertNoFilePattern($pattern, $path, $message = "%s") { - $shell = &$this->_getShell(); return $this->assert( new NoPatternExpectation($pattern), implode('', file($path)), @@ -316,8 +314,8 @@ class ShellTestCase extends SimpleTestCase { * @return Shell Current shell. * @access protected */ - function &_getShell() { - return $this->_current_shell; + protected function getShell() { + return $this->current_shell; } /** @@ -325,9 +323,8 @@ class ShellTestCase extends SimpleTestCase { * @return Shell New shell object. * @access protected */ - function &_createShell() { - $shell = &new SimpleShell(); - return $shell; + protected function createShell() { + return new SimpleShell(); } } -?> +?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/simpletest.php b/contrib/simpletest/simpletest/simpletest.php index bab2c1a6..425c869a 100644 --- a/contrib/simpletest/simpletest/simpletest.php +++ b/contrib/simpletest/simpletest/simpletest.php @@ -3,17 +3,13 @@ * Global state for SimpleTest and kicker script in future versions. * @package SimpleTest * @subpackage UnitTester - * @version $Id: simpletest.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: simpletest.php 2011 2011-04-29 08:22:48Z pp11 $ */ /**#@+ * include SimpleTest files */ -if (version_compare(phpversion(), '5') >= 0) { - require_once(dirname(__FILE__) . '/reflection_php5.php'); -} else { - require_once(dirname(__FILE__) . '/reflection_php4.php'); -} +require_once(dirname(__FILE__) . '/reflection_php5.php'); require_once(dirname(__FILE__) . '/default_reporter.php'); require_once(dirname(__FILE__) . '/compatibility.php'); /**#@-*/ @@ -29,10 +25,8 @@ class SimpleTest { /** * Reads the SimpleTest version from the release file. * @return string Version string. - * @static - * @access public */ - function getVersion() { + static function getVersion() { $content = file(dirname(__FILE__) . '/VERSION'); return trim($content[0]); } @@ -40,14 +34,10 @@ class SimpleTest { /** * Sets the name of a test case to ignore, usually * because the class is an abstract case that should - * not be run. Once PHP4 is dropped this will disappear - * as a public method and "abstract" will rule. * @param string $class Add a class to ignore. - * @static - * @access public */ - function ignore($class) { - $registry = &SimpleTest::_getRegistry(); + static function ignore($class) { + $registry = &SimpleTest::getRegistry(); $registry['IgnoreList'][strtolower($class)] = true; } @@ -63,11 +53,9 @@ class SimpleTest { * the ignore() calls. It's just nice to have the ignore() * calls at the top of the file before the actual declarations. * @param array $classes Class names of interest. - * @static - * @access public */ - function ignoreParentsIfIgnored($classes) { - $registry = &SimpleTest::_getRegistry(); + static function ignoreParentsIfIgnored($classes) { + $registry = &SimpleTest::getRegistry(); foreach ($classes as $class) { if (SimpleTest::isIgnored($class)) { $reflection = new SimpleReflection($class); @@ -83,13 +71,11 @@ class SimpleTest { * which can be retrieved with SimpleTest :: preferred() method. * Instances of the same class are overwritten. * @param object $object Preferred object - * @static - * @access public * @see preferred() */ - function prefer(&$object) { - $registry = &SimpleTest::_getRegistry(); - $registry['Preferred'][] = &$object; + static function prefer($object) { + $registry = &SimpleTest::getRegistry(); + $registry['Preferred'][] = $object; } /** @@ -97,16 +83,14 @@ class SimpleTest { * can be applied in order to retrieve the object of the specific * class * @param array|string $classes Allowed classes or interfaces. - * @static - * @access public * @return array|object|null * @see prefer() */ - function &preferred($classes) { + static function preferred($classes) { if (! is_array($classes)) { $classes = array($classes); } - $registry = &SimpleTest::_getRegistry(); + $registry = &SimpleTest::getRegistry(); for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) { foreach ($classes as $class) { if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) { @@ -125,30 +109,12 @@ class SimpleTest { * use it. * @param string $class Class name to test. * @return boolean True if should not be run. - * @access public - * @static */ - function isIgnored($class) { - $registry = &SimpleTest::_getRegistry(); + static function isIgnored($class) { + $registry = &SimpleTest::getRegistry(); return isset($registry['IgnoreList'][strtolower($class)]); } - /** - * @deprecated - */ - function setMockBaseClass($mock_base) { - $registry = &SimpleTest::_getRegistry(); - $registry['MockBaseClass'] = $mock_base; - } - - /** - * @deprecated - */ - function getMockBaseClass() { - $registry = &SimpleTest::_getRegistry(); - return $registry['MockBaseClass']; - } - /** * Sets proxy to use on all requests for when * testing from behind a firewall. Set host @@ -157,10 +123,9 @@ class SimpleTest { * @param string $proxy Proxy host as URL. * @param string $username Proxy username for authentication. * @param string $password Proxy password for authentication. - * @access public */ - function useProxy($proxy, $username = false, $password = false) { - $registry = &SimpleTest::_getRegistry(); + static function useProxy($proxy, $username = false, $password = false) { + $registry = &SimpleTest::getRegistry(); $registry['DefaultProxy'] = $proxy; $registry['DefaultProxyUsername'] = $username; $registry['DefaultProxyPassword'] = $password; @@ -169,43 +134,60 @@ class SimpleTest { /** * Accessor for default proxy host. * @return string Proxy URL. - * @access public */ - function getDefaultProxy() { - $registry = &SimpleTest::_getRegistry(); + static function getDefaultProxy() { + $registry = &SimpleTest::getRegistry(); return $registry['DefaultProxy']; } /** * Accessor for default proxy username. * @return string Proxy username for authentication. - * @access public */ - function getDefaultProxyUsername() { - $registry = &SimpleTest::_getRegistry(); + static function getDefaultProxyUsername() { + $registry = &SimpleTest::getRegistry(); return $registry['DefaultProxyUsername']; } /** * Accessor for default proxy password. * @return string Proxy password for authentication. - * @access public */ - function getDefaultProxyPassword() { - $registry = &SimpleTest::_getRegistry(); + static function getDefaultProxyPassword() { + $registry = &SimpleTest::getRegistry(); return $registry['DefaultProxyPassword']; } + /** + * Accessor for default HTML parsers. + * @return array List of parsers to try in + * order until one responds true + * to can(). + */ + static function getParsers() { + $registry = &SimpleTest::getRegistry(); + return $registry['Parsers']; + } + + /** + * Set the list of HTML parsers to attempt to use by default. + * @param array $parsers List of parsers to try in + * order until one responds true + * to can(). + */ + static function setParsers($parsers) { + $registry = &SimpleTest::getRegistry(); + $registry['Parsers'] = $parsers; + } + /** * Accessor for global registry of options. * @return hash All stored values. - * @access private - * @static */ - function &_getRegistry() { + protected static function &getRegistry() { static $registry = false; if (! $registry) { - $registry = SimpleTest::_getDefaults(); + $registry = SimpleTest::getDefaults(); } return $registry; } @@ -214,10 +196,8 @@ class SimpleTest { * Accessor for the context of the current * test run. * @return SimpleTestContext Current test run. - * @access public - * @static */ - function &getContext() { + static function getContext() { static $context = false; if (! $context) { $context = new SimpleTestContext(); @@ -228,12 +208,10 @@ class SimpleTest { /** * Constant default values. * @return hash All registry defaults. - * @access private - * @static */ - function _getDefaults() { + protected static function getDefaults() { return array( - 'StubBaseClass' => 'SimpleStub', + 'Parsers' => false, 'MockBaseClass' => 'SimpleMock', 'IgnoreList' => array(), 'DefaultProxy' => false, @@ -241,6 +219,22 @@ class SimpleTest { 'DefaultProxyPassword' => false, 'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter())); } + + /** + * @deprecated + */ + static function setMockBaseClass($mock_base) { + $registry = &SimpleTest::getRegistry(); + $registry['MockBaseClass'] = $mock_base; + } + + /** + * @deprecated + */ + static function getMockBaseClass() { + $registry = &SimpleTest::getRegistry(); + return $registry['MockBaseClass']; + } } /** @@ -252,16 +246,16 @@ class SimpleTest { * @package SimpleTest */ class SimpleTestContext { - var $_test; - var $_reporter; - var $_resources; + private $test; + private $reporter; + private $resources; /** * Clears down the current context. * @access public */ function clear() { - $this->_resources = array(); + $this->resources = array(); } /** @@ -269,20 +263,18 @@ class SimpleTestContext { * global instance can be used by the mock objects * to send message to the test cases. * @param SimpleTestCase $test Test case to register. - * @access public */ - function setTest(&$test) { + function setTest($test) { $this->clear(); - $this->_test = &$test; + $this->test = $test; } /** * Accessor for currently running test case. * @return SimpleTestCase Current test. - * @access public */ - function &getTest() { - return $this->_test; + function getTest() { + return $this->test; } /** @@ -290,33 +282,29 @@ class SimpleTestContext { * global instance can be used by the mock objects * to send messages. * @param SimpleReporter $reporter Reporter to register. - * @access public */ - function setReporter(&$reporter) { + function setReporter($reporter) { $this->clear(); - $this->_reporter = &$reporter; + $this->reporter = $reporter; } /** * Accessor for current reporter. * @return SimpleReporter Current reporter. - * @access public */ - function &getReporter() { - return $this->_reporter; + function getReporter() { + return $this->reporter; } /** * Accessor for the Singleton resource. * @return object Global resource. - * @access public - * @static */ - function &get($resource) { - if (! isset($this->_resources[$resource])) { - $this->_resources[$resource] = &new $resource(); + function get($resource) { + if (! isset($this->resources[$resource])) { + $this->resources[$resource] = new $resource(); } - return $this->_resources[$resource]; + return $this->resources[$resource]; } } @@ -327,15 +315,15 @@ class SimpleTestContext { * @subpackage UnitTester */ class SimpleStackTrace { - var $_prefixes; + private $prefixes; /** * Stashes the list of target prefixes. * @param array $prefixes List of method prefixes * to search for. */ - function SimpleStackTrace($prefixes) { - $this->_prefixes = $prefixes; + function __construct($prefixes) { + $this->prefixes = $prefixes; } /** @@ -344,15 +332,14 @@ class SimpleStackTrace { * @param array $stack List of stack frames. * @return string Snippet of test report with line * number and file. - * @access public */ function traceMethod($stack = false) { - $stack = $stack ? $stack : $this->_captureTrace(); + $stack = $stack ? $stack : $this->captureTrace(); foreach ($stack as $frame) { - if ($this->_frameLiesWithinSimpleTestFolder($frame)) { + if ($this->frameLiesWithinSimpleTestFolder($frame)) { continue; } - if ($this->_frameMatchesPrefix($frame)) { + if ($this->frameMatchesPrefix($frame)) { return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']'; } } @@ -363,9 +350,8 @@ class SimpleStackTrace { * Test to see if error is generated by SimpleTest itself. * @param array $frame PHP stack frame. * @return boolean True if a SimpleTest file. - * @access private */ - function _frameLiesWithinSimpleTestFolder($frame) { + protected function frameLiesWithinSimpleTestFolder($frame) { if (isset($frame['file'])) { $path = substr(SIMPLE_TEST, 0, -1); if (strpos($frame['file'], $path) === 0) { @@ -381,10 +367,9 @@ class SimpleStackTrace { * Tries to determine if the method call is an assert, etc. * @param array $frame PHP stack frame. * @return boolean True if matches a target. - * @access private */ - function _frameMatchesPrefix($frame) { - foreach ($this->_prefixes as $prefix) { + protected function frameMatchesPrefix($frame) { + foreach ($this->prefixes as $prefix) { if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) { return true; } @@ -395,84 +380,12 @@ class SimpleStackTrace { /** * Grabs a current stack trace. * @return array Fulle trace. - * @access private */ - function _captureTrace() { + protected function captureTrace() { if (function_exists('debug_backtrace')) { return array_reverse(debug_backtrace()); } return array(); } } - -/** - * @package SimpleTest - * @subpackage UnitTester - * @deprecated - */ -class SimpleTestOptions extends SimpleTest { - - /** - * @deprecated - */ - function getVersion() { - return Simpletest::getVersion(); - } - - /** - * @deprecated - */ - function ignore($class) { - return Simpletest::ignore($class); - } - - /** - * @deprecated - */ - function isIgnored($class) { - return Simpletest::isIgnored($class); - } - - /** - * @deprecated - */ - function setMockBaseClass($mock_base) { - return Simpletest::setMockBaseClass($mock_base); - } - - /** - * @deprecated - */ - function getMockBaseClass() { - return Simpletest::getMockBaseClass(); - } - - /** - * @deprecated - */ - function useProxy($proxy, $username = false, $password = false) { - return Simpletest::useProxy($proxy, $username, $password); - } - - /** - * @deprecated - */ - function getDefaultProxy() { - return Simpletest::getDefaultProxy(); - } - - /** - * @deprecated - */ - function getDefaultProxyUsername() { - return Simpletest::getDefaultProxyUsername(); - } - - /** - * @deprecated - */ - function getDefaultProxyPassword() { - return Simpletest::getDefaultProxyPassword(); - } -} -?> +?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/socket.php b/contrib/simpletest/simpletest/socket.php old mode 100644 new mode 100755 index 3ad5a9ff..06e8ca62 --- a/contrib/simpletest/simpletest/socket.php +++ b/contrib/simpletest/simpletest/socket.php @@ -3,7 +3,7 @@ * base include file for SimpleTest * @package SimpleTest * @subpackage MockObjects - * @version $Id: socket.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: socket.php 1953 2009-09-20 01:26:25Z jsweat $ */ /**#@+ @@ -19,14 +19,14 @@ require_once(dirname(__FILE__) . '/compatibility.php'); * @subpackage WebTester */ class SimpleStickyError { - var $_error = 'Constructor not chained'; + private $error = 'Constructor not chained'; /** * Sets the error to empty. * @access public */ - function SimpleStickyError() { - $this->_clearError(); + function __construct() { + $this->clearError(); } /** @@ -35,7 +35,7 @@ class SimpleStickyError { * @access public */ function isError() { - return ($this->_error != ''); + return ($this->error != ''); } /** @@ -45,7 +45,7 @@ class SimpleStickyError { * @access public */ function getError() { - return $this->_error; + return $this->error; } /** @@ -53,16 +53,112 @@ class SimpleStickyError { * @param string Error message to stash. * @access protected */ - function _setError($error) { - $this->_error = $error; + function setError($error) { + $this->error = $error; } /** * Resets the error state to no error. * @access protected */ - function _clearError() { - $this->_setError(''); + function clearError() { + $this->setError(''); + } +} + +/** + * @package SimpleTest + * @subpackage WebTester + */ +class SimpleFileSocket extends SimpleStickyError { + private $handle; + private $is_open = false; + private $sent = ''; + private $block_size; + + /** + * Opens a socket for reading and writing. + * @param SimpleUrl $file Target URI to fetch. + * @param integer $block_size Size of chunk to read. + * @access public + */ + function __construct($file, $block_size = 1024) { + parent::__construct(); + if (! ($this->handle = $this->openFile($file, $error))) { + $file_string = $file->asString(); + $this->setError("Cannot open [$file_string] with [$error]"); + return; + } + $this->is_open = true; + $this->block_size = $block_size; + } + + /** + * Writes some data to the socket and saves alocal copy. + * @param string $message String to send to socket. + * @return boolean True if successful. + * @access public + */ + function write($message) { + return true; + } + + /** + * Reads data from the socket. The error suppresion + * is a workaround for PHP4 always throwing a warning + * with a secure socket. + * @return integer/boolean Incoming bytes. False + * on error. + * @access public + */ + function read() { + $raw = @fread($this->handle, $this->block_size); + if ($raw === false) { + $this->setError('Cannot read from socket'); + $this->close(); + } + return $raw; + } + + /** + * Accessor for socket open state. + * @return boolean True if open. + * @access public + */ + function isOpen() { + return $this->is_open; + } + + /** + * Closes the socket preventing further reads. + * Cannot be reopened once closed. + * @return boolean True if successful. + * @access public + */ + function close() { + if (!$this->is_open) return false; + $this->is_open = false; + return fclose($this->handle); + } + + /** + * Accessor for content so far. + * @return string Bytes sent only. + * @access public + */ + function getSent() { + return $this->sent; + } + + /** + * Actually opens the low level socket. + * @param SimpleUrl $file SimpleUrl file target. + * @param string $error Recipient of error message. + * @param integer $timeout Maximum time to wait for connection. + * @access protected + */ + protected function openFile($file, &$error) { + return @fopen($file->asString(), 'r'); } } @@ -72,10 +168,10 @@ class SimpleStickyError { * @subpackage WebTester */ class SimpleSocket extends SimpleStickyError { - var $_handle; - var $_is_open = false; - var $_sent = ''; - var $lock_size; + private $handle; + private $is_open = false; + private $sent = ''; + private $lock_size; /** * Opens a socket for reading and writing. @@ -85,15 +181,15 @@ class SimpleSocket extends SimpleStickyError { * @param integer $block_size Size of chunk to read. * @access public */ - function SimpleSocket($host, $port, $timeout, $block_size = 255) { - $this->SimpleStickyError(); - if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) { - $this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds"); + function __construct($host, $port, $timeout, $block_size = 255) { + parent::__construct(); + if (! ($this->handle = $this->openSocket($host, $port, $error_number, $error, $timeout))) { + $this->setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds"); return; } - $this->_is_open = true; - $this->_block_size = $block_size; - SimpleTestCompatibility::setTimeout($this->_handle, $timeout); + $this->is_open = true; + $this->block_size = $block_size; + SimpleTestCompatibility::setTimeout($this->handle, $timeout); } /** @@ -106,16 +202,16 @@ class SimpleSocket extends SimpleStickyError { if ($this->isError() || ! $this->isOpen()) { return false; } - $count = fwrite($this->_handle, $message); + $count = fwrite($this->handle, $message); if (! $count) { if ($count === false) { - $this->_setError('Cannot write to socket'); + $this->setError('Cannot write to socket'); $this->close(); } return false; } - fflush($this->_handle); - $this->_sent .= $message; + fflush($this->handle); + $this->sent .= $message; return true; } @@ -131,9 +227,9 @@ class SimpleSocket extends SimpleStickyError { if ($this->isError() || ! $this->isOpen()) { return false; } - $raw = @fread($this->_handle, $this->_block_size); + $raw = @fread($this->handle, $this->block_size); if ($raw === false) { - $this->_setError('Cannot read from socket'); + $this->setError('Cannot read from socket'); $this->close(); } return $raw; @@ -145,7 +241,7 @@ class SimpleSocket extends SimpleStickyError { * @access public */ function isOpen() { - return $this->_is_open; + return $this->is_open; } /** @@ -155,8 +251,8 @@ class SimpleSocket extends SimpleStickyError { * @access public */ function close() { - $this->_is_open = false; - return fclose($this->_handle); + $this->is_open = false; + return fclose($this->handle); } /** @@ -165,7 +261,7 @@ class SimpleSocket extends SimpleStickyError { * @access public */ function getSent() { - return $this->_sent; + return $this->sent; } /** @@ -177,7 +273,7 @@ class SimpleSocket extends SimpleStickyError { * @param integer $timeout Maximum time to wait for connection. * @access protected */ - function _openSocket($host, $port, &$error_number, &$error, $timeout) { + protected function openSocket($host, $port, &$error_number, &$error, $timeout) { return @fsockopen($host, $port, $error_number, $error, $timeout); } } @@ -196,8 +292,8 @@ class SimpleSecureSocket extends SimpleSocket { * @param integer $timeout Connection timeout in seconds. * @access public */ - function SimpleSecureSocket($host, $port, $timeout) { - $this->SimpleSocket($host, $port, $timeout); + function __construct($host, $port, $timeout) { + parent::__construct($host, $port, $timeout); } /** @@ -209,8 +305,8 @@ class SimpleSecureSocket extends SimpleSocket { * @param integer $timeout Maximum time to wait for connection. * @access protected */ - function _openSocket($host, $port, &$error_number, &$error, $timeout) { - return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout); + function openSocket($host, $port, &$error_number, &$error, $timeout) { + return parent::openSocket("tls://$host", $port, $error_number, $error, $timeout); } } ?> \ No newline at end of file diff --git a/contrib/simpletest/simpletest/tag.php b/contrib/simpletest/simpletest/tag.php index 7bccae20..afe649ec 100644 --- a/contrib/simpletest/simpletest/tag.php +++ b/contrib/simpletest/simpletest/tag.php @@ -3,26 +3,121 @@ * Base include file for SimpleTest. * @package SimpleTest * @subpackage WebTester - * @version $Id: tag.php 1723 2008-04-08 00:34:10Z lastcraft $ + * @version $Id: tag.php 2011 2011-04-29 08:22:48Z pp11 $ */ - + /**#@+ * include SimpleTest files */ -require_once(dirname(__FILE__) . '/parser.php'); +require_once(dirname(__FILE__) . '/page.php'); require_once(dirname(__FILE__) . '/encoding.php'); /**#@-*/ +/** + * Creates tags and widgets given HTML tag + * attributes. + * @package SimpleTest + * @subpackage WebTester + */ +class SimpleTagBuilder { + + /** + * Factory for the tag objects. Creates the + * appropriate tag object for the incoming tag name + * and attributes. + * @param string $name HTML tag name. + * @param hash $attributes Element attributes. + * @return SimpleTag Tag object. + * @access public + */ + function createTag($name, $attributes) { + static $map = array( + 'a' => 'SimpleAnchorTag', + 'title' => 'SimpleTitleTag', + 'base' => 'SimpleBaseTag', + 'button' => 'SimpleButtonTag', + 'textarea' => 'SimpleTextAreaTag', + 'option' => 'SimpleOptionTag', + 'label' => 'SimpleLabelTag', + 'form' => 'SimpleFormTag', + 'frame' => 'SimpleFrameTag'); + $attributes = $this->keysToLowerCase($attributes); + if (array_key_exists($name, $map)) { + $tag_class = $map[$name]; + return new $tag_class($attributes); + } elseif ($name == 'select') { + return $this->createSelectionTag($attributes); + } elseif ($name == 'input') { + return $this->createInputTag($attributes); + } + return new SimpleTag($name, $attributes); + } + + /** + * Factory for selection fields. + * @param hash $attributes Element attributes. + * @return SimpleTag Tag object. + * @access protected + */ + protected function createSelectionTag($attributes) { + if (isset($attributes['multiple'])) { + return new MultipleSelectionTag($attributes); + } + return new SimpleSelectionTag($attributes); + } + + /** + * Factory for input tags. + * @param hash $attributes Element attributes. + * @return SimpleTag Tag object. + * @access protected + */ + protected function createInputTag($attributes) { + if (! isset($attributes['type'])) { + return new SimpleTextTag($attributes); + } + $type = strtolower(trim($attributes['type'])); + $map = array( + 'submit' => 'SimpleSubmitTag', + 'image' => 'SimpleImageSubmitTag', + 'checkbox' => 'SimpleCheckboxTag', + 'radio' => 'SimpleRadioButtonTag', + 'text' => 'SimpleTextTag', + 'hidden' => 'SimpleTextTag', + 'password' => 'SimpleTextTag', + 'file' => 'SimpleUploadTag'); + if (array_key_exists($type, $map)) { + $tag_class = $map[$type]; + return new $tag_class($attributes); + } + return false; + } + + /** + * Make the keys lower case for case insensitive look-ups. + * @param hash $map Hash to convert. + * @return hash Unchanged values, but keys lower case. + * @access private + */ + protected function keysToLowerCase($map) { + $lower = array(); + foreach ($map as $key => $value) { + $lower[strtolower($key)] = $value; + } + return $lower; + } +} + /** * HTML or XML tag. * @package SimpleTest * @subpackage WebTester */ class SimpleTag { - var $_name; - var $_attributes; - var $_content; - + private $name; + private $attributes; + private $content; + /** * Starts with a named tag with attributes only. * @param string $name Tag name. @@ -31,12 +126,12 @@ class SimpleTag { * the keys must have been * converted to lower case. */ - function SimpleTag($name, $attributes) { - $this->_name = strtolower(trim($name)); - $this->_attributes = $attributes; - $this->_content = ''; + function __construct($name, $attributes) { + $this->name = strtolower(trim($name)); + $this->attributes = $attributes; + $this->content = ''; } - + /** * Check to see if the tag can have both start and * end tags with content in between. @@ -46,7 +141,7 @@ class SimpleTag { function expectEndTag() { return true; } - + /** * The current tag should not swallow all content for * itself as it's searchable page content. Private @@ -66,26 +161,37 @@ class SimpleTag { * @access public */ function addContent($content) { - $this->_content .= (string)$content; + $this->content .= (string)$content; + return $this; } - + /** * Adds an enclosed tag to the content. * @param SimpleTag $tag New tag. * @access public */ - function addTag(&$tag) { + function addTag($tag) { } - + + /** + * Adds multiple enclosed tags to the content. + * @param array List of SimpleTag objects to be added. + */ + function addTags($tags) { + foreach ($tags as $tag) { + $this->addTag($tag); + } + } + /** * Accessor for tag name. * @return string Name of tag. * @access public */ function getTagName() { - return $this->_name; + return $this->name; } - + /** * List of legal child elements. * @return array List of element names. @@ -94,7 +200,7 @@ class SimpleTag { function getChildElements() { return array(); } - + /** * Accessor for an attribute. * @param string $label Attribute name. @@ -103,31 +209,31 @@ class SimpleTag { */ function getAttribute($label) { $label = strtolower($label); - if (! isset($this->_attributes[$label])) { + if (! isset($this->attributes[$label])) { return false; } - return (string)$this->_attributes[$label]; + return (string)$this->attributes[$label]; } - + /** * Sets an attribute. * @param string $label Attribute name. * @return string $value New attribute value. * @access protected */ - function _setAttribute($label, $value) { - $this->_attributes[strtolower($label)] = $value; + protected function setAttribute($label, $value) { + $this->attributes[strtolower($label)] = $value; } - + /** * Accessor for the whole content so far. * @return string Content as big raw string. * @access public */ function getContent() { - return $this->_content; + return $this->content; } - + /** * Accessor for content reduced to visible text. Acts * like a text mode browser, normalising space and @@ -136,9 +242,9 @@ class SimpleTag { * @access public */ function getText() { - return SimpleHtmlSaxParser::normalise($this->_content); + return SimplePage::normalise($this->content); } - + /** * Test to see if id attribute matches. * @param string $id ID to test against. @@ -156,14 +262,14 @@ class SimpleTag { * @subpackage WebTester */ class SimpleBaseTag extends SimpleTag { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleBaseTag($attributes) { - $this->SimpleTag('base', $attributes); + function __construct($attributes) { + parent::__construct('base', $attributes); } /** @@ -182,14 +288,14 @@ class SimpleBaseTag extends SimpleTag { * @subpackage WebTester */ class SimpleTitleTag extends SimpleTag { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleTitleTag($attributes) { - $this->SimpleTag('title', $attributes); + function __construct($attributes) { + parent::__construct('title', $attributes); } } @@ -199,16 +305,16 @@ class SimpleTitleTag extends SimpleTag { * @subpackage WebTester */ class SimpleAnchorTag extends SimpleTag { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleAnchorTag($attributes) { - $this->SimpleTag('a', $attributes); + function __construct($attributes) { + parent::__construct('a', $attributes); } - + /** * Accessor for URL as string. * @return string Coerced as string. @@ -229,33 +335,33 @@ class SimpleAnchorTag extends SimpleTag { * @subpackage WebTester */ class SimpleWidget extends SimpleTag { - var $_value; - var $_label; - var $_is_set; - + private $value; + private $label; + private $is_set; + /** * Starts with a named tag with attributes only. * @param string $name Tag name. * @param hash $attributes Attribute names and * string values. */ - function SimpleWidget($name, $attributes) { - $this->SimpleTag($name, $attributes); - $this->_value = false; - $this->_label = false; - $this->_is_set = false; + function __construct($name, $attributes) { + parent::__construct($name, $attributes); + $this->value = false; + $this->label = false; + $this->is_set = false; } - + /** * Accessor for name submitted as the key in - * GET/POST variables hash. + * GET/POST privateiables hash. * @return string Parsed value. * @access public */ function getName() { return $this->getAttribute('name'); } - + /** * Accessor for default value parsed with the tag. * @return string Parsed value. @@ -264,7 +370,7 @@ class SimpleWidget extends SimpleTag { function getDefault() { return $this->getAttribute('value'); } - + /** * Accessor for currently set value or default if * none. @@ -273,12 +379,12 @@ class SimpleWidget extends SimpleTag { * @access public */ function getValue() { - if (! $this->_is_set) { + if (! $this->is_set) { return $this->getDefault(); } - return $this->_value; + return $this->value; } - + /** * Sets the current form element value. * @param string $value New value. @@ -286,20 +392,20 @@ class SimpleWidget extends SimpleTag { * @access public */ function setValue($value) { - $this->_value = $value; - $this->_is_set = true; + $this->value = $value; + $this->is_set = true; return true; } - + /** * Resets the form element value back to the * default. * @access public */ function resetValue() { - $this->_is_set = false; + $this->is_set = false; } - + /** * Allows setting of a label externally, say by a * label tag. @@ -307,9 +413,10 @@ class SimpleWidget extends SimpleTag { * @access public */ function setLabel($label) { - $this->_label = trim($label); + $this->label = trim($label); + return $this; } - + /** * Reads external or internal label. * @param string $label Label to test. @@ -317,15 +424,15 @@ class SimpleWidget extends SimpleTag { * @access public */ function isLabel($label) { - return $this->_label == trim($label); + return $this->label == trim($label); } - + /** * Dispatches the value into the form encoded packet. * @param SimpleEncoding $encoding Form packet. * @access public */ - function write(&$encoding) { + function write($encoding) { if ($this->getName()) { $encoding->add($this->getName(), $this->getValue()); } @@ -338,19 +445,19 @@ class SimpleWidget extends SimpleTag { * @subpackage WebTester */ class SimpleTextTag extends SimpleWidget { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleTextTag($attributes) { - $this->SimpleWidget('input', $attributes); + function __construct($attributes) { + parent::__construct('input', $attributes); if ($this->getAttribute('value') === false) { - $this->_setAttribute('value', ''); + $this->setAttribute('value', ''); } } - + /** * Tag contains no content. * @return boolean False. @@ -359,7 +466,7 @@ class SimpleTextTag extends SimpleWidget { function expectEndTag() { return false; } - + /** * Sets the current form element value. Cannot * change the value of a hidden field. @@ -381,19 +488,19 @@ class SimpleTextTag extends SimpleWidget { * @subpackage WebTester */ class SimpleSubmitTag extends SimpleWidget { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleSubmitTag($attributes) { - $this->SimpleWidget('input', $attributes); + function __construct($attributes) { + parent::__construct('input', $attributes); if ($this->getAttribute('value') === false) { - $this->_setAttribute('value', 'Submit'); + $this->setAttribute('value', 'Submit'); } } - + /** * Tag contains no end element. * @return boolean False. @@ -402,7 +509,7 @@ class SimpleSubmitTag extends SimpleWidget { function expectEndTag() { return false; } - + /** * Disables the setting of the button value. * @param string $value Ignored. @@ -412,7 +519,7 @@ class SimpleSubmitTag extends SimpleWidget { function setValue($value) { return false; } - + /** * Value of browser visible text. * @return string Visible label. @@ -421,7 +528,7 @@ class SimpleSubmitTag extends SimpleWidget { function getLabel() { return $this->getValue(); } - + /** * Test for a label match when searching. * @param string $label Label to test. @@ -432,23 +539,23 @@ class SimpleSubmitTag extends SimpleWidget { return trim($label) == trim($this->getLabel()); } } - + /** * Image button as input tag. * @package SimpleTest * @subpackage WebTester */ class SimpleImageSubmitTag extends SimpleWidget { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleImageSubmitTag($attributes) { - $this->SimpleWidget('input', $attributes); + function __construct($attributes) { + parent::__construct('input', $attributes); } - + /** * Tag contains no end element. * @return boolean False. @@ -457,7 +564,7 @@ class SimpleImageSubmitTag extends SimpleWidget { function expectEndTag() { return false; } - + /** * Disables the setting of the button value. * @param string $value Ignored. @@ -467,7 +574,7 @@ class SimpleImageSubmitTag extends SimpleWidget { function setValue($value) { return false; } - + /** * Value of browser visible text. * @return string Visible label. @@ -479,7 +586,7 @@ class SimpleImageSubmitTag extends SimpleWidget { } return $this->getAttribute('alt'); } - + /** * Test for a label match when searching. * @param string $label Label to test. @@ -489,7 +596,7 @@ class SimpleImageSubmitTag extends SimpleWidget { function isLabel($label) { return trim($label) == trim($this->getLabel()); } - + /** * Dispatches the value into the form encoded packet. * @param SimpleEncoding $encoding Form packet. @@ -497,7 +604,7 @@ class SimpleImageSubmitTag extends SimpleWidget { * @param integer $y Y coordinate of click. * @access public */ - function write(&$encoding, $x, $y) { + function write($encoding, $x = 1, $y = 1) { if ($this->getName()) { $encoding->add($this->getName() . '.x', $x); $encoding->add($this->getName() . '.y', $y); @@ -507,24 +614,24 @@ class SimpleImageSubmitTag extends SimpleWidget { } } } - + /** * Submit button as button tag. * @package SimpleTest * @subpackage WebTester */ class SimpleButtonTag extends SimpleWidget { - + /** * Starts with a named tag with attributes only. * Defaults are very browser dependent. * @param hash $attributes Attribute names and * string values. */ - function SimpleButtonTag($attributes) { - $this->SimpleWidget('button', $attributes); + function __construct($attributes) { + parent::__construct('button', $attributes); } - + /** * Check to see if the tag can have both start and * end tags with content in between. @@ -534,7 +641,7 @@ class SimpleButtonTag extends SimpleWidget { function expectEndTag() { return true; } - + /** * Disables the setting of the button value. * @param string $value Ignored. @@ -544,7 +651,7 @@ class SimpleButtonTag extends SimpleWidget { function setValue($value) { return false; } - + /** * Value of browser visible text. * @return string Visible label. @@ -553,7 +660,7 @@ class SimpleButtonTag extends SimpleWidget { function getLabel() { return $this->getContent(); } - + /** * Test for a label match when searching. * @param string $label Label to test. @@ -571,25 +678,25 @@ class SimpleButtonTag extends SimpleWidget { * @subpackage WebTester */ class SimpleTextAreaTag extends SimpleWidget { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleTextAreaTag($attributes) { - $this->SimpleWidget('textarea', $attributes); + function __construct($attributes) { + parent::__construct('textarea', $attributes); } - + /** * Accessor for starting value. * @return string Parsed value. * @access public */ function getDefault() { - return $this->_wrap(SimpleHtmlSaxParser::decodeHtml($this->getContent())); + return $this->wrap(html_entity_decode($this->getContent(), ENT_QUOTES)); } - + /** * Applies word wrapping if needed. * @param string $value New value. @@ -597,15 +704,15 @@ class SimpleTextAreaTag extends SimpleWidget { * @access public */ function setValue($value) { - return parent::setValue($this->_wrap($value)); + return parent::setValue($this->wrap($value)); } - + /** * Test to see if text should be wrapped. * @return boolean True if wrapping on. * @access private */ - function _wrapIsEnabled() { + function wrapIsEnabled() { if ($this->getAttribute('cols')) { $wrap = $this->getAttribute('wrap'); if (($wrap == 'physical') || ($wrap == 'hard')) { @@ -614,7 +721,7 @@ class SimpleTextAreaTag extends SimpleWidget { } return false; } - + /** * Performs the formatting that is peculiar to * this tag. There is strange behaviour in this @@ -625,13 +732,13 @@ class SimpleTextAreaTag extends SimpleWidget { * returns and line feeds * @access private */ - function _wrap($text) { + protected function wrap($text) { $text = str_replace("\r\r\n", "\r\n", str_replace("\n", "\r\n", $text)); $text = str_replace("\r\n\n", "\r\n", str_replace("\r", "\r\n", $text)); if (strncmp($text, "\r\n", strlen("\r\n")) == 0) { $text = substr($text, strlen("\r\n")); } - if ($this->_wrapIsEnabled()) { + if ($this->wrapIsEnabled()) { return wordwrap( $text, (integer)$this->getAttribute('cols'), @@ -639,7 +746,7 @@ class SimpleTextAreaTag extends SimpleWidget { } return $text; } - + /** * The content of textarea is not part of the page. * @return boolean True. @@ -656,16 +763,16 @@ class SimpleTextAreaTag extends SimpleWidget { * @subpackage WebTester */ class SimpleUploadTag extends SimpleWidget { - + /** * Starts with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleUploadTag($attributes) { - $this->SimpleWidget('input', $attributes); + function __construct($attributes) { + parent::__construct('input', $attributes); } - + /** * Tag contains no content. * @return boolean False. @@ -674,13 +781,13 @@ class SimpleUploadTag extends SimpleWidget { function expectEndTag() { return false; } - + /** * Dispatches the value into the form encoded packet. * @param SimpleEncoding $encoding Form packet. * @access public */ - function write(&$encoding) { + function write($encoding) { if (! file_exists($this->getValue())) { return; } @@ -697,39 +804,40 @@ class SimpleUploadTag extends SimpleWidget { * @subpackage WebTester */ class SimpleSelectionTag extends SimpleWidget { - var $_options; - var $_choice; - + private $options; + private $choice; + /** * Starts with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleSelectionTag($attributes) { - $this->SimpleWidget('select', $attributes); - $this->_options = array(); - $this->_choice = false; + function __construct($attributes) { + parent::__construct('select', $attributes); + $this->options = array(); + $this->choice = false; } - + /** * Adds an option tag to a selection field. * @param SimpleOptionTag $tag New option. * @access public */ - function addTag(&$tag) { + function addTag($tag) { if ($tag->getTagName() == 'option') { - $this->_options[] = &$tag; + $this->options[] = $tag; } } - + /** * Text within the selection element is ignored. * @param string $content Ignored. * @access public */ function addContent($content) { + return $this; } - + /** * Scans options for defaults. If none, then * the first option is selected. @@ -737,17 +845,17 @@ class SimpleSelectionTag extends SimpleWidget { * @access public */ function getDefault() { - for ($i = 0, $count = count($this->_options); $i < $count; $i++) { - if ($this->_options[$i]->getAttribute('selected') !== false) { - return $this->_options[$i]->getDefault(); + for ($i = 0, $count = count($this->options); $i < $count; $i++) { + if ($this->options[$i]->getAttribute('selected') !== false) { + return $this->options[$i]->getDefault(); } } if ($count > 0) { - return $this->_options[0]->getDefault(); + return $this->options[0]->getDefault(); } return ''; } - + /** * Can only set allowed values. * @param string $value New choice. @@ -755,15 +863,15 @@ class SimpleSelectionTag extends SimpleWidget { * @access public */ function setValue($value) { - for ($i = 0, $count = count($this->_options); $i < $count; $i++) { - if ($this->_options[$i]->isValue($value)) { - $this->_choice = $i; + for ($i = 0, $count = count($this->options); $i < $count; $i++) { + if ($this->options[$i]->isValue($value)) { + $this->choice = $i; return true; } } return false; } - + /** * Accessor for current selection value. * @return string Value attribute or @@ -771,10 +879,10 @@ class SimpleSelectionTag extends SimpleWidget { * @access public */ function getValue() { - if ($this->_choice === false) { + if ($this->choice === false) { return $this->getDefault(); } - return $this->_options[$this->_choice]->getValue(); + return $this->options[$this->choice]->getValue(); } } @@ -784,39 +892,40 @@ class SimpleSelectionTag extends SimpleWidget { * @subpackage WebTester */ class MultipleSelectionTag extends SimpleWidget { - var $_options; - var $_values; - + private $options; + private $values; + /** * Starts with attributes only. * @param hash $attributes Attribute names and * string values. */ - function MultipleSelectionTag($attributes) { - $this->SimpleWidget('select', $attributes); - $this->_options = array(); - $this->_values = false; + function __construct($attributes) { + parent::__construct('select', $attributes); + $this->options = array(); + $this->values = false; } - + /** * Adds an option tag to a selection field. * @param SimpleOptionTag $tag New option. * @access public */ - function addTag(&$tag) { + function addTag($tag) { if ($tag->getTagName() == 'option') { - $this->_options[] = &$tag; + $this->options[] = &$tag; } } - + /** * Text within the selection element is ignored. * @param string $content Ignored. * @access public */ function addContent($content) { + return $this; } - + /** * Scans options for defaults to populate the * value array(). @@ -825,14 +934,14 @@ class MultipleSelectionTag extends SimpleWidget { */ function getDefault() { $default = array(); - for ($i = 0, $count = count($this->_options); $i < $count; $i++) { - if ($this->_options[$i]->getAttribute('selected') !== false) { - $default[] = $this->_options[$i]->getDefault(); + for ($i = 0, $count = count($this->options); $i < $count; $i++) { + if ($this->options[$i]->getAttribute('selected') !== false) { + $default[] = $this->options[$i]->getDefault(); } } return $default; } - + /** * Can only set allowed values. Any illegal value * will result in a failure, but all correct values @@ -845,9 +954,9 @@ class MultipleSelectionTag extends SimpleWidget { $achieved = array(); foreach ($desired as $value) { $success = false; - for ($i = 0, $count = count($this->_options); $i < $count; $i++) { - if ($this->_options[$i]->isValue($value)) { - $achieved[] = $this->_options[$i]->getValue(); + for ($i = 0, $count = count($this->options); $i < $count; $i++) { + if ($this->options[$i]->isValue($value)) { + $achieved[] = $this->options[$i]->getValue(); $success = true; break; } @@ -856,20 +965,20 @@ class MultipleSelectionTag extends SimpleWidget { return false; } } - $this->_values = $achieved; + $this->values = $achieved; return true; } - + /** * Accessor for current selection value. * @return array List of currently set options. * @access public */ function getValue() { - if ($this->_values === false) { + if ($this->values === false) { return $this->getDefault(); } - return $this->_values; + return $this->values; } } @@ -879,14 +988,14 @@ class MultipleSelectionTag extends SimpleWidget { * @subpackage WebTester */ class SimpleOptionTag extends SimpleWidget { - + /** * Stashes the attributes. */ - function SimpleOptionTag($attributes) { - $this->SimpleWidget('option', $attributes); + function __construct($attributes) { + parent::__construct('option', $attributes); } - + /** * Does nothing. * @param string $value Ignored. @@ -896,7 +1005,7 @@ class SimpleOptionTag extends SimpleWidget { function setValue($value) { return false; } - + /** * Test to see if a value matches the option. * @param string $compare Value to compare with. @@ -908,9 +1017,9 @@ class SimpleOptionTag extends SimpleWidget { if (trim($this->getValue()) == $compare) { return true; } - return trim($this->getContent()) == $compare; + return trim(strip_tags($this->getContent())) == $compare; } - + /** * Accessor for starting value. Will be set to * the option label if no value exists. @@ -919,11 +1028,11 @@ class SimpleOptionTag extends SimpleWidget { */ function getDefault() { if ($this->getAttribute('value') === false) { - return $this->getContent(); + return strip_tags($this->getContent()); } return $this->getAttribute('value'); } - + /** * The content of options is not part of the page. * @return boolean True. @@ -940,18 +1049,18 @@ class SimpleOptionTag extends SimpleWidget { * @subpackage WebTester */ class SimpleRadioButtonTag extends SimpleWidget { - + /** * Stashes the attributes. * @param array $attributes Hash of attributes. */ - function SimpleRadioButtonTag($attributes) { - $this->SimpleWidget('input', $attributes); + function __construct($attributes) { + parent::__construct('input', $attributes); if ($this->getAttribute('value') === false) { - $this->_setAttribute('value', 'on'); + $this->setAttribute('value', 'on'); } } - + /** * Tag contains no content. * @return boolean False. @@ -960,7 +1069,7 @@ class SimpleRadioButtonTag extends SimpleWidget { function expectEndTag() { return false; } - + /** * The only allowed value sn the one in the * "value" attribute. @@ -977,7 +1086,7 @@ class SimpleRadioButtonTag extends SimpleWidget { } return parent::setValue($value); } - + /** * Accessor for starting value. * @return string Parsed value. @@ -997,19 +1106,19 @@ class SimpleRadioButtonTag extends SimpleWidget { * @subpackage WebTester */ class SimpleCheckboxTag extends SimpleWidget { - + /** * Starts with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleCheckboxTag($attributes) { - $this->SimpleWidget('input', $attributes); + function __construct($attributes) { + parent::__construct('input', $attributes); if ($this->getAttribute('value') === false) { - $this->_setAttribute('value', 'on'); + $this->setAttribute('value', 'on'); } } - + /** * Tag contains no content. * @return boolean False. @@ -1018,7 +1127,7 @@ class SimpleCheckboxTag extends SimpleWidget { function expectEndTag() { return false; } - + /** * The only allowed value in the one in the * "value" attribute. The default for this @@ -1040,7 +1149,7 @@ class SimpleCheckboxTag extends SimpleWidget { } return parent::setValue($value); } - + /** * Accessor for starting value. The default * value is "on". @@ -1061,24 +1170,24 @@ class SimpleCheckboxTag extends SimpleWidget { * @subpackage WebTester */ class SimpleTagGroup { - var $_widgets = array(); + private $widgets = array(); /** * Adds a tag to the group. * @param SimpleWidget $widget * @access public */ - function addWidget(&$widget) { - $this->_widgets[] = &$widget; + function addWidget($widget) { + $this->widgets[] = $widget; } - + /** * Accessor to widget set. * @return array All widgets. * @access protected */ - function &_getWidgets() { - return $this->_widgets; + protected function &getWidgets() { + return $this->widgets; } /** @@ -1090,7 +1199,7 @@ class SimpleTagGroup { function getAttribute($label) { return false; } - + /** * Fetches the name for the widget from the first * member. @@ -1098,11 +1207,11 @@ class SimpleTagGroup { * @access public */ function getName() { - if (count($this->_widgets) > 0) { - return $this->_widgets[0]->getName(); + if (count($this->widgets) > 0) { + return $this->widgets[0]->getName(); } } - + /** * Scans the widgets for one with the appropriate * ID field. @@ -1111,14 +1220,14 @@ class SimpleTagGroup { * @access public */ function isId($id) { - for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) { - if ($this->_widgets[$i]->isId($id)) { + for ($i = 0, $count = count($this->widgets); $i < $count; $i++) { + if ($this->widgets[$i]->isId($id)) { return true; } } return false; } - + /** * Scans the widgets for one with the appropriate * attached label. @@ -1127,20 +1236,20 @@ class SimpleTagGroup { * @access public */ function isLabel($label) { - for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) { - if ($this->_widgets[$i]->isLabel($label)) { + for ($i = 0, $count = count($this->widgets); $i < $count; $i++) { + if ($this->widgets[$i]->isLabel($label)) { return true; } } return false; } - + /** * Dispatches the value into the form encoded packet. * @param SimpleEncoding $encoding Form packet. * @access public */ - function write(&$encoding) { + function write($encoding) { $encoding->add($this->getName(), $this->getValue()); } } @@ -1151,7 +1260,7 @@ class SimpleTagGroup { * @subpackage WebTester */ class SimpleCheckboxGroup extends SimpleTagGroup { - + /** * Accessor for current selected widget or false * if none. @@ -1160,15 +1269,15 @@ class SimpleCheckboxGroup extends SimpleTagGroup { */ function getValue() { $values = array(); - $widgets = &$this->_getWidgets(); + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { if ($widgets[$i]->getValue() !== false) { $values[] = $widgets[$i]->getValue(); } } - return $this->_coerceValues($values); + return $this->coerceValues($values); } - + /** * Accessor for starting value that is active. * @return string/array Widget values or false if none. @@ -1176,15 +1285,15 @@ class SimpleCheckboxGroup extends SimpleTagGroup { */ function getDefault() { $values = array(); - $widgets = &$this->_getWidgets(); + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { if ($widgets[$i]->getDefault() !== false) { $values[] = $widgets[$i]->getDefault(); } } - return $this->_coerceValues($values); + return $this->coerceValues($values); } - + /** * Accessor for current set values. * @param string/array/boolean $values Either a single string, a @@ -1193,11 +1302,11 @@ class SimpleCheckboxGroup extends SimpleTagGroup { * @access public */ function setValue($values) { - $values = $this->_makeArray($values); - if (! $this->_valuesArePossible($values)) { + $values = $this->makeArray($values); + if (! $this->valuesArePossible($values)) { return false; } - $widgets = &$this->_getWidgets(); + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { $possible = $widgets[$i]->getAttribute('value'); if (in_array($widgets[$i]->getAttribute('value'), $values)) { @@ -1208,7 +1317,7 @@ class SimpleCheckboxGroup extends SimpleTagGroup { } return true; } - + /** * Tests to see if a possible value set is legal. * @param string/array/boolean $values Either a single string, a @@ -1217,9 +1326,9 @@ class SimpleCheckboxGroup extends SimpleTagGroup { * missing value. * @access private */ - function _valuesArePossible($values) { + protected function valuesArePossible($values) { $matches = array(); - $widgets = &$this->_getWidgets(); + $widgets = &$this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { $possible = $widgets[$i]->getAttribute('value'); if (in_array($possible, $values)) { @@ -1228,7 +1337,7 @@ class SimpleCheckboxGroup extends SimpleTagGroup { } return ($values == $matches); } - + /** * Converts the output to an appropriate format. This means * that no values is false, a single value is just that @@ -1237,7 +1346,7 @@ class SimpleCheckboxGroup extends SimpleTagGroup { * @return string/array/boolean Expected format for a tag. * @access private */ - function _coerceValues($values) { + protected function coerceValues($values) { if (count($values) == 0) { return false; } elseif (count($values) == 1) { @@ -1246,7 +1355,7 @@ class SimpleCheckboxGroup extends SimpleTagGroup { return $values; } } - + /** * Converts false or string into array. The opposite of * the coercian method. @@ -1256,7 +1365,7 @@ class SimpleCheckboxGroup extends SimpleTagGroup { * @return array List of values, possibly empty. * @access private */ - function _makeArray($value) { + protected function makeArray($value) { if ($value === false) { return array(); } @@ -1274,7 +1383,7 @@ class SimpleCheckboxGroup extends SimpleTagGroup { * @subpackage WebTester */ class SimpleRadioGroup extends SimpleTagGroup { - + /** * Each tag is tried in turn until one is * successfully set. The others will be @@ -1284,11 +1393,11 @@ class SimpleRadioGroup extends SimpleTagGroup { * @access public */ function setValue($value) { - if (! $this->_valueIsPossible($value)) { + if (! $this->valueIsPossible($value)) { return false; } $index = false; - $widgets = &$this->_getWidgets(); + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { if (! $widgets[$i]->setValue($value)) { $widgets[$i]->setValue(false); @@ -1296,15 +1405,15 @@ class SimpleRadioGroup extends SimpleTagGroup { } return true; } - + /** * Tests to see if a value is allowed. * @param string Attempted value. * @return boolean True if a valid value. * @access private */ - function _valueIsPossible($value) { - $widgets = &$this->_getWidgets(); + protected function valueIsPossible($value) { + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { if ($widgets[$i]->getAttribute('value') == $value) { return true; @@ -1312,7 +1421,7 @@ class SimpleRadioGroup extends SimpleTagGroup { } return false; } - + /** * Accessor for current selected widget or false * if none. @@ -1321,7 +1430,7 @@ class SimpleRadioGroup extends SimpleTagGroup { * @access public */ function getValue() { - $widgets = &$this->_getWidgets(); + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { if ($widgets[$i]->getValue() !== false) { return $widgets[$i]->getValue(); @@ -1329,7 +1438,7 @@ class SimpleRadioGroup extends SimpleTagGroup { } return false; } - + /** * Accessor for starting value that is active. * @return string/boolean Value of first checked @@ -1337,7 +1446,7 @@ class SimpleRadioGroup extends SimpleTagGroup { * @access public */ function getDefault() { - $widgets = &$this->_getWidgets(); + $widgets = $this->getWidgets(); for ($i = 0, $count = count($widgets); $i < $count; $i++) { if ($widgets[$i]->getDefault() !== false) { return $widgets[$i]->getDefault(); @@ -1353,16 +1462,16 @@ class SimpleRadioGroup extends SimpleTagGroup { * @subpackage WebTester */ class SimpleLabelTag extends SimpleTag { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleLabelTag($attributes) { - $this->SimpleTag('label', $attributes); + function __construct($attributes) { + parent::__construct('label', $attributes); } - + /** * Access for the ID to attach the label to. * @return string For attribute. @@ -1379,14 +1488,14 @@ class SimpleLabelTag extends SimpleTag { * @subpackage WebTester */ class SimpleFormTag extends SimpleTag { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleFormTag($attributes) { - $this->SimpleTag('form', $attributes); + function __construct($attributes) { + parent::__construct('form', $attributes); } } @@ -1396,16 +1505,16 @@ class SimpleFormTag extends SimpleTag { * @subpackage WebTester */ class SimpleFrameTag extends SimpleTag { - + /** * Starts with a named tag with attributes only. * @param hash $attributes Attribute names and * string values. */ - function SimpleFrameTag($attributes) { - $this->SimpleTag('frame', $attributes); + function __construct($attributes) { + parent::__construct('frame', $attributes); } - + /** * Tag contains no content. * @return boolean False. diff --git a/contrib/simpletest/simpletest/test.zip b/contrib/simpletest/simpletest/test.zip deleted file mode 100644 index 46bccfbc48b363ce23cb30ed092f655bb4a68525..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67459 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 diff --git a/contrib/simpletest/simpletest/test_case.php b/contrib/simpletest/simpletest/test_case.php index e5b22983..ba023c3b 100644 --- a/contrib/simpletest/simpletest/test_case.php +++ b/contrib/simpletest/simpletest/test_case.php @@ -3,7 +3,7 @@ * Base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester - * @version $Id: test_case.php 1726 2008-04-08 01:20:10Z lastcraft $ + * @version $Id: test_case.php 2012 2011-04-29 08:57:00Z pp11 $ */ /**#@+ @@ -17,19 +17,15 @@ require_once(dirname(__FILE__) . '/scorer.php'); require_once(dirname(__FILE__) . '/expectation.php'); require_once(dirname(__FILE__) . '/dumper.php'); require_once(dirname(__FILE__) . '/simpletest.php'); -if (version_compare(phpversion(), '5') >= 0) { - require_once(dirname(__FILE__) . '/exceptions.php'); - require_once(dirname(__FILE__) . '/reflection_php5.php'); -} else { - require_once(dirname(__FILE__) . '/reflection_php4.php'); -} +require_once(dirname(__FILE__) . '/exceptions.php'); +require_once(dirname(__FILE__) . '/reflection_php5.php'); +/**#@-*/ if (! defined('SIMPLE_TEST')) { /** * @ignore */ define('SIMPLE_TEST', dirname(__FILE__) . DIRECTORY_SEPARATOR); } -/**#@-*/ /** * Basic test case. This is the smallest unit of a test @@ -40,10 +36,10 @@ if (! defined('SIMPLE_TEST')) { * @subpackage UnitTester */ class SimpleTestCase { - var $_label = false; - var $_reporter; - var $_observers; - var $_should_skip = false; + private $label = false; + protected $reporter; + private $observers; + private $should_skip = false; /** * Sets up the test with no display. @@ -51,9 +47,9 @@ class SimpleTestCase { * the class name is used. * @access public */ - function SimpleTestCase($label = false) { + function __construct($label = false) { if ($label) { - $this->_label = $label; + $this->label = $label; } } @@ -63,7 +59,7 @@ class SimpleTestCase { * @access public */ function getLabel() { - return $this->_label ? $this->_label : get_class($this); + return $this->label ? $this->label : get_class($this); } /** @@ -83,13 +79,21 @@ class SimpleTestCase { * @access public */ function skipIf($should_skip, $message = '%s') { - if ($should_skip && ! $this->_should_skip) { - $this->_should_skip = true; + if ($should_skip && ! $this->should_skip) { + $this->should_skip = true; $message = sprintf($message, 'Skipping [' . get_class($this) . ']'); - $this->_reporter->paintSkip($message . $this->getAssertionLine()); + $this->reporter->paintSkip($message . $this->getAssertionLine()); } } + /** + * Accessor for the private variable $_shoud_skip + * @access public + */ + function shouldSkip() { + return $this->should_skip; + } + /** * Will issue a message to the reporter and tell the test * case to skip if the incoming flag is false. @@ -106,12 +110,9 @@ class SimpleTestCase { * @return SimpleInvoker Individual test runner. * @access public */ - function &createInvoker() { - $invoker = &new SimpleErrorTrappingInvoker(new SimpleInvoker($this)); - if (version_compare(phpversion(), '5') >= 0) { - $invoker = &new SimpleExceptionTrappingInvoker($invoker); - } - return $invoker; + function createInvoker() { + return new SimpleErrorTrappingInvoker( + new SimpleExceptionTrappingInvoker(new SimpleInvoker($this))); } /** @@ -122,23 +123,23 @@ class SimpleTestCase { * @return boolean True if all tests passed. * @access public */ - function run(&$reporter) { - $context = &SimpleTest::getContext(); + function run($reporter) { + $context = SimpleTest::getContext(); $context->setTest($this); $context->setReporter($reporter); - $this->_reporter = &$reporter; + $this->reporter = $reporter; $started = false; foreach ($this->getTests() as $method) { if ($reporter->shouldInvoke($this->getLabel(), $method)) { $this->skip(); - if ($this->_should_skip) { + if ($this->should_skip) { break; } if (! $started) { $reporter->paintCaseStart($this->getLabel()); $started = true; } - $invoker = &$this->_reporter->createInvoker($this->createInvoker()); + $invoker = $this->reporter->createInvoker($this->createInvoker()); $invoker->before($method); $invoker->invoke($method); $invoker->after($method); @@ -147,7 +148,8 @@ class SimpleTestCase { if ($started) { $reporter->paintCaseEnd($this->getLabel()); } - unset($this->_reporter); + unset($this->reporter); + $context->setTest(null); return $reporter->getStatus(); } @@ -162,7 +164,7 @@ class SimpleTestCase { function getTests() { $methods = array(); foreach (get_class_methods(get_class($this)) as $method) { - if ($this->_isTest($method)) { + if ($this->isTest($method)) { $methods[] = $method; } } @@ -177,7 +179,7 @@ class SimpleTestCase { * @return boolean True if test method. * @access protected */ - function _isTest($method) { + protected function isTest($method) { if (strtolower(substr($method, 0, 4)) == 'test') { return ! SimpleTestCompatibility::isA($this, strtolower($method)); } @@ -190,8 +192,8 @@ class SimpleTestCase { * @access public */ function before($method) { - $this->_reporter->paintMethodStart($method); - $this->_observers = array(); + $this->reporter->paintMethodStart($method); + $this->observers = array(); } /** @@ -217,10 +219,10 @@ class SimpleTestCase { * @access public */ function after($method) { - for ($i = 0; $i < count($this->_observers); $i++) { - $this->_observers[$i]->atTestEnd($method, $this); + for ($i = 0; $i < count($this->observers); $i++) { + $this->observers[$i]->atTestEnd($method, $this); } - $this->_reporter->paintMethodEnd($method); + $this->reporter->paintMethodEnd($method); } /** @@ -229,18 +231,18 @@ class SimpleTestCase { * method. * @access public */ - function tell(&$observer) { - $this->_observers[] = &$observer; + function tell($observer) { + $this->observers[] = &$observer; } /** * @deprecated */ function pass($message = "Pass") { - if (! isset($this->_reporter)) { + if (! isset($this->reporter)) { trigger_error('Can only make assertions within test methods'); } - $this->_reporter->paintPass( + $this->reporter->paintPass( $message . $this->getAssertionLine()); return true; } @@ -251,10 +253,10 @@ class SimpleTestCase { * @access public */ function fail($message = "Fail") { - if (! isset($this->_reporter)) { + if (! isset($this->reporter)) { trigger_error('Can only make assertions within test methods'); } - $this->_reporter->paintFail( + $this->reporter->paintFail( $message . $this->getAssertionLine()); return false; } @@ -269,10 +271,10 @@ class SimpleTestCase { * @access public */ function error($severity, $message, $file, $line) { - if (! isset($this->_reporter)) { + if (! isset($this->reporter)) { trigger_error('Can only make assertions within test methods'); } - $this->_reporter->paintError( + $this->reporter->paintError( "Unexpected PHP error [$message] severity [$severity] in [$file line $line]"); } @@ -283,17 +285,19 @@ class SimpleTestCase { * @access public */ function exception($exception) { - $this->_reporter->paintException($exception); + $this->reporter->paintException($exception); } /** - * @deprecated + * For user defined expansion of the available messages. + * @param string $type Tag for sorting the signals. + * @param mixed $payload Extra user specific information. */ - function signal($type, &$payload) { - if (! isset($this->_reporter)) { + function signal($type, $payload) { + if (! isset($this->reporter)) { trigger_error('Can only make assertions within test methods'); } - $this->_reporter->paintSignal($type, $payload); + $this->reporter->paintSignal($type, $payload); } /** @@ -305,25 +309,18 @@ class SimpleTestCase { * @return boolean True on pass * @access public */ - function assert(&$expectation, $compare, $message = '%s') { + function assert($expectation, $compare, $message = '%s') { if ($expectation->test($compare)) { return $this->pass(sprintf( $message, - $expectation->overlayMessage($compare, $this->_reporter->getDumper()))); + $expectation->overlayMessage($compare, $this->reporter->getDumper()))); } else { return $this->fail(sprintf( $message, - $expectation->overlayMessage($compare, $this->_reporter->getDumper()))); + $expectation->overlayMessage($compare, $this->reporter->getDumper()))); } } - /** - * @deprecated - */ - function assertExpectation(&$expectation, $compare, $message = '%s') { - return $this->assert($expectation, $compare, $message); - } - /** * Uses a stack trace to find the line of an assertion. * @return string Line number of first assert* @@ -345,27 +342,19 @@ class SimpleTestCase { * @access public */ function dump($variable, $message = false) { - $dumper = $this->_reporter->getDumper(); + $dumper = $this->reporter->getDumper(); $formatted = $dumper->dump($variable); if ($message) { $formatted = $message . "\n" . $formatted; } - $this->_reporter->paintFormattedMessage($formatted); + $this->reporter->paintFormattedMessage($formatted); return $variable; } - /** - * @deprecated - */ - function sendMessage($message) { - $this->_reporter->PaintMessage($message); - } - /** * Accessor for the number of subtests including myelf. * @return integer Number of test cases. * @access public - * @static */ function getSize() { return 1; @@ -374,6 +363,8 @@ class SimpleTestCase { /** * Helps to extract test cases automatically from a file. + * @package SimpleTest + * @subpackage UnitTester */ class SimpleFileLoader { @@ -385,34 +376,33 @@ class SimpleFileLoader { * @return TestSuite The new test suite. * @access public */ - function &load($test_file) { + function load($test_file) { $existing_classes = get_declared_classes(); $existing_globals = get_defined_vars(); include_once($test_file); $new_globals = get_defined_vars(); - $this->_makeFileVariablesGlobal($existing_globals, $new_globals); + $this->makeFileVariablesGlobal($existing_globals, $new_globals); $new_classes = array_diff(get_declared_classes(), $existing_classes); if (empty($new_classes)) { - $new_classes = $this->_scrapeClassesFromFile($test_file); + $new_classes = $this->scrapeClassesFromFile($test_file); } $classes = $this->selectRunnableTests($new_classes); - $suite = &$this->createSuiteFromClasses($test_file, $classes); - return $suite; + return $this->createSuiteFromClasses($test_file, $classes); } - + /** * Imports new variables into the global namespace. * @param hash $existing Variables before the file was loaded. * @param hash $new Variables after the file was loaded. * @access private */ - function _makeFileVariablesGlobal($existing, $new) { + protected function makeFileVariablesGlobal($existing, $new) { $globals = array_diff(array_keys($new), array_keys($existing)); foreach ($globals as $global) { - $_GLOBALS[$global] = $new[$global]; + $GLOBALS[$global] = $new[$global]; } } - + /** * Lookup classnames from file contents, in case the * file may have been included before. @@ -423,7 +413,7 @@ class SimpleFileLoader { * @param string $test_file File name with classes. * @access private */ - function _scrapeClassesFromFile($test_file) { + protected function scrapeClassesFromFile($test_file) { preg_match_all('~^\s*class\s+(\w+)(\s+(extends|implements)\s+\w+)*\s*\{~mi', file_get_contents($test_file), $matches ); @@ -461,16 +451,16 @@ class SimpleFileLoader { * test cases. * @access public */ - function &createSuiteFromClasses($title, $classes) { + function createSuiteFromClasses($title, $classes) { if (count($classes) == 0) { - $suite = &new BadTestSuite($title, "No runnable test cases in [$title]"); + $suite = new BadTestSuite($title, "No runnable test cases in [$title]"); return $suite; } SimpleTest::ignoreParentsIfIgnored($classes); - $suite = &new TestSuite($title); + $suite = new TestSuite($title); foreach ($classes as $class) { if (! SimpleTest::isIgnored($class)) { - $suite->addTestClass($class); + $suite->add($class); } } return $suite; @@ -485,8 +475,8 @@ class SimpleFileLoader { * @subpackage UnitTester */ class TestSuite { - var $_label; - var $_test_cases; + private $label; + private $test_cases; /** * Sets the name of the test suite. @@ -495,8 +485,8 @@ class TestSuite { * @access public */ function TestSuite($label = false) { - $this->_label = $label; - $this->_test_cases = array(); + $this->label = $label; + $this->test_cases = array(); } /** @@ -506,29 +496,11 @@ class TestSuite { * @access public */ function getLabel() { - if (! $this->_label) { + if (! $this->label) { return ($this->getSize() == 1) ? - get_class($this->_test_cases[0]) : get_class($this); + get_class($this->test_cases[0]) : get_class($this); } else { - return $this->_label; - } - } - - /** - * @deprecated - */ - function addTestCase(&$test_case) { - $this->_test_cases[] = &$test_case; - } - - /** - * @deprecated - */ - function addTestClass($class) { - if (TestSuite::getBaseTestCase($class) == 'testsuite') { - $this->_test_cases[] = &new $class(); - } else { - $this->_test_cases[] = $class; + return $this->label; } } @@ -540,23 +512,16 @@ class TestSuite { * runnable test interface. * @access public */ - function add(&$test_case) { + function add($test_case) { if (! is_string($test_case)) { - $this->_test_cases[] = &$test_case; - } elseif (TestSuite::getBaseTestCase($class) == 'testsuite') { - $this->_test_cases[] = &new $class(); + $this->test_cases[] = $test_case; + } elseif (TestSuite::getBaseTestCase($test_case) == 'testsuite') { + $this->test_cases[] = new $test_case(); } else { - $this->_test_cases[] = $class; + $this->test_cases[] = $test_case; } } - /** - * @deprecated - */ - function addTestFile($test_file) { - $this->addFile($test_file); - } - /** * Builds a test suite from a library of test cases. * The new suite is composed into this one. @@ -576,7 +541,7 @@ class TestSuite { * @param SimpleCollector $collector Directory scanner. * @access public */ - function collect($path, &$collector) { + function collect($path, $collector) { $collector->collect($this, $path); } @@ -586,16 +551,16 @@ class TestSuite { * @param SimpleReporter $reporter Current test reporter. * @access public */ - function run(&$reporter) { + function run($reporter) { $reporter->paintGroupStart($this->getLabel(), $this->getSize()); - for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) { - if (is_string($this->_test_cases[$i])) { - $class = $this->_test_cases[$i]; - $test = &new $class(); + for ($i = 0, $count = count($this->test_cases); $i < $count; $i++) { + if (is_string($this->test_cases[$i])) { + $class = $this->test_cases[$i]; + $test = new $class(); $test->run($reporter); unset($test); } else { - $this->_test_cases[$i]->run($reporter); + $this->test_cases[$i]->run($reporter); } } $reporter->paintGroupEnd($this->getLabel()); @@ -609,7 +574,7 @@ class TestSuite { */ function getSize() { $count = 0; - foreach ($this->_test_cases as $case) { + foreach ($this->test_cases as $case) { if (is_string($case)) { if (! SimpleTest::isIgnored($case)) { $count++; @@ -626,9 +591,8 @@ class TestSuite { * SimpleTestCase class. * @param string $class Class name. * @access public - * @static */ - function getBaseTestCase($class) { + static function getBaseTestCase($class) { while ($class = get_parent_class($class)) { $class = strtolower($class); if ($class == 'simpletestcase' || $class == 'testsuite') { @@ -639,13 +603,6 @@ class TestSuite { } } -/** - * @package SimpleTest - * @subpackage UnitTester - * @deprecated - */ -class GroupTest extends TestSuite { } - /** * This is a failing group test for when a test suite hasn't * loaded properly. @@ -653,8 +610,8 @@ class GroupTest extends TestSuite { } * @subpackage UnitTester */ class BadTestSuite { - var $_label; - var $_error; + private $label; + private $error; /** * Sets the name of the test suite and error message. @@ -663,8 +620,8 @@ class BadTestSuite { * @access public */ function BadTestSuite($label, $error) { - $this->_label = $label; - $this->_error = $error; + $this->label = $label; + $this->error = $error; } /** @@ -673,7 +630,7 @@ class BadTestSuite { * @access public */ function getLabel() { - return $this->_label; + return $this->label; } /** @@ -681,10 +638,10 @@ class BadTestSuite { * @param SimpleReporter $reporter Current test reporter. * @access public */ - function run(&$reporter) { + function run($reporter) { $reporter->paintGroupStart($this->getLabel(), $this->getSize()); $reporter->paintFail('Bad TestSuite [' . $this->getLabel() . - '] with error [' . $this->_error . ']'); + '] with error [' . $this->error . ']'); $reporter->paintGroupEnd($this->getLabel()); return $reporter->getStatus(); } @@ -698,11 +655,4 @@ class BadTestSuite { return 0; } } - -/** - * @package SimpleTest - * @subpackage UnitTester - * @deprecated - */ -class BadGroupTest extends BadTestSuite { } ?> diff --git a/contrib/simpletest/simpletest/tidy_parser.php b/contrib/simpletest/simpletest/tidy_parser.php new file mode 100755 index 00000000..3d8b4b2a --- /dev/null +++ b/contrib/simpletest/simpletest/tidy_parser.php @@ -0,0 +1,382 @@ +free(); + } + + /** + * Frees up any references so as to allow the PHP garbage + * collection from unset() to work. + */ + private function free() { + unset($this->page); + $this->forms = array(); + $this->labels = array(); + } + + /** + * This builder is only available if the 'tidy' extension is loaded. + * @return boolean True if available. + */ + function can() { + return extension_loaded('tidy'); + } + + /** + * Reads the raw content the page using HTML Tidy. + * @param $response SimpleHttpResponse Fetched response. + * @return SimplePage Newly parsed page. + */ + function parse($response) { + $this->page = new SimplePage($response); + $tidied = tidy_parse_string($input = $this->insertGuards($response->getContent()), + array('output-xml' => false, 'wrap' => '0', 'indent' => 'no'), + 'latin1'); + $this->walkTree($tidied->html()); + $this->attachLabels($this->widgets_by_id, $this->labels); + $this->page->setForms($this->forms); + $page = $this->page; + $this->free(); + return $page; + } + + /** + * Stops HTMLTidy stripping content that we wish to preserve. + * @param string The raw html. + * @return string The html with guard tags inserted. + */ + private function insertGuards($html) { + return $this->insertEmptyTagGuards($this->insertTextareaSimpleWhitespaceGuards($html)); + } + + /** + * Removes the extra content added during the parse stage + * in order to preserve content we don't want stripped + * out by HTMLTidy. + * @param string The raw html. + * @return string The html with guard tags removed. + */ + private function stripGuards($html) { + return $this->stripTextareaWhitespaceGuards($this->stripEmptyTagGuards($html)); + } + + /** + * HTML tidy strips out empty tags such as