MDL-15204 Update complete
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
BACKLOG
|
||||
This is backed up stuff that defines the 1.0.1 release.
|
||||
|
||||
$Id$
|
||||
|
||||
Unit tester
|
||||
-----------
|
||||
Add skip facility (4).
|
||||
|
||||
Reporter
|
||||
--------
|
||||
Add a repeating reporter (2).
|
||||
Split and refactor dumpers by type (2).
|
||||
|
||||
Mock objects
|
||||
------------
|
||||
|
||||
Parser
|
||||
------
|
||||
Add U flag to regexes to allow unicode (3).
|
||||
Parse fieldsets correctly with labels (5).
|
||||
|
||||
Browser
|
||||
-------
|
||||
Change getUrls() to return more information (2).
|
||||
Add a file() loading command (2).
|
||||
Investigate bug, clicking keeps encoding again and again (3).
|
||||
Fix bug URL losing spaces (3).
|
||||
Setting an option by id attribute should only toggle that option (3).
|
||||
Add additional parameters to click() method (1).
|
||||
Allow index selection of controls (3).
|
||||
|
||||
Web tester
|
||||
----------
|
||||
Add assertClickable() method (1).
|
||||
Add assertSubmit() method (1).
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
Extension docs (1).
|
||||
Replace all deprecated methods (3).
|
||||
Split mock objects off fromtutorial (4).
|
||||
Add page for projects that use or extend SimpleTest (2).
|
||||
|
||||
Build
|
||||
-----
|
||||
@@ -5,17 +5,31 @@ 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...
|
||||
|
||||
No method getRelativeUrls() or getAbsoluteUrls()
|
||||
------------------------------------------------
|
||||
These methods were always a bit weird anyway, and
|
||||
the new parsing of the base tag makes them more so.
|
||||
They have been replaced with getUrls() instead. If
|
||||
you want the old functionality then simply chop
|
||||
off the current domain from getUrl().
|
||||
|
||||
Method setWildcard() removed in mocks
|
||||
-------------------------------------
|
||||
Even setWildcard() has been removed in 1.0.1beta now.
|
||||
If you want to test explicitely for a '*' string, then
|
||||
simply pass in new IdenticalExpectation('*') instead.
|
||||
|
||||
No method _getTest() on mocks
|
||||
-----------------------------
|
||||
This has finally been removed. It was a pretty esoteric
|
||||
flex point anyway. It was there to allow the mocks to
|
||||
work with other test tools, but no one does this anyway.
|
||||
work with other test tools, but no one does this.
|
||||
|
||||
No method assertError(), assertNoErrors(), swallowErrors()
|
||||
----------------------------------------------------------
|
||||
These have been deprecated in 1.0.1beta in favour of
|
||||
expectError() and expectException(). assertNoErrors() is
|
||||
redundant if you use expectError() as failures are now reporterted
|
||||
redundant if you use expectError() as failures are now reported
|
||||
immediately.
|
||||
|
||||
No method TestCase::signal()
|
||||
|
||||
+12
-12
@@ -8,9 +8,9 @@ a version from the location above. You must read and accept that
|
||||
licence to use this software. The file is titled simply LICENSE.
|
||||
|
||||
What is it? It's a framework for unit testing, web site testing and
|
||||
mock objects for PHP 4.2.0+.
|
||||
mock objects for PHP 4.2.0+ (and PHP 5.0 to 5.3 without E_STRICT).
|
||||
|
||||
If you have used JUnit you will find this PHP unit testing version very
|
||||
If you have used JUnit, you will find this PHP unit testing version very
|
||||
similar. Also included is a mock objects and server stubs generator.
|
||||
The stubs can have return values set for different arguments, can have
|
||||
sequences set also by arguments and can return items by reference.
|
||||
@@ -31,9 +31,9 @@ in the extreme, but a lot of information flows from the test suite.
|
||||
After version 1.0 we will release a better web UI, but we are leaving XUL
|
||||
and GTk versions to volunteers as everybody has their own opinion
|
||||
on a good GUI, and we don't want to discourage development by shipping
|
||||
one with the toolkit.
|
||||
one with the toolkit. YOucan download an Eclipse plug-in separately.
|
||||
|
||||
You are looking at a first full release. The unit tests for SimpleTest
|
||||
You are looking at a second full release. The unit tests for SimpleTest
|
||||
itself can be run here...
|
||||
|
||||
simpletest/test/unit_tests.php
|
||||
@@ -42,7 +42,7 @@ And tests involving live network connections as well are here...
|
||||
|
||||
simpletest/test/all_tests.php
|
||||
|
||||
The full tests will typically overrun the 8Mb limit usually allowed
|
||||
The full tests will typically overrun the 8Mb limit often allowed
|
||||
to a PHP process. A workaround is to run the tests on the command
|
||||
with a custom php.ini file if you do not have access to your server
|
||||
version.
|
||||
@@ -55,7 +55,7 @@ The full tests read some test data from the LastCraft site. If the site
|
||||
is down or has been modified for a later version then you will get
|
||||
spurious errors. A unit_tests.php failure on the other hand would be
|
||||
very serious. As far as we know we haven't yet managed to check in any
|
||||
unit test failures so please correct us if you find one.
|
||||
unit test failures, so please correct us if you find one.
|
||||
|
||||
Even if all of the tests run please verify that your existing test suites
|
||||
also function as expected. If they don't see the file...
|
||||
@@ -63,7 +63,7 @@ also function as expected. If they don't see the file...
|
||||
HELP_MY_TESTS_DONT_WORK_ANYMORE
|
||||
|
||||
This contains information on interface changes. It also points out
|
||||
deprecated interfaces so you should read this even if all of
|
||||
deprecated interfaces, so you should read this even if all of
|
||||
your current tests appear to run.
|
||||
|
||||
There is a documentation folder which contains the core reference information
|
||||
@@ -77,7 +77,7 @@ with the project documentation. A French translation exists at...
|
||||
|
||||
http://www.onpk.net/index.php/2005/01/12/254-tutoriel-simpletest-decouvrir-les-tests-unitaires.
|
||||
|
||||
If you download and use and possibly even extend this tool, please let us
|
||||
If you download and use, and possibly even extend this tool, please let us
|
||||
know. Any feedback, even bad, is always welcome and we will work to get
|
||||
your suggestions into the next release. Ideally please send your
|
||||
comments to...
|
||||
@@ -87,10 +87,10 @@ [email protected]
|
||||
...so that others can read them too. We usually try to respond within 48
|
||||
hours.
|
||||
|
||||
There is no change log as yet except at Sourceforge. You can visit the
|
||||
There is no change log except at Sourceforge. You can visit the
|
||||
release notes to see the completed TODO list after each cycle and also the
|
||||
status of any bugs, but if the bug is recent then it will be fixed in CVS only.
|
||||
The CVS check-ins always have all the tests passing and so CVS snapshots should
|
||||
status of any bugs, but if the bug is recent then it will be fixed in SVN only.
|
||||
The SVN check-ins always have all the tests passing and so SVN snapshots should
|
||||
be pretty usable, although the code may not look so good internally.
|
||||
|
||||
Oh, yes. It is called "Simple" because it should be simple to
|
||||
@@ -103,6 +103,6 @@ really are invaluable, but sadly you are too many to mention in full.
|
||||
Thanks to all on the advanced PHP forum on SitePoint, especially Harry
|
||||
Feucks. Early adopters are always an inspiration.
|
||||
|
||||
yours Marcus Baker, Jason Sweat, Travis Swicegood and Perrick Penet.
|
||||
Marcus Baker, Jason Sweat, Travis Swicegood, Perrick Penet and Edward Z. Yang.
|
||||
--
|
||||
[email protected]
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
TODO
|
||||
This is immediate stuff only for this iteration (1.0.1alpha3) of 44 hours (60 actual).
|
||||
|
||||
$Id$
|
||||
|
||||
Unit tester
|
||||
-----------
|
||||
Change assertCopy() to assertClone() and add identical check (1/1) - done.
|
||||
The ignore() directive should ignore parent classes as well (1/3) - done.
|
||||
The fail() method should issue a line number (2/1) - done.
|
||||
Abstract test cases should be ignored automatically (2/2) - done.
|
||||
More meaningful message when trying a test in the constructor (1/1) - done.
|
||||
Add exception trap (2/2) - done.
|
||||
|
||||
Reporter
|
||||
--------
|
||||
Allow multiple reporters (2/1) - done.
|
||||
Add a test case selecting ReporterDecorator (2/4) - done.
|
||||
Can we get rid of that useless runner class? yes! (1/2) - done.
|
||||
Test case should say what tests are available (1/1) - done.
|
||||
|
||||
Mock objects
|
||||
------------
|
||||
Confirm mocking of SPL classes and derivatives (3/4) - done.
|
||||
Optional parameters generate spurious warnings in PHP 5.0.2 (1/2) - done.
|
||||
|
||||
Parser
|
||||
------
|
||||
|
||||
Browser
|
||||
-------
|
||||
Allow ignoring of cookies as per feature request (2/8) - done.
|
||||
Setting a radio button with value 0 just doesn't happen (1/10) - done.
|
||||
Fix quoting issue with fields as in bug report (2/2) - done.
|
||||
Fix bug with encoded GET parameters not being transmitted in form action (3/2) - done.
|
||||
Confirm that button with no name has no value transmitted (2/4) - done.
|
||||
Allow setting of checkboxes by setting them to true (1/1) - done.
|
||||
Add memory fixes to builder (1/1) - done.
|
||||
|
||||
Web tester
|
||||
----------
|
||||
Failure to connect should be reported unless suppressed (2/2) - done.
|
||||
Message bug in web header pattern assertions (2/1) - done.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Build
|
||||
-----
|
||||
Fix fatal error in PHP 5.1 (3/0) - done.
|
||||
Fix fatal error in PHP 5.0.5 (3/2) - done.
|
||||
Test with PHP 4.4.2 (1/1) - done.
|
||||
Fix error in PHP 5.0.2 (2/2) - done.
|
||||
@@ -1 +1 @@
|
||||
1.0.1beta
|
||||
1.0.1
|
||||
@@ -1,238 +1,238 @@
|
||||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* include http class
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* include http class
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
|
||||
/**
|
||||
* Represents a single security realm's identity.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleRealm {
|
||||
var $_type;
|
||||
var $_root;
|
||||
var $_username;
|
||||
var $_password;
|
||||
|
||||
/**
|
||||
* Represents a single security realm's identity.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Starts with the initial entry directory.
|
||||
* @param string $type Authentication type for this
|
||||
* realm. Only Basic authentication
|
||||
* is currently supported.
|
||||
* @param SimpleUrl $url Somewhere in realm.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleRealm {
|
||||
var $_type;
|
||||
var $_root;
|
||||
var $_username;
|
||||
var $_password;
|
||||
|
||||
/**
|
||||
* Starts with the initial entry directory.
|
||||
* @param string $type Authentication type for this
|
||||
* realm. Only Basic authentication
|
||||
* is currently supported.
|
||||
* @param SimpleUrl $url Somewhere in realm.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleRealm($type, $url) {
|
||||
$this->_type = $type;
|
||||
$this->_root = $url->getBasePath();
|
||||
$this->_username = false;
|
||||
$this->_password = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another location to the realm.
|
||||
* @param SimpleUrl $url Somewhere in realm.
|
||||
* @access public
|
||||
*/
|
||||
function stretch($url) {
|
||||
$this->_root = $this->_getCommonPath($this->_root, $url->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the common starting path.
|
||||
* @param string $first Path to compare.
|
||||
* @param string $second Path to compare.
|
||||
* @return string Common directories.
|
||||
* @access private
|
||||
*/
|
||||
function _getCommonPath($first, $second) {
|
||||
$first = explode('/', $first);
|
||||
$second = explode('/', $second);
|
||||
for ($i = 0; $i < min(count($first), count($second)); $i++) {
|
||||
if ($first[$i] != $second[$i]) {
|
||||
return implode('/', array_slice($first, 0, $i)) . '/';
|
||||
}
|
||||
function SimpleRealm($type, $url) {
|
||||
$this->_type = $type;
|
||||
$this->_root = $url->getBasePath();
|
||||
$this->_username = false;
|
||||
$this->_password = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another location to the realm.
|
||||
* @param SimpleUrl $url Somewhere in realm.
|
||||
* @access public
|
||||
*/
|
||||
function stretch($url) {
|
||||
$this->_root = $this->_getCommonPath($this->_root, $url->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the common starting path.
|
||||
* @param string $first Path to compare.
|
||||
* @param string $second Path to compare.
|
||||
* @return string Common directories.
|
||||
* @access private
|
||||
*/
|
||||
function _getCommonPath($first, $second) {
|
||||
$first = explode('/', $first);
|
||||
$second = explode('/', $second);
|
||||
for ($i = 0; $i < min(count($first), count($second)); $i++) {
|
||||
if ($first[$i] != $second[$i]) {
|
||||
return implode('/', array_slice($first, 0, $i)) . '/';
|
||||
}
|
||||
return implode('/', $first) . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity to try within this realm.
|
||||
* @param string $username Username in authentication dialog.
|
||||
* @param string $username Password in authentication dialog.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentity($username, $password) {
|
||||
$this->_username = $username;
|
||||
$this->_password = $password;
|
||||
return implode('/', $first) . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity to try within this realm.
|
||||
* @param string $username Username in authentication dialog.
|
||||
* @param string $username Password in authentication dialog.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentity($username, $password) {
|
||||
$this->_username = $username;
|
||||
$this->_password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current identity.
|
||||
* @return string Last succesful username.
|
||||
* @access public
|
||||
*/
|
||||
function getUsername() {
|
||||
return $this->_username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current identity.
|
||||
* @return string Last succesful password.
|
||||
* @access public
|
||||
*/
|
||||
function getPassword() {
|
||||
return $this->_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the URL is within the directory
|
||||
* tree of the realm.
|
||||
* @param SimpleUrl $url URL to test.
|
||||
* @return boolean True if subpath.
|
||||
* @access public
|
||||
*/
|
||||
function isWithin($url) {
|
||||
if ($this->_isIn($this->_root, $url->getBasePath())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current identity.
|
||||
* @return string Last succesful username.
|
||||
* @access public
|
||||
*/
|
||||
function getUsername() {
|
||||
return $this->_username;
|
||||
if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current identity.
|
||||
* @return string Last succesful password.
|
||||
* @access public
|
||||
*/
|
||||
function getPassword() {
|
||||
return $this->_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the URL is within the directory
|
||||
* tree of the realm.
|
||||
* @param SimpleUrl $url URL to test.
|
||||
* @return boolean True if subpath.
|
||||
* @access public
|
||||
*/
|
||||
function isWithin($url) {
|
||||
if ($this->_isIn($this->_root, $url->getBasePath())) {
|
||||
return true;
|
||||
}
|
||||
if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if one string is a substring of
|
||||
* another.
|
||||
* @param string $part Small bit.
|
||||
* @param string $whole Big bit.
|
||||
* @return boolean True if the small bit is
|
||||
* in the big bit.
|
||||
* @access private
|
||||
*/
|
||||
function _isIn($part, $whole) {
|
||||
return strpos($whole, $part) === 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if one string is a substring of
|
||||
* another.
|
||||
* @param string $part Small bit.
|
||||
* @param string $whole Big bit.
|
||||
* @return boolean True if the small bit is
|
||||
* in the big bit.
|
||||
* @access private
|
||||
*/
|
||||
function _isIn($part, $whole) {
|
||||
return strpos($whole, $part) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages security realms.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleAuthenticator {
|
||||
var $_realms;
|
||||
|
||||
/**
|
||||
* Clears the realms.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleAuthenticator() {
|
||||
$this->restartSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts with no realms set up.
|
||||
* @access public
|
||||
*/
|
||||
function restartSession() {
|
||||
$this->_realms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new realm centered the current URL.
|
||||
* Browsers vary wildly on their behaviour in this
|
||||
* regard. Mozilla ignores the realm and presents
|
||||
* only when challenged, wasting bandwidth. IE
|
||||
* just carries on presenting until a new challenge
|
||||
* occours. SimpleTest tries to follow the spirit of
|
||||
* the original standards committee and treats the
|
||||
* base URL as the root of a file tree shaped realm.
|
||||
* @param SimpleUrl $url Base of realm.
|
||||
* @param string $type Authentication type for this
|
||||
* realm. Only Basic authentication
|
||||
* is currently supported.
|
||||
* @param string $realm Name of realm.
|
||||
* @access public
|
||||
*/
|
||||
function addRealm($url, $type, $realm) {
|
||||
$this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current identity to be presented
|
||||
* against that realm.
|
||||
* @param string $host Server hosting realm.
|
||||
* @param string $realm Name of realm.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentityForRealm($host, $realm, $username, $password) {
|
||||
if (isset($this->_realms[$host][$realm])) {
|
||||
$this->_realms[$host][$realm]->setIdentity($username, $password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages security realms.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Finds the name of the realm by comparing URLs.
|
||||
* @param SimpleUrl $url URL to test.
|
||||
* @return SimpleRealm Name of realm.
|
||||
* @access private
|
||||
*/
|
||||
class SimpleAuthenticator {
|
||||
var $_realms;
|
||||
|
||||
/**
|
||||
* Clears the realms.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleAuthenticator() {
|
||||
$this->restartSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts with no realms set up.
|
||||
* @access public
|
||||
*/
|
||||
function restartSession() {
|
||||
$this->_realms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new realm centered the current URL.
|
||||
* Browsers vary wildly on their behaviour in this
|
||||
* regard. Mozilla ignores the realm and presents
|
||||
* only when challenged, wasting bandwidth. IE
|
||||
* just carries on presenting until a new challenge
|
||||
* occours. SimpleTest tries to follow the spirit of
|
||||
* the original standards committee and treats the
|
||||
* base URL as the root of a file tree shaped realm.
|
||||
* @param SimpleUrl $url Base of realm.
|
||||
* @param string $type Authentication type for this
|
||||
* realm. Only Basic authentication
|
||||
* is currently supported.
|
||||
* @param string $realm Name of realm.
|
||||
* @access public
|
||||
*/
|
||||
function addRealm($url, $type, $realm) {
|
||||
$this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current identity to be presented
|
||||
* against that realm.
|
||||
* @param string $host Server hosting realm.
|
||||
* @param string $realm Name of realm.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentityForRealm($host, $realm, $username, $password) {
|
||||
if (isset($this->_realms[$host][$realm])) {
|
||||
$this->_realms[$host][$realm]->setIdentity($username, $password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the name of the realm by comparing URLs.
|
||||
* @param SimpleUrl $url URL to test.
|
||||
* @return SimpleRealm Name of realm.
|
||||
* @access private
|
||||
*/
|
||||
function _findRealmFromUrl($url) {
|
||||
if (! isset($this->_realms[$url->getHost()])) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->_realms[$url->getHost()] as $name => $realm) {
|
||||
if ($realm->isWithin($url)) {
|
||||
return $realm;
|
||||
}
|
||||
}
|
||||
function _findRealmFromUrl($url) {
|
||||
if (! isset($this->_realms[$url->getHost()])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the appropriate headers for this location.
|
||||
* @param SimpleHttpRequest $request Request to modify.
|
||||
* @param SimpleUrl $url Base of realm.
|
||||
* @access public
|
||||
*/
|
||||
function addHeaders(&$request, $url) {
|
||||
if ($url->getUsername() && $url->getPassword()) {
|
||||
$username = $url->getUsername();
|
||||
$password = $url->getPassword();
|
||||
} elseif ($realm = $this->_findRealmFromUrl($url)) {
|
||||
$username = $realm->getUsername();
|
||||
$password = $realm->getPassword();
|
||||
} else {
|
||||
return;
|
||||
foreach ($this->_realms[$url->getHost()] as $name => $realm) {
|
||||
if ($realm->isWithin($url)) {
|
||||
return $realm;
|
||||
}
|
||||
$this->addBasicHeaders($request, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the appropriate headers for this
|
||||
* location for basic authentication.
|
||||
* @param SimpleHttpRequest $request Request to modify.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function addBasicHeaders(&$request, $username, $password) {
|
||||
if ($username && $password) {
|
||||
$request->addHeaderLine(
|
||||
'Authorization: Basic ' . base64_encode("$username:$password"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the appropriate headers for this location.
|
||||
* @param SimpleHttpRequest $request Request to modify.
|
||||
* @param SimpleUrl $url Base of realm.
|
||||
* @access public
|
||||
*/
|
||||
function addHeaders(&$request, $url) {
|
||||
if ($url->getUsername() && $url->getPassword()) {
|
||||
$username = $url->getUsername();
|
||||
$password = $url->getPassword();
|
||||
} elseif ($realm = $this->_findRealmFromUrl($url)) {
|
||||
$username = $realm->getUsername();
|
||||
$password = $realm->getPassword();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
$this->addBasicHeaders($request, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the appropriate headers for this
|
||||
* location for basic authentication.
|
||||
* @param SimpleHttpRequest $request Request to modify.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function addBasicHeaders(&$request, $username, $password) {
|
||||
if ($username && $password) {
|
||||
$request->addHeaderLine(
|
||||
'Authorization: Basic ' . base64_encode("$username:$password"));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* Autorunner which runs all tests cases found in a file
|
||||
* that includes this module.
|
||||
* @package SimpleTest
|
||||
* @version $Id$
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/unit_tester.php';
|
||||
require_once dirname(__FILE__) . '/mock_objects.php';
|
||||
require_once dirname(__FILE__) . '/collector.php';
|
||||
require_once dirname(__FILE__) . '/default_reporter.php';
|
||||
|
||||
$GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_CLASSES'] = get_declared_classes();
|
||||
register_shutdown_function('simpletest_autorun');
|
||||
|
||||
/**
|
||||
* Exit handler to run all recent test cases if no test has
|
||||
* so far been run. Uses the DefaultReporter which can have
|
||||
* it's output controlled with SimpleTest::prefer().
|
||||
*/
|
||||
function simpletest_autorun() {
|
||||
if (tests_have_run()) {
|
||||
return;
|
||||
}
|
||||
$candidates = array_intersect(
|
||||
capture_new_classes(),
|
||||
classes_defined_in_initial_file());
|
||||
$loader = new SimpleFileLoader();
|
||||
$suite = $loader->createSuiteFromClasses(
|
||||
basename(initial_file()),
|
||||
$loader->selectRunnableTests($candidates));
|
||||
$result = $suite->run(new DefaultReporter());
|
||||
if (SimpleReporter::inCli()) {
|
||||
exit($result ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current test context to see if a test has
|
||||
* ever been run.
|
||||
* @return boolean True if tests have run.
|
||||
*/
|
||||
function tests_have_run() {
|
||||
if ($context = SimpleTest::getContext()) {
|
||||
return (boolean)$context->getTest();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The first autorun file.
|
||||
* @return string Filename of first autorun script.
|
||||
*/
|
||||
function initial_file() {
|
||||
static $file = false;
|
||||
if (! $file) {
|
||||
$file = reset(get_included_files());
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just the classes from the first autorun script. May
|
||||
* get a few false positives, as it just does a regex based
|
||||
* on following the word "class".
|
||||
* @return array List of all possible classes in first
|
||||
* autorun script.
|
||||
*/
|
||||
function classes_defined_in_initial_file() {
|
||||
if (preg_match_all('/\bclass\s+(\w+)/i', file_get_contents(initial_file()), $matches)) {
|
||||
return array_map('strtolower', $matches[1]);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Every class since the first autorun include. This
|
||||
* is safe enough if require_once() is alwyas used.
|
||||
* @return array Class names.
|
||||
*/
|
||||
function capture_new_classes() {
|
||||
global $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES;
|
||||
return array_map('strtolower', array_diff(get_declared_classes(),
|
||||
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES ?
|
||||
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES : array()));
|
||||
}
|
||||
?>
|
||||
+1063
-1062
File diff suppressed because it is too large
Load Diff
+107
-92
@@ -1,107 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* This file contains the following classes: {@link SimpleCollector},
|
||||
* {@link SimplePatternCollector}.
|
||||
*
|
||||
* @author Travis Swicegood <[email protected]>
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* The basic collector for {@link GroupTest}
|
||||
*
|
||||
* @see collect(), GroupTest::collect()
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleCollector {
|
||||
|
||||
/**
|
||||
* This file contains the following classes: {@link SimpleCollector},
|
||||
* {@link SimplePatternCollector}.
|
||||
*
|
||||
* @author Travis Swicegood <[email protected]>
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
* Strips off any kind of slash at the end so as to normalise the path.
|
||||
* @param string $path Path to normalise.
|
||||
* @return string Path without trailing slash.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The basic collector for {@link GroupTest}
|
||||
*
|
||||
* @see collect(), GroupTest::collect()
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleCollector {
|
||||
|
||||
/**
|
||||
* Strips off any kind of slash at the end so as to normalise the path.
|
||||
* @param string $path Path to normalise.
|
||||
* @return string Path without trailing slash.
|
||||
*/
|
||||
function _removeTrailingSlash($path) {
|
||||
if (substr($path, -1) == DIRECTORY_SEPARATOR) {
|
||||
return substr($path, 0, -1);
|
||||
} elseif (substr($path, -1) == '/') {
|
||||
return substr($path, 0, -1);
|
||||
} else {
|
||||
return $path;
|
||||
}
|
||||
function _removeTrailingSlash($path) {
|
||||
if (substr($path, -1) == DIRECTORY_SEPARATOR) {
|
||||
return substr($path, 0, -1);
|
||||
} elseif (substr($path, -1) == '/') {
|
||||
return substr($path, 0, -1);
|
||||
} else {
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the directory and adds what it can.
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $path Directory to scan.
|
||||
* @see _attemptToAdd()
|
||||
*/
|
||||
function collect(&$test, $path) {
|
||||
$path = $this->_removeTrailingSlash($path);
|
||||
if ($handle = opendir($path)) {
|
||||
while (($entry = readdir($handle)) !== false) {
|
||||
$this->_handle($test, $path . DIRECTORY_SEPARATOR . $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the directory and adds what it can.
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $path Directory to scan.
|
||||
* @see _attemptToAdd()
|
||||
*/
|
||||
function collect(&$test, $path) {
|
||||
$path = $this->_removeTrailingSlash($path);
|
||||
if ($handle = opendir($path)) {
|
||||
while (($entry = readdir($handle)) !== false) {
|
||||
if ($this->_isHidden($entry)) {
|
||||
continue;
|
||||
}
|
||||
closedir($handle);
|
||||
$this->_handle($test, $path . DIRECTORY_SEPARATOR . $entry);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method determines what should be done with a given file and adds
|
||||
* it via {@link GroupTest::addTestFile()} if necessary.
|
||||
*
|
||||
* This method should be overriden to provide custom matching criteria,
|
||||
* such as pattern matching, recursive matching, etc. For an example, see
|
||||
* {@link SimplePatternCollector::_handle()}.
|
||||
*
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $filename A filename as generated by {@link collect()}
|
||||
* @see collect()
|
||||
* @access protected
|
||||
*/
|
||||
function _handle(&$test, $file) {
|
||||
if (! is_dir($file)) {
|
||||
$test->addTestFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method determines what should be done with a given file and adds
|
||||
* it via {@link GroupTest::addTestFile()} if necessary.
|
||||
*
|
||||
* This method should be overriden to provide custom matching criteria,
|
||||
* such as pattern matching, recursive matching, etc. For an example, see
|
||||
* {@link SimplePatternCollector::_handle()}.
|
||||
*
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $filename A filename as generated by {@link collect()}
|
||||
* @see collect()
|
||||
* @access protected
|
||||
*/
|
||||
function _handle(&$test, $file) {
|
||||
if (is_dir($file)) {
|
||||
return;
|
||||
}
|
||||
$test->addTestFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension to {@link SimpleCollector} that only adds files matching a
|
||||
* given pattern.
|
||||
*
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @see SimpleCollector
|
||||
* Tests for hidden files so as to skip them. Currently
|
||||
* only tests for Unix hidden files.
|
||||
* @param string $filename Plain filename.
|
||||
* @return boolean True if hidden file.
|
||||
* @access private
|
||||
*/
|
||||
class SimplePatternCollector extends SimpleCollector {
|
||||
var $_pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $pattern Perl compatible regex to test name against
|
||||
* See {@link http://us4.php.net/manual/en/reference.pcre.pattern.syntax.php PHP's PCRE}
|
||||
* for full documentation of valid pattern.s
|
||||
*/
|
||||
function SimplePatternCollector($pattern = '/php$/i') {
|
||||
$this->_pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add files that match a given pattern.
|
||||
*
|
||||
* @see SimpleCollector::_handle()
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $path Directory to scan.
|
||||
* @access protected
|
||||
*/
|
||||
function _handle(&$test, $filename) {
|
||||
if (preg_match($this->_pattern, $filename)) {
|
||||
parent::_handle($test, $filename);
|
||||
}
|
||||
function _isHidden($filename) {
|
||||
return strncmp($filename, '.', 1) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension to {@link SimpleCollector} that only adds files matching a
|
||||
* given pattern.
|
||||
*
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @see SimpleCollector
|
||||
*/
|
||||
class SimplePatternCollector extends SimpleCollector {
|
||||
var $_pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $pattern Perl compatible regex to test name against
|
||||
* See {@link http://us4.php.net/manual/en/reference.pcre.pattern.syntax.php PHP's PCRE}
|
||||
* for full documentation of valid pattern.s
|
||||
*/
|
||||
function SimplePatternCollector($pattern = '/php$/i') {
|
||||
$this->_pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add files that match a given pattern.
|
||||
*
|
||||
* @see SimpleCollector::_handle()
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $path Directory to scan.
|
||||
* @access protected
|
||||
*/
|
||||
function _handle(&$test, $filename) {
|
||||
if (preg_match($this->_pattern, $filename)) {
|
||||
parent::_handle($test, $filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
+155
-155
@@ -1,173 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Static methods for compatibility between different
|
||||
* PHP versions.
|
||||
* @package SimpleTest
|
||||
*/
|
||||
class SimpleTestCompatibility {
|
||||
|
||||
/**
|
||||
* Static methods for compatibility between different
|
||||
* PHP versions.
|
||||
* @package SimpleTest
|
||||
* Creates a copy whether in PHP5 or PHP4.
|
||||
* @param object $object Thing to copy.
|
||||
* @return object A copy.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
class SimpleTestCompatibility {
|
||||
|
||||
/**
|
||||
* Creates a copy whether in PHP5 or PHP4.
|
||||
* @param object $object Thing to copy.
|
||||
* @return object A copy.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function copy($object) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
eval('$copy = clone $object;');
|
||||
return $copy;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity test. Drops back to equality + types for PHP5
|
||||
* objects as the === operator counts as the
|
||||
* stronger reference constraint.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if identical.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isIdentical($first, $second) {
|
||||
if ($first != $second) {
|
||||
function copy($object) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
eval('$copy = clone $object;');
|
||||
return $copy;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity test. Drops back to equality + types for PHP5
|
||||
* objects as the === operator counts as the
|
||||
* stronger reference constraint.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if identical.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isIdentical($first, $second) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
return SimpleTestCompatibility::_isIdenticalType($first, $second);
|
||||
}
|
||||
if ($first != $second) {
|
||||
return false;
|
||||
}
|
||||
return ($first === $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive type test.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if same type.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _isIdenticalType($first, $second) {
|
||||
if (gettype($first) != gettype($second)) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($first) && is_object($second)) {
|
||||
if (get_class($first) != get_class($second)) {
|
||||
return false;
|
||||
}
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
return SimpleTestCompatibility::_isIdenticalType($first, $second);
|
||||
return SimpleTestCompatibility::_isArrayOfIdenticalTypes(
|
||||
get_object_vars($first),
|
||||
get_object_vars($second));
|
||||
}
|
||||
if (is_array($first) && is_array($second)) {
|
||||
return SimpleTestCompatibility::_isArrayOfIdenticalTypes($first, $second);
|
||||
}
|
||||
if ($first !== $second) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive type test for each element of an array.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if identical.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _isArrayOfIdenticalTypes($first, $second) {
|
||||
if (array_keys($first) != array_keys($second)) {
|
||||
return false;
|
||||
}
|
||||
foreach (array_keys($first) as $key) {
|
||||
$is_identical = SimpleTestCompatibility::_isIdenticalType(
|
||||
$first[$key],
|
||||
$second[$key]);
|
||||
if (! $is_identical) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for two variables being aliases.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if same.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isReference(&$first, &$second) {
|
||||
if (version_compare(phpversion(), '5', '>=') && is_object($first)) {
|
||||
return ($first === $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive type test.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if same type.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _isIdenticalType($first, $second) {
|
||||
if (gettype($first) != gettype($second)) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($first) && is_object($second)) {
|
||||
if (get_class($first) != get_class($second)) {
|
||||
return false;
|
||||
}
|
||||
return SimpleTestCompatibility::_isArrayOfIdenticalTypes(
|
||||
get_object_vars($first),
|
||||
get_object_vars($second));
|
||||
}
|
||||
if (is_array($first) && is_array($second)) {
|
||||
return SimpleTestCompatibility::_isArrayOfIdenticalTypes($first, $second);
|
||||
}
|
||||
if ($first !== $second) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive type test for each element of an array.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if identical.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _isArrayOfIdenticalTypes($first, $second) {
|
||||
if (array_keys($first) != array_keys($second)) {
|
||||
return false;
|
||||
}
|
||||
foreach (array_keys($first) as $key) {
|
||||
$is_identical = SimpleTestCompatibility::_isIdenticalType(
|
||||
$first[$key],
|
||||
$second[$key]);
|
||||
if (! $is_identical) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for two variables being aliases.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if same.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isReference(&$first, &$second) {
|
||||
if (version_compare(phpversion(), '5', '>=') && is_object($first)) {
|
||||
return ($first === $second);
|
||||
}
|
||||
if (is_object($first) && is_object($second)) {
|
||||
$id = uniqid("test");
|
||||
$first->$id = true;
|
||||
$is_ref = isset($second->$id);
|
||||
unset($first->$id);
|
||||
return $is_ref;
|
||||
}
|
||||
$temp = $first;
|
||||
$first = uniqid("test");
|
||||
$is_ref = ($first === $second);
|
||||
$first = $temp;
|
||||
if (is_object($first) && is_object($second)) {
|
||||
$id = uniqid("test");
|
||||
$first->$id = true;
|
||||
$is_ref = isset($second->$id);
|
||||
unset($first->$id);
|
||||
return $is_ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if an object is a member of a
|
||||
* class hiearchy.
|
||||
* @param object $object Object to test.
|
||||
* @param string $class Root name of hiearchy.
|
||||
* @return boolean True if class in hiearchy.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isA($object, $class) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
if (! class_exists($class, false)) {
|
||||
if (function_exists('interface_exists')) {
|
||||
if (! interface_exists($class, false)) {
|
||||
return false;
|
||||
}
|
||||
$temp = $first;
|
||||
$first = uniqid("test");
|
||||
$is_ref = ($first === $second);
|
||||
$first = $temp;
|
||||
return $is_ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if an object is a member of a
|
||||
* class hiearchy.
|
||||
* @param object $object Object to test.
|
||||
* @param string $class Root name of hiearchy.
|
||||
* @return boolean True if class in hiearchy.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isA($object, $class) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
if (! class_exists($class, false)) {
|
||||
if (function_exists('interface_exists')) {
|
||||
if (! interface_exists($class, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
eval("\$is_a = \$object instanceof $class;");
|
||||
return $is_a;
|
||||
}
|
||||
if (function_exists('is_a')) {
|
||||
return is_a($object, $class);
|
||||
}
|
||||
return ((strtolower($class) == get_class($object))
|
||||
or (is_subclass_of($object, $class)));
|
||||
eval("\$is_a = \$object instanceof $class;");
|
||||
return $is_a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a socket timeout for each chunk.
|
||||
* @param resource $handle Socket handle.
|
||||
* @param integer $timeout Limit in seconds.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function setTimeout($handle, $timeout) {
|
||||
if (function_exists('stream_set_timeout')) {
|
||||
stream_set_timeout($handle, $timeout, 0);
|
||||
} elseif (function_exists('socket_set_timeout')) {
|
||||
socket_set_timeout($handle, $timeout, 0);
|
||||
} elseif (function_exists('set_socket_timeout')) {
|
||||
set_socket_timeout($handle, $timeout, 0);
|
||||
}
|
||||
if (function_exists('is_a')) {
|
||||
return is_a($object, $class);
|
||||
}
|
||||
return ((strtolower($class) == get_class($object))
|
||||
or (is_subclass_of($object, $class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a socket timeout for each chunk.
|
||||
* @param resource $handle Socket handle.
|
||||
* @param integer $timeout Limit in seconds.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function setTimeout($handle, $timeout) {
|
||||
if (function_exists('stream_set_timeout')) {
|
||||
stream_set_timeout($handle, $timeout, 0);
|
||||
} elseif (function_exists('socket_set_timeout')) {
|
||||
socket_set_timeout($handle, $timeout, 0);
|
||||
} elseif (function_exists('set_socket_timeout')) {
|
||||
set_socket_timeout($handle, $timeout, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
+365
-365
@@ -1,380 +1,380 @@
|
||||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/url.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/url.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Cookie data holder. Cookie rules are full of pretty
|
||||
* arbitary stuff. I have used...
|
||||
* http://wp.netscape.com/newsref/std/cookie_spec.html
|
||||
* http://www.cookiecentral.com/faq/
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleCookie {
|
||||
var $_host;
|
||||
var $_name;
|
||||
var $_value;
|
||||
var $_path;
|
||||
var $_expiry;
|
||||
var $_is_secure;
|
||||
|
||||
/**
|
||||
* Cookie data holder. Cookie rules are full of pretty
|
||||
* arbitary stuff. I have used...
|
||||
* http://wp.netscape.com/newsref/std/cookie_spec.html
|
||||
* http://www.cookiecentral.com/faq/
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Constructor. Sets the stored values.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date as string.
|
||||
* @param boolean $is_secure Currently ignored.
|
||||
*/
|
||||
class SimpleCookie {
|
||||
var $_host;
|
||||
var $_name;
|
||||
var $_value;
|
||||
var $_path;
|
||||
var $_expiry;
|
||||
var $_is_secure;
|
||||
|
||||
/**
|
||||
* Constructor. Sets the stored values.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date as string.
|
||||
* @param boolean $is_secure Currently ignored.
|
||||
*/
|
||||
function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
|
||||
$this->_host = false;
|
||||
$this->_name = $name;
|
||||
$this->_value = $value;
|
||||
$this->_path = ($path ? $this->_fixPath($path) : "/");
|
||||
$this->_expiry = false;
|
||||
if (is_string($expiry)) {
|
||||
$this->_expiry = strtotime($expiry);
|
||||
} elseif (is_integer($expiry)) {
|
||||
$this->_expiry = $expiry;
|
||||
}
|
||||
$this->_is_secure = $is_secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host. The cookie rules determine
|
||||
* that the first two parts are taken for
|
||||
* certain TLDs and three for others. If the
|
||||
* new host does not match these rules then the
|
||||
* call will fail.
|
||||
* @param string $host New hostname.
|
||||
* @return boolean True if hostname is valid.
|
||||
* @access public
|
||||
*/
|
||||
function setHost($host) {
|
||||
if ($host = $this->_truncateHost($host)) {
|
||||
$this->_host = $host;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the truncated host to which this
|
||||
* cookie applies.
|
||||
* @return string Truncated hostname.
|
||||
* @access public
|
||||
*/
|
||||
function getHost() {
|
||||
return $this->_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for a cookie being valid for a host name.
|
||||
* @param string $host Host to test against.
|
||||
* @return boolean True if the cookie would be valid
|
||||
* here.
|
||||
*/
|
||||
function isValidHost($host) {
|
||||
return ($this->_truncateHost($host) === $this->getHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts just the domain part that determines a
|
||||
* cookie's host validity.
|
||||
* @param string $host Host name to truncate.
|
||||
* @return string Domain or false on a bad host.
|
||||
* @access private
|
||||
*/
|
||||
function _truncateHost($host) {
|
||||
$tlds = SimpleUrl::getAllTopLevelDomains();
|
||||
if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
|
||||
return $matches[0];
|
||||
} elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
|
||||
return $matches[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for name.
|
||||
* @return string Cookie key.
|
||||
* @access public
|
||||
*/
|
||||
function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for value. A deleted cookie will
|
||||
* have an empty string for this.
|
||||
* @return string Cookie value.
|
||||
* @access public
|
||||
*/
|
||||
function getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for path.
|
||||
* @return string Valid cookie path.
|
||||
* @access public
|
||||
*/
|
||||
function getPath() {
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a path to see if the cookie applies
|
||||
* there. The test path must be longer or
|
||||
* equal to the cookie path.
|
||||
* @param string $path Path to test against.
|
||||
* @return boolean True if cookie valid here.
|
||||
* @access public
|
||||
*/
|
||||
function isValidPath($path) {
|
||||
return (strncmp(
|
||||
$this->_fixPath($path),
|
||||
$this->getPath(),
|
||||
strlen($this->getPath())) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for expiry.
|
||||
* @return string Expiry string.
|
||||
* @access public
|
||||
*/
|
||||
function getExpiry() {
|
||||
if (! $this->_expiry) {
|
||||
return false;
|
||||
}
|
||||
return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if cookie is expired against
|
||||
* the cookie format time or timestamp.
|
||||
* Will give true for a session cookie.
|
||||
* @param integer/string $now Time to test against. Result
|
||||
* will be false if this time
|
||||
* is later than the cookie expiry.
|
||||
* Can be either a timestamp integer
|
||||
* or a cookie format date.
|
||||
* @access public
|
||||
*/
|
||||
function isExpired($now) {
|
||||
if (! $this->_expiry) {
|
||||
return true;
|
||||
}
|
||||
if (is_string($now)) {
|
||||
$now = strtotime($now);
|
||||
}
|
||||
return ($this->_expiry < $now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages the cookie by the specified number of
|
||||
* seconds.
|
||||
* @param integer $interval In seconds.
|
||||
* @public
|
||||
*/
|
||||
function agePrematurely($interval) {
|
||||
if ($this->_expiry) {
|
||||
$this->_expiry -= $interval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the secure flag.
|
||||
* @return boolean True if cookie needs SSL.
|
||||
* @access public
|
||||
*/
|
||||
function isSecure() {
|
||||
return $this->_is_secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a trailing and leading slash to the path
|
||||
* if missing.
|
||||
* @param string $path Path to fix.
|
||||
* @access private
|
||||
*/
|
||||
function _fixPath($path) {
|
||||
if (substr($path, 0, 1) != '/') {
|
||||
$path = '/' . $path;
|
||||
}
|
||||
if (substr($path, -1, 1) != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
return $path;
|
||||
function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
|
||||
$this->_host = false;
|
||||
$this->_name = $name;
|
||||
$this->_value = $value;
|
||||
$this->_path = ($path ? $this->_fixPath($path) : "/");
|
||||
$this->_expiry = false;
|
||||
if (is_string($expiry)) {
|
||||
$this->_expiry = strtotime($expiry);
|
||||
} elseif (is_integer($expiry)) {
|
||||
$this->_expiry = $expiry;
|
||||
}
|
||||
$this->_is_secure = $is_secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository for cookies. This stuff is a
|
||||
* tiny bit browser dependent.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Sets the host. The cookie rules determine
|
||||
* that the first two parts are taken for
|
||||
* certain TLDs and three for others. If the
|
||||
* new host does not match these rules then the
|
||||
* call will fail.
|
||||
* @param string $host New hostname.
|
||||
* @return boolean True if hostname is valid.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleCookieJar {
|
||||
var $_cookies;
|
||||
|
||||
/**
|
||||
* Constructor. Jar starts empty.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleCookieJar() {
|
||||
$this->_cookies = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes expired and temporary cookies as if
|
||||
* the browser was closed and re-opened.
|
||||
* @param string/integer $now Time to test expiry against.
|
||||
* @access public
|
||||
*/
|
||||
function restartSession($date = false) {
|
||||
$surviving_cookies = array();
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
if (! $this->_cookies[$i]->getValue()) {
|
||||
continue;
|
||||
}
|
||||
if (! $this->_cookies[$i]->getExpiry()) {
|
||||
continue;
|
||||
}
|
||||
if ($date && $this->_cookies[$i]->isExpired($date)) {
|
||||
continue;
|
||||
}
|
||||
$surviving_cookies[] = $this->_cookies[$i];
|
||||
}
|
||||
$this->_cookies = $surviving_cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages all cookies in the cookie jar.
|
||||
* @param integer $interval The old session is moved
|
||||
* into the past by this number
|
||||
* of seconds. Cookies now over
|
||||
* age will be removed.
|
||||
* @access public
|
||||
*/
|
||||
function agePrematurely($interval) {
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
$this->_cookies[$i]->agePrematurely($interval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional cookie. If a cookie has
|
||||
* the same name and path it is replaced.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $host Host upon which the cookie is valid.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date.
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
||||
$cookie = new SimpleCookie($name, $value, $path, $expiry);
|
||||
if ($host) {
|
||||
$cookie->setHost($host);
|
||||
}
|
||||
$this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a matching cookie to write over or the
|
||||
* first empty slot if none.
|
||||
* @param SimpleCookie $cookie Cookie to write into jar.
|
||||
* @return integer Available slot.
|
||||
* @access private
|
||||
*/
|
||||
function _findFirstMatch($cookie) {
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
$is_match = $this->_isMatch(
|
||||
$cookie,
|
||||
$this->_cookies[$i]->getHost(),
|
||||
$this->_cookies[$i]->getPath(),
|
||||
$this->_cookies[$i]->getName());
|
||||
if ($is_match) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
return count($this->_cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the most specific cookie value from the
|
||||
* browser cookies. Looks for the longest path that
|
||||
* matches.
|
||||
* @param string $host Host to search.
|
||||
* @param string $path Applicable path.
|
||||
* @param string $name Name of cookie to read.
|
||||
* @return string False if not present, else the
|
||||
* value as a string.
|
||||
* @access public
|
||||
*/
|
||||
function getCookieValue($host, $path, $name) {
|
||||
$longest_path = '';
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
if ($this->_isMatch($cookie, $host, $path, $name)) {
|
||||
if (strlen($cookie->getPath()) > strlen($longest_path)) {
|
||||
$value = $cookie->getValue();
|
||||
$longest_path = $cookie->getPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
return (isset($value) ? $value : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests cookie for matching against search
|
||||
* criteria.
|
||||
* @param SimpleTest $cookie Cookie to test.
|
||||
* @param string $host Host must match.
|
||||
* @param string $path Cookie path must be shorter than
|
||||
* this path.
|
||||
* @param string $name Name must match.
|
||||
* @return boolean True if matched.
|
||||
* @access private
|
||||
*/
|
||||
function _isMatch($cookie, $host, $path, $name) {
|
||||
if ($cookie->getName() != $name) {
|
||||
return false;
|
||||
}
|
||||
if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
|
||||
return false;
|
||||
}
|
||||
if (! $cookie->isValidPath($path)) {
|
||||
return false;
|
||||
}
|
||||
function setHost($host) {
|
||||
if ($host = $this->_truncateHost($host)) {
|
||||
$this->_host = $host;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses a URL to sift relevant cookies by host and
|
||||
* path. Results are list of strings of form "name=value".
|
||||
* @param SimpleUrl $url Url to select by.
|
||||
* @return array Valid name and value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function selectAsPairs($url) {
|
||||
$pairs = array();
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
|
||||
$pairs[] = $cookie->getName() . '=' . $cookie->getValue();
|
||||
}
|
||||
}
|
||||
return $pairs;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the truncated host to which this
|
||||
* cookie applies.
|
||||
* @return string Truncated hostname.
|
||||
* @access public
|
||||
*/
|
||||
function getHost() {
|
||||
return $this->_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for a cookie being valid for a host name.
|
||||
* @param string $host Host to test against.
|
||||
* @return boolean True if the cookie would be valid
|
||||
* here.
|
||||
*/
|
||||
function isValidHost($host) {
|
||||
return ($this->_truncateHost($host) === $this->getHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts just the domain part that determines a
|
||||
* cookie's host validity.
|
||||
* @param string $host Host name to truncate.
|
||||
* @return string Domain or false on a bad host.
|
||||
* @access private
|
||||
*/
|
||||
function _truncateHost($host) {
|
||||
$tlds = SimpleUrl::getAllTopLevelDomains();
|
||||
if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
|
||||
return $matches[0];
|
||||
} elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
|
||||
return $matches[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for name.
|
||||
* @return string Cookie key.
|
||||
* @access public
|
||||
*/
|
||||
function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for value. A deleted cookie will
|
||||
* have an empty string for this.
|
||||
* @return string Cookie value.
|
||||
* @access public
|
||||
*/
|
||||
function getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for path.
|
||||
* @return string Valid cookie path.
|
||||
* @access public
|
||||
*/
|
||||
function getPath() {
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a path to see if the cookie applies
|
||||
* there. The test path must be longer or
|
||||
* equal to the cookie path.
|
||||
* @param string $path Path to test against.
|
||||
* @return boolean True if cookie valid here.
|
||||
* @access public
|
||||
*/
|
||||
function isValidPath($path) {
|
||||
return (strncmp(
|
||||
$this->_fixPath($path),
|
||||
$this->getPath(),
|
||||
strlen($this->getPath())) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for expiry.
|
||||
* @return string Expiry string.
|
||||
* @access public
|
||||
*/
|
||||
function getExpiry() {
|
||||
if (! $this->_expiry) {
|
||||
return false;
|
||||
}
|
||||
return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if cookie is expired against
|
||||
* the cookie format time or timestamp.
|
||||
* Will give true for a session cookie.
|
||||
* @param integer/string $now Time to test against. Result
|
||||
* will be false if this time
|
||||
* is later than the cookie expiry.
|
||||
* Can be either a timestamp integer
|
||||
* or a cookie format date.
|
||||
* @access public
|
||||
*/
|
||||
function isExpired($now) {
|
||||
if (! $this->_expiry) {
|
||||
return true;
|
||||
}
|
||||
if (is_string($now)) {
|
||||
$now = strtotime($now);
|
||||
}
|
||||
return ($this->_expiry < $now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages the cookie by the specified number of
|
||||
* seconds.
|
||||
* @param integer $interval In seconds.
|
||||
* @public
|
||||
*/
|
||||
function agePrematurely($interval) {
|
||||
if ($this->_expiry) {
|
||||
$this->_expiry -= $interval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the secure flag.
|
||||
* @return boolean True if cookie needs SSL.
|
||||
* @access public
|
||||
*/
|
||||
function isSecure() {
|
||||
return $this->_is_secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a trailing and leading slash to the path
|
||||
* if missing.
|
||||
* @param string $path Path to fix.
|
||||
* @access private
|
||||
*/
|
||||
function _fixPath($path) {
|
||||
if (substr($path, 0, 1) != '/') {
|
||||
$path = '/' . $path;
|
||||
}
|
||||
if (substr($path, -1, 1) != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository for cookies. This stuff is a
|
||||
* tiny bit browser dependent.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleCookieJar {
|
||||
var $_cookies;
|
||||
|
||||
/**
|
||||
* Constructor. Jar starts empty.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleCookieJar() {
|
||||
$this->_cookies = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes expired and temporary cookies as if
|
||||
* the browser was closed and re-opened.
|
||||
* @param string/integer $now Time to test expiry against.
|
||||
* @access public
|
||||
*/
|
||||
function restartSession($date = false) {
|
||||
$surviving_cookies = array();
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
if (! $this->_cookies[$i]->getValue()) {
|
||||
continue;
|
||||
}
|
||||
if (! $this->_cookies[$i]->getExpiry()) {
|
||||
continue;
|
||||
}
|
||||
if ($date && $this->_cookies[$i]->isExpired($date)) {
|
||||
continue;
|
||||
}
|
||||
$surviving_cookies[] = $this->_cookies[$i];
|
||||
}
|
||||
$this->_cookies = $surviving_cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages all cookies in the cookie jar.
|
||||
* @param integer $interval The old session is moved
|
||||
* into the past by this number
|
||||
* of seconds. Cookies now over
|
||||
* age will be removed.
|
||||
* @access public
|
||||
*/
|
||||
function agePrematurely($interval) {
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
$this->_cookies[$i]->agePrematurely($interval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional cookie. If a cookie has
|
||||
* the same name and path it is replaced.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $host Host upon which the cookie is valid.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date.
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
||||
$cookie = new SimpleCookie($name, $value, $path, $expiry);
|
||||
if ($host) {
|
||||
$cookie->setHost($host);
|
||||
}
|
||||
$this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a matching cookie to write over or the
|
||||
* first empty slot if none.
|
||||
* @param SimpleCookie $cookie Cookie to write into jar.
|
||||
* @return integer Available slot.
|
||||
* @access private
|
||||
*/
|
||||
function _findFirstMatch($cookie) {
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
$is_match = $this->_isMatch(
|
||||
$cookie,
|
||||
$this->_cookies[$i]->getHost(),
|
||||
$this->_cookies[$i]->getPath(),
|
||||
$this->_cookies[$i]->getName());
|
||||
if ($is_match) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
return count($this->_cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the most specific cookie value from the
|
||||
* browser cookies. Looks for the longest path that
|
||||
* matches.
|
||||
* @param string $host Host to search.
|
||||
* @param string $path Applicable path.
|
||||
* @param string $name Name of cookie to read.
|
||||
* @return string False if not present, else the
|
||||
* value as a string.
|
||||
* @access public
|
||||
*/
|
||||
function getCookieValue($host, $path, $name) {
|
||||
$longest_path = '';
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
if ($this->_isMatch($cookie, $host, $path, $name)) {
|
||||
if (strlen($cookie->getPath()) > strlen($longest_path)) {
|
||||
$value = $cookie->getValue();
|
||||
$longest_path = $cookie->getPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
return (isset($value) ? $value : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests cookie for matching against search
|
||||
* criteria.
|
||||
* @param SimpleTest $cookie Cookie to test.
|
||||
* @param string $host Host must match.
|
||||
* @param string $path Cookie path must be shorter than
|
||||
* this path.
|
||||
* @param string $name Name must match.
|
||||
* @return boolean True if matched.
|
||||
* @access private
|
||||
*/
|
||||
function _isMatch($cookie, $host, $path, $name) {
|
||||
if ($cookie->getName() != $name) {
|
||||
return false;
|
||||
}
|
||||
if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
|
||||
return false;
|
||||
}
|
||||
if (! $cookie->isValidPath($path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses a URL to sift relevant cookies by host and
|
||||
* path. Results are list of strings of form "name=value".
|
||||
* @param SimpleUrl $url Url to select by.
|
||||
* @return array Valid name and value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function selectAsPairs($url) {
|
||||
$pairs = array();
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
|
||||
$pairs[] = $cookie->getName() . '=' . $cookie->getValue();
|
||||
}
|
||||
}
|
||||
return $pairs;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/**
|
||||
* Optional include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/simpletest.php');
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
require_once(dirname(__FILE__) . '/reporter.php');
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Parser for command line arguments. Extracts
|
||||
* the a specific test to run and engages XML
|
||||
* reporting when necessary.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleCommandLineParser {
|
||||
var $_to_property = array(
|
||||
'case' => '_case', 'c' => '_case',
|
||||
'test' => '_test', 't' => '_test',
|
||||
'xml' => '_xml', 'x' => '_xml');
|
||||
var $_case = '';
|
||||
var $_test = '';
|
||||
var $_xml = false;
|
||||
var $_no_skips = false;
|
||||
|
||||
/**
|
||||
* Parses raw command line arguments into object properties.
|
||||
* @param string $arguments Raw commend line arguments.
|
||||
*/
|
||||
function SimpleCommandLineParser($arguments) {
|
||||
if (! is_array($arguments)) {
|
||||
return;
|
||||
}
|
||||
foreach ($arguments as $i => $argument) {
|
||||
if (preg_match('/^--?(test|case|t|c)=(.+)$/', $argument, $matches)) {
|
||||
$property = $this->_to_property[$matches[1]];
|
||||
$this->$property = $matches[2];
|
||||
} elseif (preg_match('/^--?(test|case|t|c)$/', $argument, $matches)) {
|
||||
$property = $this->_to_property[$matches[1]];
|
||||
if (isset($arguments[$i + 1])) {
|
||||
$this->$property = $arguments[$i + 1];
|
||||
}
|
||||
} elseif (preg_match('/^--?(xml|x)$/', $argument)) {
|
||||
$this->_xml = true;
|
||||
} elseif (preg_match('/^--?(no-skip|no-skips|s)$/', $argument)) {
|
||||
$this->_no_skips = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run only this test.
|
||||
* @return string Test name to run.
|
||||
* @access public
|
||||
*/
|
||||
function getTest() {
|
||||
return $this->_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run only this test suite.
|
||||
* @return string Test class name to run.
|
||||
* @access public
|
||||
*/
|
||||
function getTestCase() {
|
||||
return $this->_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output should be XML or not.
|
||||
* @return boolean True if XML desired.
|
||||
* @access public
|
||||
*/
|
||||
function isXml() {
|
||||
return $this->_xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output should suppress skip messages.
|
||||
* @return boolean True for no skips.
|
||||
* @access public
|
||||
*/
|
||||
function noSkips() {
|
||||
return $this->_no_skips;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default reporter used by SimpleTest's autorun
|
||||
* feature. The actual reporters used are dependency
|
||||
* injected and can be overridden.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class DefaultReporter extends SimpleReporterDecorator {
|
||||
|
||||
/**
|
||||
* Assembles the appopriate reporter for the environment.
|
||||
*/
|
||||
function DefaultReporter() {
|
||||
if (SimpleReporter::inCli()) {
|
||||
global $argv;
|
||||
$parser = new SimpleCommandLineParser($argv);
|
||||
$interfaces = $parser->isXml() ? array('XmlReporter') : array('TextReporter');
|
||||
$reporter = &new SelectiveReporter(
|
||||
SimpleTest::preferred($interfaces),
|
||||
$parser->getTestCase(),
|
||||
$parser->getTest());
|
||||
if ($parser->noSkips()) {
|
||||
$reporter = &new NoSkipsReporter($reporter);
|
||||
}
|
||||
} else {
|
||||
$reporter = &new SelectiveReporter(
|
||||
SimpleTest::preferred('HtmlReporter'),
|
||||
@$_GET['c'],
|
||||
@$_GET['t']);
|
||||
if (@$_GET['skips'] == 'no' || @$_GET['show-skips'] == 'no') {
|
||||
$reporter = &new NoSkipsReporter($reporter);
|
||||
}
|
||||
}
|
||||
$this->SimpleReporterDecorator($reporter);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,96 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
require_once(dirname(__FILE__) . '/shell_tester.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
require_once(dirname(__FILE__) . '/shell_tester.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Runs an XML formated test in a separate process.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class DetachedTestCase {
|
||||
var $_command;
|
||||
var $_dry_command;
|
||||
var $_size;
|
||||
|
||||
/**
|
||||
* Runs an XML formated test in a separate process.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Sets the location of the remote test.
|
||||
* @param string $command Test script.
|
||||
* @param string $dry_command Script for dry run.
|
||||
* @access public
|
||||
*/
|
||||
class DetachedTestCase {
|
||||
var $_command;
|
||||
var $_dry_command;
|
||||
var $_size;
|
||||
function DetachedTestCase($command, $dry_command = false) {
|
||||
$this->_command = $command;
|
||||
$this->_dry_command = $dry_command ? $dry_command : $command;
|
||||
$this->_size = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location of the remote test.
|
||||
* @param string $command Test script.
|
||||
* @param string $dry_command Script for dry run.
|
||||
* @access public
|
||||
*/
|
||||
function DetachedTestCase($command, $dry_command = false) {
|
||||
$this->_command = $command;
|
||||
$this->_dry_command = $dry_command ? $dry_command : $command;
|
||||
$this->_size = false;
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the top level test for this class. Currently
|
||||
* reads the data as a single chunk. I'll fix this
|
||||
* once I have added iteration to the browser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @returns boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$shell = &new SimpleShell();
|
||||
$shell->execute($this->_command);
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($shell->getOutput())) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_command . ']');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the top level test for this class. Currently
|
||||
* reads the data as a single chunk. I'll fix this
|
||||
* once I have added iteration to the browser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @returns boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$shell = &new SimpleShell();
|
||||
$shell->execute($this->_command);
|
||||
/**
|
||||
* Accessor for the number of subtests.
|
||||
* @return integer Number of test cases.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
if ($this->_size === false) {
|
||||
$shell = &new SimpleShell();
|
||||
$shell->execute($this->_dry_command);
|
||||
$reporter = &new SimpleReporter();
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($shell->getOutput())) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_command . ']');
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_dry_command . ']');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of subtests.
|
||||
* @return integer Number of test cases.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
if ($this->_size === false) {
|
||||
$shell = &new SimpleShell();
|
||||
$shell->execute($this->_dry_command);
|
||||
$reporter = &new SimpleReporter();
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($shell->getOutput())) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_dry_command . ']');
|
||||
return false;
|
||||
}
|
||||
$this->_size = $reporter->getTestCaseCount();
|
||||
}
|
||||
return $this->_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the XML parser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @return SimpleTestXmlListener XML reader.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createParser(&$reporter) {
|
||||
return new SimpleTestXmlParser($reporter);
|
||||
$this->_size = $reporter->getTestCaseCount();
|
||||
}
|
||||
return $this->_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the XML parser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @return SimpleTestXmlListener XML reader.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createParser(&$reporter) {
|
||||
return new SimpleTestXmlParser($reporter);
|
||||
}
|
||||
}
|
||||
?>
|
||||
+334
-334
@@ -1,360 +1,360 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* does type matter
|
||||
*/
|
||||
if (! defined('TYPE_MATTERS')) {
|
||||
define('TYPE_MATTERS', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays variables as text and does diffs.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleDumper {
|
||||
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
* Renders a variable in a shorter form than print_r().
|
||||
* @param mixed $value Variable to render as a string.
|
||||
* @return string Human readable string form.
|
||||
* @access public
|
||||
*/
|
||||
/**
|
||||
* does type matter
|
||||
*/
|
||||
if (! defined('TYPE_MATTERS')) {
|
||||
define('TYPE_MATTERS', true);
|
||||
function describeValue($value) {
|
||||
$type = $this->getType($value);
|
||||
switch($type) {
|
||||
case "Null":
|
||||
return "NULL";
|
||||
case "Boolean":
|
||||
return "Boolean: " . ($value ? "true" : "false");
|
||||
case "Array":
|
||||
return "Array: " . count($value) . " items";
|
||||
case "Object":
|
||||
return "Object: of " . get_class($value);
|
||||
case "String":
|
||||
return "String: " . $this->clipString($value, 200);
|
||||
default:
|
||||
return "$type: $value";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays variables as text and does diffs.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Gets the string representation of a type.
|
||||
* @param mixed $value Variable to check against.
|
||||
* @return string Type.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleDumper {
|
||||
|
||||
/**
|
||||
* Renders a variable in a shorter form than print_r().
|
||||
* @param mixed $value Variable to render as a string.
|
||||
* @return string Human readable string form.
|
||||
* @access public
|
||||
*/
|
||||
function describeValue($value) {
|
||||
$type = $this->getType($value);
|
||||
switch($type) {
|
||||
case "Null":
|
||||
return "NULL";
|
||||
case "Boolean":
|
||||
return "Boolean: " . ($value ? "true" : "false");
|
||||
case "Array":
|
||||
return "Array: " . count($value) . " items";
|
||||
case "Object":
|
||||
return "Object: of " . get_class($value);
|
||||
case "String":
|
||||
return "String: " . $this->clipString($value, 200);
|
||||
default:
|
||||
return "$type: $value";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of a type.
|
||||
* @param mixed $value Variable to check against.
|
||||
* @return string Type.
|
||||
* @access public
|
||||
*/
|
||||
function getType($value) {
|
||||
if (! isset($value)) {
|
||||
return "Null";
|
||||
} elseif (is_bool($value)) {
|
||||
return "Boolean";
|
||||
} elseif (is_string($value)) {
|
||||
return "String";
|
||||
} elseif (is_integer($value)) {
|
||||
return "Integer";
|
||||
} elseif (is_float($value)) {
|
||||
return "Float";
|
||||
} elseif (is_array($value)) {
|
||||
return "Array";
|
||||
} elseif (is_resource($value)) {
|
||||
return "Resource";
|
||||
} elseif (is_object($value)) {
|
||||
return "Object";
|
||||
}
|
||||
return "Unknown";
|
||||
function getType($value) {
|
||||
if (! isset($value)) {
|
||||
return "Null";
|
||||
} elseif (is_bool($value)) {
|
||||
return "Boolean";
|
||||
} elseif (is_string($value)) {
|
||||
return "String";
|
||||
} elseif (is_integer($value)) {
|
||||
return "Integer";
|
||||
} elseif (is_float($value)) {
|
||||
return "Float";
|
||||
} elseif (is_array($value)) {
|
||||
return "Array";
|
||||
} elseif (is_resource($value)) {
|
||||
return "Resource";
|
||||
} elseif (is_object($value)) {
|
||||
return "Object";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two variables. Uses a
|
||||
* dynamic call.
|
||||
* @param mixed $first First variable.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Description of difference.
|
||||
* @access public
|
||||
*/
|
||||
function describeDifference($first, $second, $identical = false) {
|
||||
if ($identical) {
|
||||
if (! $this->_isTypeMatch($first, $second)) {
|
||||
return "with type mismatch as [" . $this->describeValue($first) .
|
||||
"] does not match [" . $this->describeValue($second) . "]";
|
||||
}
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two variables. Uses a
|
||||
* dynamic call.
|
||||
* @param mixed $first First variable.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Description of difference.
|
||||
* @access public
|
||||
*/
|
||||
function describeDifference($first, $second, $identical = false) {
|
||||
if ($identical) {
|
||||
if (! $this->_isTypeMatch($first, $second)) {
|
||||
return "with type mismatch as [" . $this->describeValue($first) .
|
||||
"] does not match [" . $this->describeValue($second) . "]";
|
||||
}
|
||||
$type = $this->getType($first);
|
||||
if ($type == "Unknown") {
|
||||
return "with unknown type";
|
||||
}
|
||||
$method = '_describe' . $type . 'Difference';
|
||||
return $this->$method($first, $second, $identical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if types match.
|
||||
* @param mixed $first First variable.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @return boolean True if matches.
|
||||
* @access private
|
||||
*/
|
||||
function _isTypeMatch($first, $second) {
|
||||
return ($this->getType($first) == $this->getType($second));
|
||||
$type = $this->getType($first);
|
||||
if ($type == "Unknown") {
|
||||
return "with unknown type";
|
||||
}
|
||||
$method = '_describe' . $type . 'Difference';
|
||||
return $this->$method($first, $second, $identical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if types match.
|
||||
* @param mixed $first First variable.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @return boolean True if matches.
|
||||
* @access private
|
||||
*/
|
||||
function _isTypeMatch($first, $second) {
|
||||
return ($this->getType($first) == $this->getType($second));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips a string to a maximum length.
|
||||
* @param string $value String to truncate.
|
||||
* @param integer $size Minimum string size to show.
|
||||
* @param integer $position Centre of string section.
|
||||
* @return string Shortened version.
|
||||
* @access public
|
||||
*/
|
||||
function clipString($value, $size, $position = 0) {
|
||||
$length = strlen($value);
|
||||
if ($length <= $size) {
|
||||
return $value;
|
||||
}
|
||||
$position = min($position, $length);
|
||||
$start = ($size/2 > $position ? 0 : $position - $size/2);
|
||||
if ($start + $size > $length) {
|
||||
$start = $length - $size;
|
||||
}
|
||||
$value = substr($value, $start, $size);
|
||||
return ($start > 0 ? "..." : "") . $value . ($start + $size < $length ? "..." : "");
|
||||
/**
|
||||
* Clips a string to a maximum length.
|
||||
* @param string $value String to truncate.
|
||||
* @param integer $size Minimum string size to show.
|
||||
* @param integer $position Centre of string section.
|
||||
* @return string Shortened version.
|
||||
* @access public
|
||||
*/
|
||||
function clipString($value, $size, $position = 0) {
|
||||
$length = strlen($value);
|
||||
if ($length <= $size) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two variables. The minimal
|
||||
* version.
|
||||
* @param null $first First value.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeGenericDifference($first, $second) {
|
||||
return "as [" . $this->describeValue($first) .
|
||||
"] does not match [" .
|
||||
$this->describeValue($second) . "]";
|
||||
$position = min($position, $length);
|
||||
$start = ($size/2 > $position ? 0 : $position - $size/2);
|
||||
if ($start + $size > $length) {
|
||||
$start = $length - $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a null and another variable.
|
||||
* @param null $first First null.
|
||||
* @param mixed $second Null to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeNullDifference($first, $second, $identical) {
|
||||
$value = substr($value, $start, $size);
|
||||
return ($start > 0 ? "..." : "") . $value . ($start + $size < $length ? "..." : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two variables. The minimal
|
||||
* version.
|
||||
* @param null $first First value.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeGenericDifference($first, $second) {
|
||||
return "as [" . $this->describeValue($first) .
|
||||
"] does not match [" .
|
||||
$this->describeValue($second) . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a null and another variable.
|
||||
* @param null $first First null.
|
||||
* @param mixed $second Null to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeNullDifference($first, $second, $identical) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a boolean and another variable.
|
||||
* @param boolean $first First boolean.
|
||||
* @param mixed $second Boolean to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeBooleanDifference($first, $second, $identical) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a string and another variable.
|
||||
* @param string $first First string.
|
||||
* @param mixed $second String to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeStringDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a boolean and another variable.
|
||||
* @param boolean $first First boolean.
|
||||
* @param mixed $second Boolean to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeBooleanDifference($first, $second, $identical) {
|
||||
$position = $this->_stringDiffersAt($first, $second);
|
||||
$message = "at character $position";
|
||||
$message .= " with [" .
|
||||
$this->clipString($first, 200, $position) . "] and [" .
|
||||
$this->clipString($second, 200, $position) . "]";
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between an integer and another variable.
|
||||
* @param integer $first First number.
|
||||
* @param mixed $second Number to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeIntegerDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a string and another variable.
|
||||
* @param string $first First string.
|
||||
* @param mixed $second String to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeStringDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
$position = $this->_stringDiffersAt($first, $second);
|
||||
$message = "at character $position";
|
||||
$message .= " with [" .
|
||||
$this->clipString($first, 200, $position) . "] and [" .
|
||||
$this->clipString($second, 200, $position) . "]";
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between an integer and another variable.
|
||||
* @param integer $first First number.
|
||||
* @param mixed $second Number to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeIntegerDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
return "because [" . $this->describeValue($first) .
|
||||
"] differs from [" .
|
||||
$this->describeValue($second) . "] by " .
|
||||
abs($first - $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two floating point numbers.
|
||||
* @param float $first First float.
|
||||
* @param mixed $second Float to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeFloatDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
return "because [" . $this->describeValue($first) .
|
||||
"] differs from [" .
|
||||
$this->describeValue($second) . "] by " .
|
||||
abs($first - $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two arrays.
|
||||
* @param array $first First array.
|
||||
* @param mixed $second Array to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeArrayDifference($first, $second, $identical) {
|
||||
if (! is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
if (! $this->_isMatchingKeys($first, $second, $identical)) {
|
||||
return "as key list [" .
|
||||
implode(", ", array_keys($first)) . "] does not match key list [" .
|
||||
implode(", ", array_keys($second)) . "]";
|
||||
}
|
||||
foreach (array_keys($first) as $key) {
|
||||
if ($identical && ($first[$key] === $second[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (! $identical && ($first[$key] == $second[$key])) {
|
||||
continue;
|
||||
}
|
||||
return "with member [$key] " . $this->describeDifference(
|
||||
$first[$key],
|
||||
$second[$key],
|
||||
$identical);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two arrays to see if their key lists match.
|
||||
* For an identical match, the ordering and types of the keys
|
||||
* is significant.
|
||||
* @param array $first First array.
|
||||
* @param array $second Array to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return boolean True if matching.
|
||||
* @access private
|
||||
*/
|
||||
function _isMatchingKeys($first, $second, $identical) {
|
||||
$first_keys = array_keys($first);
|
||||
$second_keys = array_keys($second);
|
||||
if ($identical) {
|
||||
return ($first_keys === $second_keys);
|
||||
}
|
||||
sort($first_keys);
|
||||
sort($second_keys);
|
||||
return ($first_keys == $second_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a resource and another variable.
|
||||
* @param resource $first First resource.
|
||||
* @param mixed $second Resource to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeResourceDifference($first, $second, $identical) {
|
||||
return "because [" . $this->describeValue($first) .
|
||||
"] differs from [" .
|
||||
$this->describeValue($second) . "] by " .
|
||||
abs($first - $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two floating point numbers.
|
||||
* @param float $first First float.
|
||||
* @param mixed $second Float to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeFloatDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two objects.
|
||||
* @param object $first First object.
|
||||
* @param mixed $second Object to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeObjectDifference($first, $second, $identical) {
|
||||
if (! is_object($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
return "because [" . $this->describeValue($first) .
|
||||
"] differs from [" .
|
||||
$this->describeValue($second) . "] by " .
|
||||
abs($first - $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two arrays.
|
||||
* @param array $first First array.
|
||||
* @param mixed $second Array to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeArrayDifference($first, $second, $identical) {
|
||||
if (! is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
if (! $this->_isMatchingKeys($first, $second, $identical)) {
|
||||
return "as key list [" .
|
||||
implode(", ", array_keys($first)) . "] does not match key list [" .
|
||||
implode(", ", array_keys($second)) . "]";
|
||||
}
|
||||
foreach (array_keys($first) as $key) {
|
||||
if ($identical && ($first[$key] === $second[$key])) {
|
||||
continue;
|
||||
}
|
||||
return $this->_describeArrayDifference(
|
||||
get_object_vars($first),
|
||||
get_object_vars($second),
|
||||
if (! $identical && ($first[$key] == $second[$key])) {
|
||||
continue;
|
||||
}
|
||||
return "with member [$key] " . $this->describeDifference(
|
||||
$first[$key],
|
||||
$second[$key],
|
||||
$identical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first character position that differs
|
||||
* in two strings by binary chop.
|
||||
* @param string $first First string.
|
||||
* @param string $second String to compare with.
|
||||
* @return integer Position of first differing
|
||||
* character.
|
||||
* @access private
|
||||
*/
|
||||
function _stringDiffersAt($first, $second) {
|
||||
if (! $first || ! $second) {
|
||||
return 0;
|
||||
}
|
||||
if (strlen($first) < strlen($second)) {
|
||||
list($first, $second) = array($second, $first);
|
||||
}
|
||||
$position = 0;
|
||||
$step = strlen($first);
|
||||
while ($step > 1) {
|
||||
$step = (integer)(($step + 1) / 2);
|
||||
if (strncmp($first, $second, $position + $step) == 0) {
|
||||
$position += $step;
|
||||
}
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted dump of a variable to a string.
|
||||
* @param mixed $variable Variable to display.
|
||||
* @return string Output from print_r().
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function dump($variable) {
|
||||
ob_start();
|
||||
print_r($variable);
|
||||
$formatted = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $formatted;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two arrays to see if their key lists match.
|
||||
* For an identical match, the ordering and types of the keys
|
||||
* is significant.
|
||||
* @param array $first First array.
|
||||
* @param array $second Array to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return boolean True if matching.
|
||||
* @access private
|
||||
*/
|
||||
function _isMatchingKeys($first, $second, $identical) {
|
||||
$first_keys = array_keys($first);
|
||||
$second_keys = array_keys($second);
|
||||
if ($identical) {
|
||||
return ($first_keys === $second_keys);
|
||||
}
|
||||
sort($first_keys);
|
||||
sort($second_keys);
|
||||
return ($first_keys == $second_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a resource and another variable.
|
||||
* @param resource $first First resource.
|
||||
* @param mixed $second Resource to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeResourceDifference($first, $second, $identical) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two objects.
|
||||
* @param object $first First object.
|
||||
* @param mixed $second Object to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeObjectDifference($first, $second, $identical) {
|
||||
if (! is_object($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
return $this->_describeArrayDifference(
|
||||
get_object_vars($first),
|
||||
get_object_vars($second),
|
||||
$identical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first character position that differs
|
||||
* in two strings by binary chop.
|
||||
* @param string $first First string.
|
||||
* @param string $second String to compare with.
|
||||
* @return integer Position of first differing
|
||||
* character.
|
||||
* @access private
|
||||
*/
|
||||
function _stringDiffersAt($first, $second) {
|
||||
if (! $first || ! $second) {
|
||||
return 0;
|
||||
}
|
||||
if (strlen($first) < strlen($second)) {
|
||||
list($first, $second) = array($second, $first);
|
||||
}
|
||||
$position = 0;
|
||||
$step = strlen($first);
|
||||
while ($step > 1) {
|
||||
$step = (integer)(($step + 1) / 2);
|
||||
if (strncmp($first, $second, $position + $step) == 0) {
|
||||
$position += $step;
|
||||
}
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted dump of a variable to a string.
|
||||
* @param mixed $variable Variable to display.
|
||||
* @return string Output from print_r().
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function dump($variable) {
|
||||
ob_start();
|
||||
print_r($variable);
|
||||
$formatted = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $formatted;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+299
-62
@@ -1,70 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for eclipse plugin
|
||||
* @package SimpleTest
|
||||
* @version $Id$
|
||||
*/
|
||||
include_once "xml.php";
|
||||
include_once "invoker.php";
|
||||
include_once "socket.php";
|
||||
class EclipseReporter extends XmlReporter {
|
||||
var $_port;
|
||||
function EclipseReporter($port){
|
||||
$this->_port = $port;
|
||||
$this->XmlReporter();
|
||||
}
|
||||
|
||||
function &createInvoker(&$invoker){
|
||||
$eclinvoker = &new EclipseInvoker($invoker, $this->_port);
|
||||
return $eclinvoker;
|
||||
}
|
||||
|
||||
function paintMethodStart($method) {
|
||||
parent::paintGroupStart($this->_group, $this->_size);
|
||||
parent::paintCaseStart($this->_case);
|
||||
parent::paintMethodStart($method);
|
||||
}
|
||||
|
||||
function paintMethodEnd($method){
|
||||
parent::paintMethodEnd($method);
|
||||
parent::paintCaseEnd($this->_case);
|
||||
parent::paintGroupEnd($this->_group);
|
||||
|
||||
}
|
||||
|
||||
function paintCaseStart($case){
|
||||
$this->_case = $case;
|
||||
}
|
||||
|
||||
function paintCaseEnd($case){
|
||||
$this->_case = "";
|
||||
}
|
||||
function paintGroupStart($group,$size){
|
||||
$this->_group = $group;
|
||||
}
|
||||
function paintGroupEnd($group){
|
||||
$this->_group = "";
|
||||
}
|
||||
* base include file for eclipse plugin
|
||||
* @package SimpleTest
|
||||
* @subpackage Eclipse
|
||||
* @version $Id$
|
||||
*/
|
||||
/**#@+
|
||||
* simpletest include files
|
||||
*/
|
||||
include_once 'unit_tester.php';
|
||||
include_once 'test_case.php';
|
||||
include_once 'invoker.php';
|
||||
include_once 'socket.php';
|
||||
include_once 'mock_objects.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* base reported class for eclipse plugin
|
||||
* @package SimpleTest
|
||||
* @subpackage Eclipse
|
||||
*/
|
||||
class EclipseReporter extends SimpleScorer {
|
||||
|
||||
/**
|
||||
* Reporter to be run inside of Eclipse interface.
|
||||
* @param object $listener Eclipse listener (?).
|
||||
* @param boolean $cc Whether to include test coverage.
|
||||
*/
|
||||
function EclipseReporter(&$listener, $cc=false){
|
||||
$this->_listener = &$listener;
|
||||
$this->SimpleScorer();
|
||||
$this->_case = "";
|
||||
$this->_group = "";
|
||||
$this->_method = "";
|
||||
$this->_cc = $cc;
|
||||
$this->_error = false;
|
||||
$this->_fail = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Means to display human readable object comparisons.
|
||||
* @return SimpleDumper Visual comparer.
|
||||
*/
|
||||
function getDumper() {
|
||||
return new SimpleDumper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Localhost connection from Eclipse.
|
||||
* @param integer $port Port to connect to Eclipse.
|
||||
* @param string $host Normally localhost.
|
||||
* @return SimpleSocket Connection to Eclipse.
|
||||
*/
|
||||
function &createListener($port, $host="127.0.0.1"){
|
||||
$tmplistener = &new SimpleSocket($host, $port, 5);
|
||||
return $tmplistener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the test in an output buffer.
|
||||
* @param SimpleInvoker $invoker Current test runner.
|
||||
* @return EclipseInvoker Decorator with output buffering.
|
||||
* @access public
|
||||
*/
|
||||
function &createInvoker(&$invoker){
|
||||
$eclinvoker = &new EclipseInvoker($invoker, $this->_listener);
|
||||
return $eclinvoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* C style escaping.
|
||||
* @param string $raw String with backslashes, quotes and whitespace.
|
||||
* @return string Replaced with C backslashed tokens.
|
||||
*/
|
||||
function escapeVal($raw){
|
||||
$needle = array("\\","\"","/","\b","\f","\n","\r","\t");
|
||||
$replace = array('\\\\','\"','\/','\b','\f','\n','\r','\t');
|
||||
return str_replace($needle, $replace, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash the first passing item. Clicking the test
|
||||
* item goes to first pass.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintPass($message){
|
||||
if (! $this->_pass){
|
||||
$this->_message = $this->escapeVal($message);
|
||||
}
|
||||
$this->_pass = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash the first failing item. Clicking the test
|
||||
* item goes to first fail.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message){
|
||||
//only get the first failure or error
|
||||
if (! $this->_fail && ! $this->_error){
|
||||
$this->_fail = true;
|
||||
$this->_message = $this->escapeVal($message);
|
||||
$this->_listener->write('{status:"fail",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash the first error. Clicking the test
|
||||
* item goes to first error.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message){
|
||||
if (! $this->_fail && ! $this->_error){
|
||||
$this->_error = true;
|
||||
$this->_message = $this->escapeVal($message);
|
||||
$this->_listener->write('{status:"error",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stash the first exception. Clicking the test
|
||||
* item goes to first message.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception){
|
||||
if (! $this->_fail && ! $this->_error){
|
||||
$this->_error = true;
|
||||
$message = 'Unexpected exception of type[' . get_class($exception) .
|
||||
'] with message [' . $exception->getMessage() . '] in [' .
|
||||
$exception->getFile() .' line '. $exception->getLine() . ']';
|
||||
$this->_message = $this->escapeVal($message);
|
||||
$this->_listener->write(
|
||||
'{status:"error",message:"' . $this->_message . '",group:"' .
|
||||
$this->_group . '",case:"' . $this->_case . '",method:"' . $this->_method
|
||||
. '"}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We don't display any special header.
|
||||
* @param string $test_name First test top level
|
||||
* to start.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't display any special footer.
|
||||
* @param string $test_name The top level test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints nothing at the start of a test method, but stash
|
||||
* the method name for later.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($method) {
|
||||
$this->_pass = false;
|
||||
$this->_fail = false;
|
||||
$this->_error = false;
|
||||
$this->_method = $this->escapeVal($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only send one message if the test passes, after that
|
||||
* suppress the message.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($method){
|
||||
if ($this->_fail || $this->_error || ! $this->_pass){
|
||||
} else {
|
||||
$this->_listener->write(
|
||||
'{status:"pass",message:"' . $this->_message . '",group:"' .
|
||||
$this->_group . '",case:"' . $this->_case . '",method:"' .
|
||||
$this->_method . '"}');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the test case name for the later failure message.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($case){
|
||||
$this->_case = $this->escapeVal($case);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the name.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($case){
|
||||
$this->_case = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the name of the test suite. Starts test coverage
|
||||
* if enabled.
|
||||
* @param string $group Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($group, $size){
|
||||
$this->_group = $this->escapeVal($group);
|
||||
if ($this->_cc){
|
||||
if (extension_loaded('xdebug')){
|
||||
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints coverage report if enabled.
|
||||
* @param string $group Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($group){
|
||||
$this->_group = "";
|
||||
$cc = "";
|
||||
if ($this->_cc){
|
||||
if (extension_loaded('xdebug')){
|
||||
$arrfiles = xdebug_get_code_coverage();
|
||||
xdebug_stop_code_coverage();
|
||||
$thisdir = dirname(__FILE__);
|
||||
$thisdirlen = strlen($thisdir);
|
||||
foreach ($arrfiles as $index=>$file){
|
||||
if (substr($index, 0, $thisdirlen)===$thisdir){
|
||||
continue;
|
||||
}
|
||||
$lcnt = 0;
|
||||
$ccnt = 0;
|
||||
foreach ($file as $line){
|
||||
if ($line == -2){
|
||||
continue;
|
||||
}
|
||||
$lcnt++;
|
||||
if ($line==1){
|
||||
$ccnt++;
|
||||
}
|
||||
}
|
||||
if ($lcnt > 0){
|
||||
$cc .= round(($ccnt/$lcnt) * 100, 2) . '%';
|
||||
}else{
|
||||
$cc .= "0.00%";
|
||||
}
|
||||
$cc.= "\t". $index . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->_listener->write('{status:"coverage",message:"' .
|
||||
EclipseReporter::escapeVal($cc) . '"}');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoker decorator for Eclipse. Captures output until
|
||||
* the end of the test.
|
||||
* @package SimpleTest
|
||||
* @subpackage Eclipse
|
||||
*/
|
||||
class EclipseInvoker extends SimpleInvokerDecorator{
|
||||
var $_port;
|
||||
function EclipseInvoker(&$invoker,$port) {
|
||||
$this->_port = $port;
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
function invoke($method) {
|
||||
ob_start();
|
||||
parent::invoke($method);
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
function EclipseInvoker(&$invoker, &$listener) {
|
||||
$this->_listener = &$listener;
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts output buffering.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method){
|
||||
ob_start();
|
||||
$this->_invoker->before($method);
|
||||
}
|
||||
|
||||
$sock = new SimpleSocket("127.0.0.1",$this->_port,5);
|
||||
$sock->write($output);
|
||||
$sock->close();
|
||||
echo $sock->getError();
|
||||
}
|
||||
/**
|
||||
* Stops output buffering and send the captured output
|
||||
* to the listener.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_invoker->after($method);
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if ($output !== ""){
|
||||
$result = $this->_listener->write('{status:"info",message:"' .
|
||||
EclipseReporter::escapeVal($output) . '"}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
+516
-485
File diff suppressed because it is too large
Load Diff
+275
-233
@@ -1,246 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/** @ignore - PHP5 compatibility fix. */
|
||||
if (! defined('E_STRICT')) {
|
||||
define('E_STRICT', 2048);
|
||||
}
|
||||
/**
|
||||
* @ignore - PHP5 compatibility fix.
|
||||
*/
|
||||
if (! defined('E_STRICT')) {
|
||||
define('E_STRICT', 2048);
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* Includes SimpleTest files.
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/invoker.php');
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
require_once(dirname(__FILE__) . '/expectation.php');
|
||||
/**#@+
|
||||
* Includes SimpleTest files.
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/invoker.php';
|
||||
require_once dirname(__FILE__) . '/test_case.php';
|
||||
require_once dirname(__FILE__) . '/expectation.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Extension that traps errors into an error queue.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator {
|
||||
|
||||
/**
|
||||
* Extension that traps errors into an error queue.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Stores the invoker to wrap.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator {
|
||||
|
||||
/**
|
||||
* Stores the invoker to wrap.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleErrorTrappingInvoker(&$invoker) {
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and dispatches any
|
||||
* untrapped errors. Called back from
|
||||
* the visiting runner.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->setTestCase($this->GetTestCase());
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
parent::invoke($method);
|
||||
while (list($severity, $message, $file, $line) = $queue->extract()) {
|
||||
$severity = SimpleErrorQueue::getSeverityAsString($severity);
|
||||
$test = &$this->getTestCase();
|
||||
$test->error($severity, $message, $file, $line);
|
||||
}
|
||||
restore_error_handler();
|
||||
}
|
||||
function SimpleErrorTrappingInvoker(&$invoker) {
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton error queue used to record trapped
|
||||
* errors.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleErrorQueue {
|
||||
var $_queue;
|
||||
var $_expectation_queue;
|
||||
var $_test;
|
||||
|
||||
/**
|
||||
* Starts with an empty queue.
|
||||
*/
|
||||
function SimpleErrorQueue() {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently running test case.
|
||||
* @param SimpleTestCase $test Test case to send messages to.
|
||||
* @access public
|
||||
*/
|
||||
function setTestCase(&$test) {
|
||||
$this->_test = &$test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the front of the queue.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $content Text of error.
|
||||
* @param string $filename File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access public
|
||||
*/
|
||||
function add($severity, $content, $filename, $line) {
|
||||
$content = str_replace('%', '%%', $content);
|
||||
if (count($this->_expectation_queue)) {
|
||||
$this->_testLatestError($severity, $content, $filename, $line);
|
||||
} else {
|
||||
array_push(
|
||||
$this->_queue,
|
||||
array($severity, $content, $filename, $line));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the error against the most recent expected
|
||||
* error.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $content Text of error.
|
||||
* @param string $filename File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access private
|
||||
*/
|
||||
function _testLatestError($severity, $content, $filename, $line) {
|
||||
list($expected, $message) = array_shift($this->_expectation_queue);
|
||||
$severity = $this->getSeverityAsString($severity);
|
||||
$is_match = $this->_test->assert(
|
||||
$expected,
|
||||
$content,
|
||||
sprintf($message, "%s -> PHP error [$content] severity [$severity] in [$filename] line [$line]"));
|
||||
if (! $is_match) {
|
||||
$this->_test->error($severity, $content, $filename, $line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the earliest error from the queue.
|
||||
* @return False if none, or a list of error
|
||||
* information. Elements are: severity
|
||||
* as the PHP error code, the error message,
|
||||
* the file with the error, the line number
|
||||
* and a list of PHP super global arrays.
|
||||
* @access public
|
||||
*/
|
||||
function extract() {
|
||||
if (count($this->_queue)) {
|
||||
return array_shift($this->_queue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the contents of the error queue.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_queue = array();
|
||||
$this->_expectation_queue = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoErrors($message) {
|
||||
return $this->_test->assert(
|
||||
new TrueExpectation(),
|
||||
count($this->_queue) == 0,
|
||||
sprintf($message, 'Should be no errors'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertError($expected, $message) {
|
||||
if (count($this->_queue) == 0) {
|
||||
$this->_test->fail(sprintf($message, 'Expected error not found'));
|
||||
return false;
|
||||
}
|
||||
list($severity, $content, $file, $line) = $this->extract();
|
||||
$severity = $this->getSeverityAsString($severity);
|
||||
return $this->_test->assert(
|
||||
$expected,
|
||||
$content,
|
||||
sprintf($message, "Expected PHP error [$content] severity [$severity] in [$file] line [$line]"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an expectation of an error. If this is
|
||||
* not fulfilled at the end of the test, a failure
|
||||
* will occour. If the error does happen, then this
|
||||
* will cancel it out and send a pass message.
|
||||
* @param SimpleExpectation $expected Expected error match.
|
||||
* @param string $message Message to display.
|
||||
* @access public
|
||||
*/
|
||||
function expectError($expected, $message) {
|
||||
array_push(
|
||||
$this->_expectation_queue,
|
||||
array($expected, $message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an error code into it's string
|
||||
* representation.
|
||||
* @param $severity PHP integer error code.
|
||||
* @return String version of error code.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getSeverityAsString($severity) {
|
||||
static $map = array(
|
||||
E_STRICT => 'E_STRICT',
|
||||
E_ERROR => 'E_ERROR',
|
||||
E_WARNING => 'E_WARNING',
|
||||
E_PARSE => 'E_PARSE',
|
||||
E_NOTICE => 'E_NOTICE',
|
||||
E_CORE_ERROR => 'E_CORE_ERROR',
|
||||
E_CORE_WARNING => 'E_CORE_WARNING',
|
||||
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
||||
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
||||
E_USER_ERROR => 'E_USER_ERROR',
|
||||
E_USER_WARNING => 'E_USER_WARNING',
|
||||
E_USER_NOTICE => 'E_USER_NOTICE');
|
||||
if (!isset($map[$severity])) {
|
||||
debug_print_backtrace();
|
||||
die();
|
||||
}
|
||||
return $map[$severity];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler that simply stashes any errors into the global
|
||||
* error queue. Simulates the existing behaviour with respect to
|
||||
* logging errors, but this feature may be removed in future.
|
||||
* @param $severity PHP error code.
|
||||
* @param $message Text of error.
|
||||
* @param $filename File error occoured in.
|
||||
* @param $line Line number of error.
|
||||
* @param $super_globals Hash of PHP super global arrays.
|
||||
* @static
|
||||
* Invokes a test method and dispatches any
|
||||
* untrapped errors. Called back from
|
||||
* the visiting runner.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleTestErrorHandler($severity, $message, $filename, $line, $super_globals) {
|
||||
if ($severity = $severity & error_reporting()) {
|
||||
restore_error_handler();
|
||||
if (ini_get('log_errors')) {
|
||||
$label = SimpleErrorQueue::getSeverityAsString($severity);
|
||||
error_log("$label: $message in $filename on line $line");
|
||||
}
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->add($severity, $message, $filename, $line);
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
function invoke($method) {
|
||||
$queue = &$this->_createErrorQueue();
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
parent::invoke($method);
|
||||
restore_error_handler();
|
||||
$queue->tally();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wires up the error queue for a single test.
|
||||
* @return SimpleErrorQueue Queue connected to the test.
|
||||
* @access private
|
||||
*/
|
||||
function &_createErrorQueue() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$test = &$this->getTestCase();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->setTestCase($test);
|
||||
return $queue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error queue used to record trapped
|
||||
* errors.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleErrorQueue {
|
||||
var $_queue;
|
||||
var $_expectation_queue;
|
||||
var $_test;
|
||||
var $_using_expect_style = false;
|
||||
|
||||
/**
|
||||
* Starts with an empty queue.
|
||||
*/
|
||||
function SimpleErrorQueue() {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the contents of the error queue.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_queue = array();
|
||||
$this->_expectation_queue = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently running test case.
|
||||
* @param SimpleTestCase $test Test case to send messages to.
|
||||
* @access public
|
||||
*/
|
||||
function setTestCase(&$test) {
|
||||
$this->_test = &$test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an expectation of an error. If this is
|
||||
* not fulfilled at the end of the test, a failure
|
||||
* will occour. If the error does happen, then this
|
||||
* will cancel it out and send a pass message.
|
||||
* @param SimpleExpectation $expected Expected error match.
|
||||
* @param string $message Message to display.
|
||||
* @access public
|
||||
*/
|
||||
function expectError($expected, $message) {
|
||||
$this->_using_expect_style = true;
|
||||
array_push($this->_expectation_queue, array($expected, $message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the front of the queue.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $content Text of error.
|
||||
* @param string $filename File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access public
|
||||
*/
|
||||
function add($severity, $content, $filename, $line) {
|
||||
$content = str_replace('%', '%%', $content);
|
||||
if ($this->_using_expect_style) {
|
||||
$this->_testLatestError($severity, $content, $filename, $line);
|
||||
} else {
|
||||
array_push(
|
||||
$this->_queue,
|
||||
array($severity, $content, $filename, $line));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
/**
|
||||
* Any errors still in the queue are sent to the test
|
||||
* case. Any unfulfilled expectations trigger failures.
|
||||
* @access public
|
||||
*/
|
||||
function tally() {
|
||||
while (list($severity, $message, $file, $line) = $this->extract()) {
|
||||
$severity = $this->getSeverityAsString($severity);
|
||||
$this->_test->error($severity, $message, $file, $line);
|
||||
}
|
||||
while (list($expected, $message) = $this->_extractExpectation()) {
|
||||
$this->_test->assert($expected, false, "%s -> Expected error not caught");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the error against the most recent expected
|
||||
* error.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $content Text of error.
|
||||
* @param string $filename File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access private
|
||||
*/
|
||||
function _testLatestError($severity, $content, $filename, $line) {
|
||||
if ($expectation = $this->_extractExpectation()) {
|
||||
list($expected, $message) = $expectation;
|
||||
$this->_test->assert($expected, $content, sprintf(
|
||||
$message,
|
||||
"%s -> PHP error [$content] severity [" .
|
||||
$this->getSeverityAsString($severity) .
|
||||
"] in [$filename] line [$line]"));
|
||||
} else {
|
||||
$this->_test->error($severity, $content, $filename, $line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the earliest error from the queue.
|
||||
* @return mixed False if none, or a list of error
|
||||
* information. Elements are: severity
|
||||
* as the PHP error code, the error message,
|
||||
* the file with the error, the line number
|
||||
* and a list of PHP super global arrays.
|
||||
* @access public
|
||||
*/
|
||||
function extract() {
|
||||
if (count($this->_queue)) {
|
||||
return array_shift($this->_queue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the earliest expectation from the queue.
|
||||
* @return SimpleExpectation False if none.
|
||||
* @access private
|
||||
*/
|
||||
function _extractExpectation() {
|
||||
if (count($this->_expectation_queue)) {
|
||||
return array_shift($this->_expectation_queue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoErrors($message) {
|
||||
return $this->_test->assert(
|
||||
new TrueExpectation(),
|
||||
count($this->_queue) == 0,
|
||||
sprintf($message, 'Should be no errors'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertError($expected, $message) {
|
||||
if (count($this->_queue) == 0) {
|
||||
$this->_test->fail(sprintf($message, 'Expected error not found'));
|
||||
return false;
|
||||
}
|
||||
list($severity, $content, $file, $line) = $this->extract();
|
||||
$severity = $this->getSeverityAsString($severity);
|
||||
return $this->_test->assert(
|
||||
$expected,
|
||||
$content,
|
||||
sprintf($message, "Expected PHP error [$content] severity [$severity] in [$file] line [$line]"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an error code into it's string
|
||||
* representation.
|
||||
* @param $severity PHP integer error code.
|
||||
* @return String version of error code.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getSeverityAsString($severity) {
|
||||
static $map = array(
|
||||
E_STRICT => 'E_STRICT',
|
||||
E_ERROR => 'E_ERROR',
|
||||
E_WARNING => 'E_WARNING',
|
||||
E_PARSE => 'E_PARSE',
|
||||
E_NOTICE => 'E_NOTICE',
|
||||
E_CORE_ERROR => 'E_CORE_ERROR',
|
||||
E_CORE_WARNING => 'E_CORE_WARNING',
|
||||
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
||||
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
||||
E_USER_ERROR => 'E_USER_ERROR',
|
||||
E_USER_WARNING => 'E_USER_WARNING',
|
||||
E_USER_NOTICE => 'E_USER_NOTICE');
|
||||
if (defined('E_RECOVERABLE_ERROR')) {
|
||||
$map[E_RECOVERABLE_ERROR] = 'E_RECOVERABLE_ERROR';
|
||||
}
|
||||
if (defined('E_DEPRECATED')) {
|
||||
$map[E_DEPRECATED] = 'E_DEPRECATED';
|
||||
}
|
||||
return $map[$severity];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler that simply stashes any errors into the global
|
||||
* error queue. Simulates the existing behaviour with respect to
|
||||
* logging errors, but this feature may be removed in future.
|
||||
* @param $severity PHP error code.
|
||||
* @param $message Text of error.
|
||||
* @param $filename File error occoured in.
|
||||
* @param $line Line number of error.
|
||||
* @param $super_globals Hash of PHP super global arrays.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function SimpleTestErrorHandler($severity, $message, $filename = null, $line = null, $super_globals = null, $mask = null) {
|
||||
$severity = $severity & error_reporting();
|
||||
if ($severity) {
|
||||
restore_error_handler();
|
||||
if (ini_get('log_errors')) {
|
||||
$label = SimpleErrorQueue::getSeverityAsString($severity);
|
||||
error_log("$label: $message in $filename on line $line");
|
||||
}
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->add($severity, $message, $filename, $line);
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
?>
|
||||
+174
-167
@@ -1,191 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* Includes SimpleTest files and defined the root constant
|
||||
* for dependent libraries.
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/invoker.php');
|
||||
require_once(dirname(__FILE__) . '/expectation.php');
|
||||
/**#@+
|
||||
* Include required SimpleTest files
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/invoker.php';
|
||||
require_once dirname(__FILE__) . '/expectation.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Extension that traps exceptions and turns them into
|
||||
* an error message. PHP5 only.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator {
|
||||
|
||||
/**
|
||||
* Extension that traps exceptions and turns them into
|
||||
* an error message. PHP5 only.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Stores the invoker to be wrapped.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator {
|
||||
function SimpleExceptionTrappingInvoker($invoker) {
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the invoker to be wrapped.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleExceptionTrappingInvoker($invoker) {
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method whilst trapping expected
|
||||
* exceptions. Any left over unthrown exceptions
|
||||
* are then reported as failures.
|
||||
* @param string $method Test method to call.
|
||||
*/
|
||||
function invoke($method) {
|
||||
$trap = SimpleTest::getContext()->get('SimpleExceptionTrap');
|
||||
/**
|
||||
* Invokes a test method whilst trapping expected
|
||||
* exceptions. Any left over unthrown exceptions
|
||||
* are then reported as failures.
|
||||
* @param string $method Test method to call.
|
||||
*/
|
||||
function invoke($method) {
|
||||
$trap = SimpleTest::getContext()->get('SimpleExceptionTrap');
|
||||
$trap->clear();
|
||||
try {
|
||||
$has_thrown = false;
|
||||
parent::invoke($method);
|
||||
} catch (Exception $exception) {
|
||||
$has_thrown = true;
|
||||
if (! $trap->isExpected($this->getTestCase(), $exception)) {
|
||||
$this->getTestCase()->exception($exception);
|
||||
}
|
||||
$trap->clear();
|
||||
}
|
||||
if ($message = $trap->getOutstanding()) {
|
||||
$this->getTestCase()->fail($message);
|
||||
}
|
||||
if ($has_thrown) {
|
||||
try {
|
||||
parent::invoke($method);
|
||||
} catch (Exception $exception) {
|
||||
if (! $trap->isExpected($this->getTestCase(), $exception)) {
|
||||
$this->getTestCase()->exception($exception);
|
||||
}
|
||||
$trap->clear();
|
||||
}
|
||||
if ($message = $trap->getOutstanding()) {
|
||||
$this->getTestCase()->fail($message);
|
||||
}
|
||||
parent::getTestCase()->tearDown();
|
||||
} catch (Exception $e) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests exceptions either by type or the exact
|
||||
* exception. This could be improved to accept
|
||||
* a pattern expectation to test the error
|
||||
* message, but that will have to come later.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class ExceptionExpectation extends SimpleExpectation {
|
||||
private $expected;
|
||||
|
||||
/**
|
||||
* Sets up the conditions to test against.
|
||||
* If the expected value is a string, then
|
||||
* it will act as a test of the class name.
|
||||
* An exception as the comparison will
|
||||
* trigger an identical match. Writing this
|
||||
* down now makes it look doubly dumb. I hope
|
||||
* come up with a better scheme later.
|
||||
* @param mixed $expected A class name or an actual
|
||||
* exception to compare with.
|
||||
* @param string $message Message to display.
|
||||
*/
|
||||
function __construct($expected, $message = '%s') {
|
||||
$this->expected = $expected;
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests exceptions either by type or the exact
|
||||
* exception. This could be improved to accept
|
||||
* a pattern expectation to test the error
|
||||
* message, but that will have to come later.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Carry out the test.
|
||||
* @param Exception $compare Value to check.
|
||||
* @return boolean True if matched.
|
||||
*/
|
||||
class ExceptionExpectation extends SimpleExpectation {
|
||||
private $expected;
|
||||
|
||||
/**
|
||||
* Sets up the conditions to test against.
|
||||
* If the expected value is a string, then
|
||||
* it will act as a test of the class name.
|
||||
* An exception as the comparison will
|
||||
* trigger an identical match. Writing this
|
||||
* down now makes it look doubly dumb. I hope
|
||||
* come up with a better scheme later.
|
||||
* @param mixed $expected A class name or an actual
|
||||
* exception to compare with.
|
||||
* @param string $message Message to display.
|
||||
*/
|
||||
function __construct($expected, $message = '%s') {
|
||||
$this->expected = $expected;
|
||||
parent::__construct($message);
|
||||
function test($compare) {
|
||||
if (is_string($this->expected)) {
|
||||
return ($compare instanceof $this->expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Carry out the test.
|
||||
* @param Exception $compare Value to check.
|
||||
* @return boolean True if matched.
|
||||
*/
|
||||
function test($compare) {
|
||||
if (is_string($this->expected)) {
|
||||
return ($compare instanceof $this->expected);
|
||||
}
|
||||
if (get_class($compare) != get_class($this->expected)) {
|
||||
return false;
|
||||
}
|
||||
return $compare->getMessage() == $this->expected->getMessage();
|
||||
if (get_class($compare) != get_class($this->expected)) {
|
||||
return false;
|
||||
}
|
||||
return $compare->getMessage() == $this->expected->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the message to display describing the test.
|
||||
* @param Exception $compare Exception to match.
|
||||
* @return string Final message.
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if (is_string($this->expected)) {
|
||||
return "Exception [" . $this->describeException($compare) .
|
||||
"] should be type [" . $this->expected . "]";
|
||||
}
|
||||
/**
|
||||
* Create the message to display describing the test.
|
||||
* @param Exception $compare Exception to match.
|
||||
* @return string Final message.
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if (is_string($this->expected)) {
|
||||
return "Exception [" . $this->describeException($compare) .
|
||||
"] should match [" .
|
||||
$this->describeException($this->expected) . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of an Exception object.
|
||||
* @param Exception $compare Exception to describe.
|
||||
* @return string Text description.
|
||||
*/
|
||||
protected function describeException($exception) {
|
||||
return get_class($exception) . ": " . $exception->getMessage();
|
||||
"] should be type [" . $this->expected . "]";
|
||||
}
|
||||
return "Exception [" . $this->describeException($compare) .
|
||||
"] should match [" .
|
||||
$this->describeException($this->expected) . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores expected exceptions for when they
|
||||
* get thrown. Saves the irritating try...catch
|
||||
* block.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Summary of an Exception object.
|
||||
* @param Exception $compare Exception to describe.
|
||||
* @return string Text description.
|
||||
*/
|
||||
class SimpleExceptionTrap {
|
||||
private $expected;
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* Clears down the queue ready for action.
|
||||
*/
|
||||
function __construct() {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an expectation of an exception.
|
||||
* This has the effect of intercepting an
|
||||
* exception that matches.
|
||||
* @param SimpleExpectation $expected Expected exception to match.
|
||||
* @param string $message Message to display.
|
||||
* @access public
|
||||
*/
|
||||
function expectException($expected = false, $message = '%s') {
|
||||
if ($expected === false) {
|
||||
$expected = new AnythingExpectation();
|
||||
}
|
||||
if (! SimpleExpectation::isExpectation($expected)) {
|
||||
$expected = new ExceptionExpectation($expected);
|
||||
}
|
||||
$this->expected = $expected;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the expected exception with any
|
||||
* in the queue. Issues a pass or fail and
|
||||
* returns the state of the test.
|
||||
* @param SimpleTestCase $test Test case to send messages to.
|
||||
* @param Exception $exception Exception to compare.
|
||||
* @return boolean False on no match.
|
||||
*/
|
||||
function isExpected($test, $exception) {
|
||||
if ($this->expected) {
|
||||
return $test->assert($this->expected, $exception, $this->message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for any left over exception.
|
||||
* @return string/false The failure message or false if none.
|
||||
*/
|
||||
function getOutstanding() {
|
||||
return sprintf($this->message, 'Failed to trap exception');
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the contents of the error queue.
|
||||
*/
|
||||
function clear() {
|
||||
$this->expected = false;
|
||||
$this->message = false;
|
||||
}
|
||||
protected function describeException($exception) {
|
||||
return get_class($exception) . ": " . $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores expected exceptions for when they
|
||||
* get thrown. Saves the irritating try...catch
|
||||
* block.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleExceptionTrap {
|
||||
private $expected;
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* Clears down the queue ready for action.
|
||||
*/
|
||||
function __construct() {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an expectation of an exception.
|
||||
* This has the effect of intercepting an
|
||||
* exception that matches.
|
||||
* @param SimpleExpectation $expected Expected exception to match.
|
||||
* @param string $message Message to display.
|
||||
* @access public
|
||||
*/
|
||||
function expectException($expected = false, $message = '%s') {
|
||||
if ($expected === false) {
|
||||
$expected = new AnythingExpectation();
|
||||
}
|
||||
if (! SimpleExpectation::isExpectation($expected)) {
|
||||
$expected = new ExceptionExpectation($expected);
|
||||
}
|
||||
$this->expected = $expected;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the expected exception with any
|
||||
* in the queue. Issues a pass or fail and
|
||||
* returns the state of the test.
|
||||
* @param SimpleTestCase $test Test case to send messages to.
|
||||
* @param Exception $exception Exception to compare.
|
||||
* @return boolean False on no match.
|
||||
*/
|
||||
function isExpected($test, $exception) {
|
||||
if ($this->expected) {
|
||||
return $test->assert($this->expected, $exception, $this->message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for any left over exception.
|
||||
* @return string/false The failure message or false if none.
|
||||
*/
|
||||
function getOutstanding() {
|
||||
return sprintf($this->message, 'Failed to trap exception');
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the contents of the error queue.
|
||||
*/
|
||||
function clear() {
|
||||
$this->expected = false;
|
||||
$this->message = false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+851
-767
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@
|
||||
* @param $label Test name to display.
|
||||
* @public
|
||||
*/
|
||||
function TestCase($label) {
|
||||
function TestCase($label = false) {
|
||||
$this->SimpleTestCase($label);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
class TestDoxReporter extends SimpleReporter
|
||||
{
|
||||
var $_test_case_pattern = '/^TestOf(.*)$/';
|
||||
|
||||
function TestDoxReporter($test_case_pattern = '/^TestOf(.*)$/') {
|
||||
parent::SimpleScorer();
|
||||
$this->_test_case_pattern = empty($test_case_pattern) ? '/^(.*)$/' : $test_case_pattern;
|
||||
}
|
||||
|
||||
function paintCaseStart($test_name) {
|
||||
preg_match($this->_test_case_pattern, $test_name, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
echo $matches[1] . "\n";
|
||||
} else {
|
||||
echo $test_name . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function paintCaseEnd() {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function paintMethodStart($test_name) {
|
||||
if (!preg_match('/^test(.*)$/i', $test_name, $matches)) {
|
||||
return;
|
||||
}
|
||||
$test_name = $matches[1];
|
||||
|
||||
$test_name = preg_replace('/([A-Z])([A-Z])/', '$1 $2', $test_name);
|
||||
echo '- ' . strtolower(preg_replace('/([a-zA-Z])([A-Z0-9])/', '$1 $2', $test_name));
|
||||
}
|
||||
|
||||
function paintMethodEnd() {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function paintFail() {
|
||||
echo " [FAILED]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
// $Id$
|
||||
require_once dirname(__FILE__) . '/../../autorun.php';
|
||||
require_once dirname(__FILE__) . '/../testdox.php';
|
||||
|
||||
// uncomment to see test dox in action
|
||||
//SimpleTest::prefer(new TestDoxReporter());
|
||||
|
||||
class TestOfTestDoxReporter extends UnitTestCase
|
||||
{
|
||||
function testIsAnInstanceOfSimpleScorerAndReporter() {
|
||||
$dox = new TestDoxReporter();
|
||||
$this->assertIsA($dox, 'SimpleScorer');
|
||||
$this->assertIsA($dox, 'SimpleReporter');
|
||||
}
|
||||
|
||||
function testOutputsNameOfTestCase() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintCaseStart('TestOfTestDoxReporter');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertWantedPattern('/^TestDoxReporter/', $buffer);
|
||||
}
|
||||
|
||||
function testOutputOfTestCaseNameFilteredByConstructParameter() {
|
||||
$dox = new TestDoxReporter('/^(.*)Test$/');
|
||||
ob_start();
|
||||
$dox->paintCaseStart('SomeGreatWidgetTest');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertWantedPattern('/^SomeGreatWidget/', $buffer);
|
||||
}
|
||||
|
||||
function testIfTest_case_patternIsEmptyAssumeEverythingMatches() {
|
||||
$dox = new TestDoxReporter('');
|
||||
ob_start();
|
||||
$dox->paintCaseStart('TestOfTestDoxReporter');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertWantedPattern('/^TestOfTestDoxReporter/', $buffer);
|
||||
}
|
||||
|
||||
function testEmptyLineInsertedWhenCaseEnds() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintCaseEnd('TestOfTestDoxReporter');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("\n", $buffer);
|
||||
}
|
||||
|
||||
function testPaintsTestMethodInTestDoxFormat() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('testSomeGreatTestCase');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("- some great test case", $buffer);
|
||||
unset($buffer);
|
||||
|
||||
$random = rand(100, 200);
|
||||
ob_start();
|
||||
$dox->paintMethodStart("testRandomNumberIs{$random}");
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("- random number is {$random}", $buffer);
|
||||
}
|
||||
|
||||
function testDoesNotOutputAnythingOnNoneTestMethods() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('nonMatchingMethod');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual('', $buffer);
|
||||
}
|
||||
|
||||
function testPaintMethodAddLineBreak() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodEnd('someMethod');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("\n", $buffer);
|
||||
$this->assertNoErrors();
|
||||
}
|
||||
|
||||
function testProperlySpacesSingleLettersInMethodName() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('testAVerySimpleAgainAVerySimpleMethod');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual('- a very simple again a very simple method', $buffer);
|
||||
}
|
||||
|
||||
function testOnFailureThisPrintsFailureNotice() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintFail();
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual(' [FAILED]', $buffer);
|
||||
}
|
||||
|
||||
function testWhenMatchingMethodNamesTestPrefixIsCaseInsensitive() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('TESTSupportsAllUppercaseTestPrefixEvenThoughIDoNotKnowWhyYouWouldDoThat');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual(
|
||||
'- supports all uppercase test prefix even though i do not know why you would do that',
|
||||
$buffer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+331
-328
@@ -1,352 +1,355 @@
|
||||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
require_once(dirname(__FILE__) . '/selector.php');
|
||||
/**#@-*/
|
||||
/**
|
||||
* Base include file for SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
require_once(dirname(__FILE__) . '/selector.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Form tag class to hold widget values.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleForm {
|
||||
var $_method;
|
||||
var $_action;
|
||||
var $_encoding;
|
||||
var $_default_target;
|
||||
var $_id;
|
||||
var $_buttons;
|
||||
var $_images;
|
||||
var $_widgets;
|
||||
var $_radios;
|
||||
var $_checkboxes;
|
||||
|
||||
/**
|
||||
* Form tag class to hold widget values.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Starts with no held controls/widgets.
|
||||
* @param SimpleTag $tag Form tag to read.
|
||||
* @param SimplePage $page Holding page.
|
||||
*/
|
||||
class SimpleForm {
|
||||
var $_method;
|
||||
var $_action;
|
||||
var $_encoding;
|
||||
var $_default_target;
|
||||
var $_id;
|
||||
var $_buttons;
|
||||
var $_images;
|
||||
var $_widgets;
|
||||
var $_radios;
|
||||
var $_checkboxes;
|
||||
|
||||
/**
|
||||
* Starts with no held controls/widgets.
|
||||
* @param SimpleTag $tag Form tag to read.
|
||||
* @param SimpleUrl $url Location of holding page.
|
||||
*/
|
||||
function SimpleForm($tag, $url) {
|
||||
$this->_method = $tag->getAttribute('method');
|
||||
$this->_action = $this->_createAction($tag->getAttribute('action'), $url);
|
||||
$this->_encoding = $this->_setEncodingClass($tag);
|
||||
$this->_default_target = false;
|
||||
$this->_id = $tag->getAttribute('id');
|
||||
$this->_buttons = array();
|
||||
$this->_images = array();
|
||||
$this->_widgets = array();
|
||||
$this->_radios = array();
|
||||
$this->_checkboxes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the request packet to be sent by the form.
|
||||
* @param SimpleTag $tag Form tag to read.
|
||||
* @return string Packet class.
|
||||
* @access private
|
||||
*/
|
||||
function _setEncodingClass($tag) {
|
||||
if (strtolower($tag->getAttribute('method')) == 'post') {
|
||||
if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
|
||||
return 'SimpleMultipartEncoding';
|
||||
}
|
||||
return 'SimplePostEncoding';
|
||||
function SimpleForm($tag, &$page) {
|
||||
$this->_method = $tag->getAttribute('method');
|
||||
$this->_action = $this->_createAction($tag->getAttribute('action'), $page);
|
||||
$this->_encoding = $this->_setEncodingClass($tag);
|
||||
$this->_default_target = false;
|
||||
$this->_id = $tag->getAttribute('id');
|
||||
$this->_buttons = array();
|
||||
$this->_images = array();
|
||||
$this->_widgets = array();
|
||||
$this->_radios = array();
|
||||
$this->_checkboxes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the request packet to be sent by the form.
|
||||
* @param SimpleTag $tag Form tag to read.
|
||||
* @return string Packet class.
|
||||
* @access private
|
||||
*/
|
||||
function _setEncodingClass($tag) {
|
||||
if (strtolower($tag->getAttribute('method')) == 'post') {
|
||||
if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
|
||||
return 'SimpleMultipartEncoding';
|
||||
}
|
||||
return 'SimpleGetEncoding';
|
||||
return 'SimplePostEncoding';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame target within a frameset.
|
||||
* @param string $frame Name of frame.
|
||||
* @access public
|
||||
*/
|
||||
function setDefaultTarget($frame) {
|
||||
$this->_default_target = $frame;
|
||||
return 'SimpleGetEncoding';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame target within a frameset.
|
||||
* @param string $frame Name of frame.
|
||||
* @access public
|
||||
*/
|
||||
function setDefaultTarget($frame) {
|
||||
$this->_default_target = $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for method of form submission.
|
||||
* @return string Either get or post.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return ($this->_method ? strtolower($this->_method) : 'get');
|
||||
}
|
||||
|
||||
/**
|
||||
* Combined action attribute with current location
|
||||
* to get an absolute form target.
|
||||
* @param string $action Action attribute from form tag.
|
||||
* @param SimpleUrl $base Page location.
|
||||
* @return SimpleUrl Absolute form target.
|
||||
*/
|
||||
function _createAction($action, &$page) {
|
||||
if (($action === '') || ($action === false)) {
|
||||
return $page->expandUrl($page->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for method of form submission.
|
||||
* @return string Either get or post.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return ($this->_method ? strtolower($this->_method) : 'get');
|
||||
return $page->expandUrl(new SimpleUrl($action));;
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute URL of the target.
|
||||
* @return SimpleUrl URL target.
|
||||
* @access public
|
||||
*/
|
||||
function getAction() {
|
||||
$url = $this->_action;
|
||||
if ($this->_default_target && ! $url->getTarget()) {
|
||||
$url->setTarget($this->_default_target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combined action attribute with current location
|
||||
* to get an absolute form target.
|
||||
* @param string $action Action attribute from form tag.
|
||||
* @param SimpleUrl $base Page location.
|
||||
* @return SimpleUrl Absolute form target.
|
||||
*/
|
||||
function _createAction($action, $base) {
|
||||
if (($action === '') || ($action === false)) {
|
||||
return $base;
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the encoding for the current values in the
|
||||
* form.
|
||||
* @return SimpleFormEncoding Request to submit.
|
||||
* @access private
|
||||
*/
|
||||
function _encode() {
|
||||
$class = $this->_encoding;
|
||||
$encoding = new $class();
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
$this->_widgets[$i]->write($encoding);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID field of form for unique identification.
|
||||
* @return string Unique tag ID.
|
||||
* @access public
|
||||
*/
|
||||
function getId() {
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag contents to the form.
|
||||
* @param SimpleWidget $tag Input tag to add.
|
||||
* @access public
|
||||
*/
|
||||
function addWidget(&$tag) {
|
||||
if (strtolower($tag->getAttribute('type')) == 'submit') {
|
||||
$this->_buttons[] = &$tag;
|
||||
} elseif (strtolower($tag->getAttribute('type')) == 'image') {
|
||||
$this->_images[] = &$tag;
|
||||
} elseif ($tag->getName()) {
|
||||
$this->_setWidget($tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the widget into the form, grouping radio
|
||||
* buttons if any.
|
||||
* @param SimpleWidget $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _setWidget(&$tag) {
|
||||
if (strtolower($tag->getAttribute('type')) == 'radio') {
|
||||
$this->_addRadioButton($tag);
|
||||
} elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
|
||||
$this->_addCheckbox($tag);
|
||||
} else {
|
||||
$this->_widgets[] = &$tag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a radio button, building a group if necessary.
|
||||
* @param SimpleRadioButtonTag $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _addRadioButton(&$tag) {
|
||||
if (! isset($this->_radios[$tag->getName()])) {
|
||||
$this->_widgets[] = &new SimpleRadioGroup();
|
||||
$this->_radios[$tag->getName()] = count($this->_widgets) - 1;
|
||||
}
|
||||
$this->_widgets[$this->_radios[$tag->getName()]]->addWidget($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a checkbox, making it a group on a repeated name.
|
||||
* @param SimpleCheckboxTag $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _addCheckbox(&$tag) {
|
||||
if (! isset($this->_checkboxes[$tag->getName()])) {
|
||||
$this->_widgets[] = &$tag;
|
||||
$this->_checkboxes[$tag->getName()] = count($this->_widgets) - 1;
|
||||
} else {
|
||||
$index = $this->_checkboxes[$tag->getName()];
|
||||
if (! SimpleTestCompatibility::isA($this->_widgets[$index], 'SimpleCheckboxGroup')) {
|
||||
$previous = &$this->_widgets[$index];
|
||||
$this->_widgets[$index] = &new SimpleCheckboxGroup();
|
||||
$this->_widgets[$index]->addWidget($previous);
|
||||
}
|
||||
$url = new SimpleUrl($action);
|
||||
return $url->makeAbsolute($base);
|
||||
$this->_widgets[$index]->addWidget($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute URL of the target.
|
||||
* @return SimpleUrl URL target.
|
||||
* @access public
|
||||
*/
|
||||
function getAction() {
|
||||
$url = $this->_action;
|
||||
if ($this->_default_target && ! $url->getTarget()) {
|
||||
$url->setTarget($this->_default_target);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the encoding for the current values in the
|
||||
* form.
|
||||
* @return SimpleFormEncoding Request to submit.
|
||||
* @access private
|
||||
*/
|
||||
function _encode() {
|
||||
$class = $this->_encoding;
|
||||
$encoding = new $class();
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
$this->_widgets[$i]->write($encoding);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID field of form for unique identification.
|
||||
* @return string Unique tag ID.
|
||||
* @access public
|
||||
*/
|
||||
function getId() {
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag contents to the form.
|
||||
* @param SimpleWidget $tag Input tag to add.
|
||||
* @access public
|
||||
*/
|
||||
function addWidget(&$tag) {
|
||||
if (strtolower($tag->getAttribute('type')) == 'submit') {
|
||||
$this->_buttons[] = &$tag;
|
||||
} elseif (strtolower($tag->getAttribute('type')) == 'image') {
|
||||
$this->_images[] = &$tag;
|
||||
} elseif ($tag->getName()) {
|
||||
$this->_setWidget($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts current value from form.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return string/array Value(s) as string or null
|
||||
* if not set.
|
||||
* @access public
|
||||
*/
|
||||
function getValue($selector) {
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
return $this->_widgets[$i]->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the widget into the form, grouping radio
|
||||
* buttons if any.
|
||||
* @param SimpleWidget $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _setWidget(&$tag) {
|
||||
if (strtolower($tag->getAttribute('type')) == 'radio') {
|
||||
$this->_addRadioButton($tag);
|
||||
} elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
|
||||
$this->_addCheckbox($tag);
|
||||
} else {
|
||||
$this->_widgets[] = &$tag;
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
return $button->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a radio button, building a group if necessary.
|
||||
* @param SimpleRadioButtonTag $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _addRadioButton(&$tag) {
|
||||
if (! isset($this->_radios[$tag->getName()])) {
|
||||
$this->_widgets[] = &new SimpleRadioGroup();
|
||||
$this->_radios[$tag->getName()] = count($this->_widgets) - 1;
|
||||
}
|
||||
$this->_widgets[$this->_radios[$tag->getName()]]->addWidget($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a checkbox, making it a group on a repeated name.
|
||||
* @param SimpleCheckboxTag $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _addCheckbox(&$tag) {
|
||||
if (! isset($this->_checkboxes[$tag->getName()])) {
|
||||
$this->_widgets[] = &$tag;
|
||||
$this->_checkboxes[$tag->getName()] = count($this->_widgets) - 1;
|
||||
} else {
|
||||
$index = $this->_checkboxes[$tag->getName()];
|
||||
if (! SimpleTestCompatibility::isA($this->_widgets[$index], 'SimpleCheckboxGroup')) {
|
||||
$previous = &$this->_widgets[$index];
|
||||
$this->_widgets[$index] = &new SimpleCheckboxGroup();
|
||||
$this->_widgets[$index]->addWidget($previous);
|
||||
}
|
||||
$this->_widgets[$index]->addWidget($tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts current value from form.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return string/array Value(s) as string or null
|
||||
* if not set.
|
||||
* @access public
|
||||
*/
|
||||
function getValue($selector) {
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
return $this->_widgets[$i]->getValue();
|
||||
}
|
||||
}
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
return $button->getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a widget value within the form.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param string $value Value to input into the widget.
|
||||
* @return boolean True if value is legal, false
|
||||
* otherwise. If the field is not
|
||||
* present, nothing will be set.
|
||||
* @access public
|
||||
*/
|
||||
function setField($selector, $value) {
|
||||
$success = false;
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a widget value within the form.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param string $value Value to input into the widget.
|
||||
* @return boolean True if value is legal, false
|
||||
* otherwise. If the field is not
|
||||
* present, nothing will be set.
|
||||
* @access public
|
||||
*/
|
||||
function setField($selector, $value, $position=false) {
|
||||
$success = false;
|
||||
$_position = 0;
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
$_position++;
|
||||
if ($position === false or $_position === (int)$position) {
|
||||
if ($this->_widgets[$i]->setValue($value)) {
|
||||
$success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the page object to set widgets labels to
|
||||
* external label tags.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @access public
|
||||
*/
|
||||
function attachLabelBySelector($selector, $label) {
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
if (method_exists($this->_widgets[$i], 'setLabel')) {
|
||||
$this->_widgets[$i]->setLabel($label);
|
||||
return;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the page object to set widgets labels to
|
||||
* external label tags.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @access public
|
||||
*/
|
||||
function attachLabelBySelector($selector, $label) {
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
if (method_exists($this->_widgets[$i], 'setLabel')) {
|
||||
$this->_widgets[$i]->setLabel($label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a form has a submit button.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return boolean True if present.
|
||||
* @access public
|
||||
*/
|
||||
function hasSubmit($selector) {
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a form has an image control.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return boolean True if present.
|
||||
* @access public
|
||||
*/
|
||||
function hasImage($selector) {
|
||||
foreach ($this->_images as $image) {
|
||||
if ($selector->isMatch($image)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the submit values for a selected button.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param hash $additional Additional data for the form.
|
||||
* @return SimpleEncoding Submitted values or false
|
||||
* if there is no such button
|
||||
* in the form.
|
||||
* @access public
|
||||
*/
|
||||
function submitButton($selector, $additional = false) {
|
||||
$additional = $additional ? $additional : array();
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
$encoding = $this->_encode();
|
||||
$button->write($encoding);
|
||||
if ($additional) {
|
||||
$encoding->merge($additional);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the submit values for an image.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param integer $x X-coordinate of click.
|
||||
* @param integer $y Y-coordinate of click.
|
||||
* @param hash $additional Additional data for the form.
|
||||
* @return SimpleEncoding Submitted values or false
|
||||
* if there is no such button in the
|
||||
* form.
|
||||
* @access public
|
||||
*/
|
||||
function submitImage($selector, $x, $y, $additional = false) {
|
||||
$additional = $additional ? $additional : array();
|
||||
foreach ($this->_images as $image) {
|
||||
if ($selector->isMatch($image)) {
|
||||
$encoding = $this->_encode();
|
||||
$image->write($encoding, $x, $y);
|
||||
if ($additional) {
|
||||
$encoding->merge($additional);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply submits the form without the submit button
|
||||
* value. Used when there is only one button or it
|
||||
* is unimportant.
|
||||
* @return hash Submitted values.
|
||||
* @access public
|
||||
*/
|
||||
function submit() {
|
||||
return $this->_encode();
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
/**
|
||||
* Test to see if a form has a submit button.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return boolean True if present.
|
||||
* @access public
|
||||
*/
|
||||
function hasSubmit($selector) {
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a form has an image control.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return boolean True if present.
|
||||
* @access public
|
||||
*/
|
||||
function hasImage($selector) {
|
||||
foreach ($this->_images as $image) {
|
||||
if ($selector->isMatch($image)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the submit values for a selected button.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param hash $additional Additional data for the form.
|
||||
* @return SimpleEncoding Submitted values or false
|
||||
* if there is no such button
|
||||
* in the form.
|
||||
* @access public
|
||||
*/
|
||||
function submitButton($selector, $additional = false) {
|
||||
$additional = $additional ? $additional : array();
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
$encoding = $this->_encode();
|
||||
$button->write($encoding);
|
||||
if ($additional) {
|
||||
$encoding->merge($additional);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the submit values for an image.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param integer $x X-coordinate of click.
|
||||
* @param integer $y Y-coordinate of click.
|
||||
* @param hash $additional Additional data for the form.
|
||||
* @return SimpleEncoding Submitted values or false
|
||||
* if there is no such button in the
|
||||
* form.
|
||||
* @access public
|
||||
*/
|
||||
function submitImage($selector, $x, $y, $additional = false) {
|
||||
$additional = $additional ? $additional : array();
|
||||
foreach ($this->_images as $image) {
|
||||
if ($selector->isMatch($image)) {
|
||||
$encoding = $this->_encode();
|
||||
$image->write($encoding, $x, $y);
|
||||
if ($additional) {
|
||||
$encoding->merge($additional);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply submits the form without the submit button
|
||||
* value. Used when there is only one button or it
|
||||
* is unimportant.
|
||||
* @return hash Submitted values.
|
||||
* @access public
|
||||
*/
|
||||
function submit() {
|
||||
return $this->_encode();
|
||||
}
|
||||
}
|
||||
?>
|
||||
+587
-579
File diff suppressed because it is too large
Load Diff
+583
-583
File diff suppressed because it is too large
Load Diff
+129
-129
@@ -1,139 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* Includes SimpleTest files and defined the root constant
|
||||
* for dependent libraries.
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/errors.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
require_once(dirname(__FILE__) . '/expectation.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
if (! defined('SIMPLE_TEST')) {
|
||||
define('SIMPLE_TEST', dirname(__FILE__) . '/');
|
||||
}
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* Includes SimpleTest files and defined the root constant
|
||||
* for dependent libraries.
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/errors.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
require_once(dirname(__FILE__) . '/expectation.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
if (! defined('SIMPLE_TEST')) {
|
||||
define('SIMPLE_TEST', dirname(__FILE__) . '/');
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* This is called by the class runner to run a
|
||||
* single test method. Will also run the setUp()
|
||||
* and tearDown() methods.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleInvoker {
|
||||
var $_test_case;
|
||||
|
||||
/**
|
||||
* This is called by the class runner to run a
|
||||
* single test method. Will also run the setUp()
|
||||
* and tearDown() methods.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Stashes the test case for later.
|
||||
* @param SimpleTestCase $test_case Test case to run.
|
||||
*/
|
||||
class SimpleInvoker {
|
||||
var $_test_case;
|
||||
|
||||
/**
|
||||
* Stashes the test case for later.
|
||||
* @param SimpleTestCase $test_case Test case to run.
|
||||
*/
|
||||
function SimpleInvoker(&$test_case) {
|
||||
$this->_test_case = &$test_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for test case being run.
|
||||
* @return SimpleTestCase Test case.
|
||||
* @access public
|
||||
*/
|
||||
function &getTestCase() {
|
||||
return $this->_test_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level set up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_test_case->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and buffered with setUp()
|
||||
* and tearDown() calls.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$this->_test_case->setUp();
|
||||
$this->_test_case->$method();
|
||||
$this->_test_case->tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level clean up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_test_case->after($method);
|
||||
}
|
||||
function SimpleInvoker(&$test_case) {
|
||||
$this->_test_case = &$test_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing decorator. Just passes the invocation
|
||||
* straight through.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Accessor for test case being run.
|
||||
* @return SimpleTestCase Test case.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleInvokerDecorator {
|
||||
var $_invoker;
|
||||
|
||||
/**
|
||||
* Stores the invoker to wrap.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleInvokerDecorator(&$invoker) {
|
||||
$this->_invoker = &$invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for test case being run.
|
||||
* @return SimpleTestCase Test case.
|
||||
* @access public
|
||||
*/
|
||||
function &getTestCase() {
|
||||
return $this->_invoker->getTestCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level set up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_invoker->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and buffered with setUp()
|
||||
* and tearDown() calls.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$this->_invoker->invoke($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level clean up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_invoker->after($method);
|
||||
}
|
||||
function &getTestCase() {
|
||||
return $this->_test_case;
|
||||
}
|
||||
?>
|
||||
|
||||
/**
|
||||
* Runs test level set up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_test_case->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and buffered with setUp()
|
||||
* and tearDown() calls.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$this->_test_case->setUp();
|
||||
$this->_test_case->$method();
|
||||
$this->_test_case->tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level clean up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_test_case->after($method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing decorator. Just passes the invocation
|
||||
* straight through.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleInvokerDecorator {
|
||||
var $_invoker;
|
||||
|
||||
/**
|
||||
* Stores the invoker to wrap.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleInvokerDecorator(&$invoker) {
|
||||
$this->_invoker = &$invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for test case being run.
|
||||
* @return SimpleTestCase Test case.
|
||||
* @access public
|
||||
*/
|
||||
function &getTestCase() {
|
||||
return $this->_invoker->getTestCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level set up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_invoker->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and buffered with setUp()
|
||||
* and tearDown() calls.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$this->_invoker->invoke($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level clean up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_invoker->after($method);
|
||||
}
|
||||
}
|
||||
?>
|
||||
+1534
-1170
File diff suppressed because it is too large
Load Diff
+949
-941
File diff suppressed because it is too large
Load Diff
+704
-715
File diff suppressed because it is too large
Load Diff
@@ -1,115 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version specific reflection API.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @ignore duplicate with reflection_php5.php
|
||||
*/
|
||||
class SimpleReflection {
|
||||
var $_interface;
|
||||
|
||||
/**
|
||||
* Version specific reflection API.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Stashes the class/interface.
|
||||
* @param string $interface Class or interface
|
||||
* to inspect.
|
||||
*/
|
||||
class SimpleReflection {
|
||||
var $_interface;
|
||||
|
||||
/**
|
||||
* Stashes the class/interface.
|
||||
* @param string $interface Class or interface
|
||||
* to inspect.
|
||||
*/
|
||||
function SimpleReflection($interface) {
|
||||
$this->_interface = $interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class has been declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExists() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExistsSansAutoload() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class or interface has been
|
||||
* declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExists() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExistsSansAutoload() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods on a class or
|
||||
* interface.
|
||||
* @returns array List of method names.
|
||||
* @access public
|
||||
*/
|
||||
function getMethods() {
|
||||
return get_class_methods($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of interfaces from a class. If the
|
||||
* class name is actually an interface then just that
|
||||
* interface is returned.
|
||||
* @returns array List of interfaces.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaces() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the parent class name.
|
||||
* @returns string Parent class name.
|
||||
* @access public
|
||||
*/
|
||||
function getParent() {
|
||||
return strtolower(get_parent_class($this->_interface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the class is abstract, which for PHP 4
|
||||
* will never be the case.
|
||||
* @returns boolean True if abstract.
|
||||
* @access public
|
||||
*/
|
||||
function isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code matching the declaration
|
||||
* of a method.
|
||||
* @param string $method Method name.
|
||||
* @access public
|
||||
*/
|
||||
function getSignature($method) {
|
||||
return "function &$method()";
|
||||
}
|
||||
function SimpleReflection($interface) {
|
||||
$this->_interface = $interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class has been declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExists() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExistsSansAutoload() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class or interface has been
|
||||
* declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExists() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExistsSansAutoload() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods on a class or
|
||||
* interface.
|
||||
* @returns array List of method names.
|
||||
* @access public
|
||||
*/
|
||||
function getMethods() {
|
||||
return get_class_methods($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of interfaces from a class. If the
|
||||
* class name is actually an interface then just that
|
||||
* interface is returned.
|
||||
* @returns array List of interfaces.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaces() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the parent class name.
|
||||
* @returns string Parent class name.
|
||||
* @access public
|
||||
*/
|
||||
function getParent() {
|
||||
return strtolower(get_parent_class($this->_interface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the class is abstract, which for PHP 4
|
||||
* will never be the case.
|
||||
* @returns boolean True if abstract.
|
||||
* @access public
|
||||
*/
|
||||
function isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the the entity is an interface, which for PHP 4
|
||||
* will never be the case.
|
||||
* @returns boolean True if interface.
|
||||
* @access public
|
||||
*/
|
||||
function isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans for final methods, but as it's PHP 4 there
|
||||
* aren't any.
|
||||
* @returns boolean True if the class has a final method.
|
||||
* @access public
|
||||
*/
|
||||
function hasFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code matching the declaration
|
||||
* of a method.
|
||||
* @param string $method Method name.
|
||||
* @access public
|
||||
*/
|
||||
function getSignature($method) {
|
||||
return "function &$method()";
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,280 +1,380 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version specific reflection API.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleReflection {
|
||||
var $_interface;
|
||||
|
||||
/**
|
||||
* Version specific reflection API.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Stashes the class/interface.
|
||||
* @param string $interface Class or interface
|
||||
* to inspect.
|
||||
*/
|
||||
class SimpleReflection {
|
||||
var $_interface;
|
||||
function SimpleReflection($interface) {
|
||||
$this->_interface = $interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the class/interface.
|
||||
* @param string $interface Class or interface
|
||||
* to inspect.
|
||||
*/
|
||||
function SimpleReflection($interface) {
|
||||
$this->_interface = $interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class has been declared. Versions
|
||||
* before PHP5.0.2 need a check that it's not really
|
||||
* an interface.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExists() {
|
||||
if (! class_exists($this->_interface)) {
|
||||
return false;
|
||||
}
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return ! $reflection->isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExistsSansAutoload() {
|
||||
return class_exists($this->_interface, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class or interface has been
|
||||
* declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExists() {
|
||||
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExistsSansAutoload() {
|
||||
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to select the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @param string $interface Class or interface name.
|
||||
* @param boolean $autoload True totriggerautoload.
|
||||
* @return boolean True if interface defined.
|
||||
* @access private
|
||||
*/
|
||||
function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
|
||||
if (function_exists('interface_exists')) {
|
||||
if (interface_exists($this->_interface, $autoload)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return class_exists($this->_interface, $autoload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods on a class or
|
||||
* interface. Needs to recursively look at all of
|
||||
* the interfaces included.
|
||||
* @returns array List of method names.
|
||||
* @access public
|
||||
*/
|
||||
function getMethods() {
|
||||
return array_unique(get_class_methods($this->_interface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of interfaces from a class. If the
|
||||
* class name is actually an interface then just that
|
||||
* interface is returned.
|
||||
* @returns array List of interfaces.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaces() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
if ($reflection->isInterface()) {
|
||||
return array($this->_interface);
|
||||
}
|
||||
return $this->_onlyParents($reflection->getInterfaces());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods for the implemented
|
||||
* interfaces only.
|
||||
* @returns array List of enforced method signatures.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaceMethods() {
|
||||
$methods = array();
|
||||
foreach ($this->getInterfaces() as $interface) {
|
||||
$methods = array_merge($methods, get_class_methods($interface));
|
||||
}
|
||||
return array_unique($methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the method signature has to be tightly
|
||||
* specified.
|
||||
* @param string $method Method name.
|
||||
* @returns boolean True if enforced.
|
||||
* @access private
|
||||
*/
|
||||
function _isInterfaceMethod($method) {
|
||||
return in_array($method, $this->getInterfaceMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the parent class name.
|
||||
* @returns string Parent class name.
|
||||
* @access public
|
||||
*/
|
||||
function getParent() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
$parent = $reflection->getParentClass();
|
||||
if ($parent) {
|
||||
return $parent->getName();
|
||||
}
|
||||
/**
|
||||
* Checks that a class has been declared. Versions
|
||||
* before PHP5.0.2 need a check that it's not really
|
||||
* an interface.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExists() {
|
||||
if (! class_exists($this->_interface)) {
|
||||
return false;
|
||||
}
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return ! $reflection->isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the class is abstract.
|
||||
* @returns boolean True if abstract.
|
||||
* @access public
|
||||
*/
|
||||
function isAbstract() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return $reflection->isAbstract();
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExistsSansAutoload() {
|
||||
return class_exists($this->_interface, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class or interface has been
|
||||
* declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExists() {
|
||||
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExistsSansAutoload() {
|
||||
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to select the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @param string $interface Class or interface name.
|
||||
* @param boolean $autoload True totriggerautoload.
|
||||
* @return boolean True if interface defined.
|
||||
* @access private
|
||||
*/
|
||||
function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
|
||||
if (function_exists('interface_exists')) {
|
||||
if (interface_exists($this->_interface, $autoload)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return class_exists($this->_interface, $autoload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wittles a list of interfaces down to only the top
|
||||
* level parents.
|
||||
* @param array $interfaces Reflection API interfaces
|
||||
* to reduce.
|
||||
* @returns array List of parent interface names.
|
||||
* @access private
|
||||
*/
|
||||
function _onlyParents($interfaces) {
|
||||
$parents = array();
|
||||
foreach ($interfaces as $interface) {
|
||||
foreach($interfaces as $possible_parent) {
|
||||
if ($interface->getName() == $possible_parent->getName()) {
|
||||
continue;
|
||||
}
|
||||
if ($interface->isSubClassOf($possible_parent)) {
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* Gets the list of methods on a class or
|
||||
* interface.
|
||||
* @returns array List of method names.
|
||||
* @access public
|
||||
*/
|
||||
function getMethods() {
|
||||
return array_unique(get_class_methods($this->_interface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of interfaces from a class. If the
|
||||
* class name is actually an interface then just that
|
||||
* interface is returned.
|
||||
* @returns array List of interfaces.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaces() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
if ($reflection->isInterface()) {
|
||||
return array($this->_interface);
|
||||
}
|
||||
return $this->_onlyParents($reflection->getInterfaces());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods for the implemented
|
||||
* interfaces only.
|
||||
* @returns array List of enforced method signatures.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaceMethods() {
|
||||
$methods = array();
|
||||
foreach ($this->getInterfaces() as $interface) {
|
||||
$methods = array_merge($methods, get_class_methods($interface));
|
||||
}
|
||||
return array_unique($methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the method signature has to be tightly
|
||||
* specified.
|
||||
* @param string $method Method name.
|
||||
* @returns boolean True if enforced.
|
||||
* @access private
|
||||
*/
|
||||
function _isInterfaceMethod($method) {
|
||||
return in_array($method, $this->getInterfaceMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the parent class name.
|
||||
* @returns string Parent class name.
|
||||
* @access public
|
||||
*/
|
||||
function getParent() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
$parent = $reflection->getParentClass();
|
||||
if ($parent) {
|
||||
return $parent->getName();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trivially determines if the class is abstract.
|
||||
* @returns boolean True if abstract.
|
||||
* @access public
|
||||
*/
|
||||
function isAbstract() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return $reflection->isAbstract();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trivially determines if the class is an interface.
|
||||
* @returns boolean True if interface.
|
||||
* @access public
|
||||
*/
|
||||
function isInterface() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return $reflection->isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans for final methods, as they screw up inherited
|
||||
* mocks by not allowing you to override them.
|
||||
* @returns boolean True if the class has a final method.
|
||||
* @access public
|
||||
*/
|
||||
function hasFinal() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
foreach ($reflection->getMethods() as $method) {
|
||||
if ($method->isFinal()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whittles a list of interfaces down to only the
|
||||
* necessary top level parents.
|
||||
* @param array $interfaces Reflection API interfaces
|
||||
* to reduce.
|
||||
* @returns array List of parent interface names.
|
||||
* @access private
|
||||
*/
|
||||
function _onlyParents($interfaces) {
|
||||
$parents = array();
|
||||
$blacklist = array();
|
||||
foreach ($interfaces as $interface) {
|
||||
foreach($interfaces as $possible_parent) {
|
||||
if ($interface->getName() == $possible_parent->getName()) {
|
||||
continue;
|
||||
}
|
||||
if ($interface->isSubClassOf($possible_parent)) {
|
||||
$blacklist[$possible_parent->getName()] = true;
|
||||
}
|
||||
}
|
||||
if (!isset($blacklist[$interface->getName()])) {
|
||||
$parents[] = $interface->getName();
|
||||
}
|
||||
return $parents;
|
||||
}
|
||||
return $parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code matching the declaration
|
||||
* of a method.
|
||||
* @param string $name Method name.
|
||||
* @return string Method signature up to last
|
||||
* bracket.
|
||||
* @access public
|
||||
*/
|
||||
function getSignature($name) {
|
||||
if ($name == '__set') {
|
||||
return 'function __set($key, $value)';
|
||||
}
|
||||
if ($name == '__call') {
|
||||
return 'function __call($method, $arguments)';
|
||||
}
|
||||
if (version_compare(phpversion(), '5.1.0', '>=')) {
|
||||
if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
|
||||
return "function {$name}(\$key)";
|
||||
}
|
||||
}
|
||||
if (! is_callable(array($this->_interface, $name))) {
|
||||
return "function $name()";
|
||||
}
|
||||
if ($this->_isInterfaceMethod($name)) {
|
||||
return $this->_getFullSignature($name);
|
||||
}
|
||||
return "function $name()";
|
||||
}
|
||||
|
||||
/**
|
||||
* For a signature specified in an interface, full
|
||||
* details must be replicated to be a valid implementation.
|
||||
* @param string $name Method name.
|
||||
* @return string Method signature up to last
|
||||
* bracket.
|
||||
* @access private
|
||||
*/
|
||||
function _getFullSignature($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
$method = $interface->getMethod($name);
|
||||
$reference = $method->returnsReference() ? '&' : '';
|
||||
return "function $reference$name(" .
|
||||
implode(', ', $this->_getParameterSignatures($method)) .
|
||||
")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code for each parameter.
|
||||
* @param ReflectionMethod $method Method object from
|
||||
* reflection API
|
||||
* @return array List of strings, each
|
||||
* a snippet of code.
|
||||
* @access private
|
||||
*/
|
||||
function _getParameterSignatures($method) {
|
||||
$signatures = array();
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$type = $parameter->getClass();
|
||||
$signatures[] =
|
||||
(! is_null($type) ? $type->getName() . ' ' : '') .
|
||||
($parameter->isPassedByReference() ? '&' : '') .
|
||||
'$' . $this->_suppressSpurious($parameter->getName()) .
|
||||
($this->_isOptional($parameter) ? ' = null' : '');
|
||||
}
|
||||
return $signatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SPL library has problems with the
|
||||
* Reflection library. In particular, you can
|
||||
* get extra characters in parameter names :(.
|
||||
* @param string $name Parameter name.
|
||||
* @return string Cleaner name.
|
||||
* @access private
|
||||
*/
|
||||
function _suppressSpurious($name) {
|
||||
return str_replace(array('[', ']', ' '), '', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a reflection parameter being optional
|
||||
* that works with early versions of PHP5.
|
||||
* @param reflectionParameter $parameter Is this optional.
|
||||
* @return boolean True if optional.
|
||||
* @access private
|
||||
*/
|
||||
function _isOptional($parameter) {
|
||||
if (method_exists($parameter, 'isOptional')) {
|
||||
return $parameter->isOptional();
|
||||
}
|
||||
/**
|
||||
* Checks whether a method is abstract or not.
|
||||
* @param string $name Method name.
|
||||
* @return bool true if method is abstract, else false
|
||||
* @access private
|
||||
*/
|
||||
function _isAbstractMethod($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
if (! $interface->hasMethod($name)) {
|
||||
return false;
|
||||
}
|
||||
return $interface->getMethod($name)->isAbstract();
|
||||
}
|
||||
?>
|
||||
|
||||
/**
|
||||
* Checks whether a method is the constructor.
|
||||
* @param string $name Method name.
|
||||
* @return bool true if method is the constructor
|
||||
* @access private
|
||||
*/
|
||||
function _isConstructor($name) {
|
||||
return ($name == '__construct') || ($name == $this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a method is abstract in all parents or not.
|
||||
* @param string $name Method name.
|
||||
* @return bool true if method is abstract in parent, else false
|
||||
* @access private
|
||||
*/
|
||||
function _isAbstractMethodInParents($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
$parent = $interface->getParentClass();
|
||||
while($parent) {
|
||||
if (! $parent->hasMethod($name)) {
|
||||
return false;
|
||||
}
|
||||
if ($parent->getMethod($name)->isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
$parent = $parent->getParentClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a method is static or not.
|
||||
* @param string $name Method name
|
||||
* @return bool true if method is static, else false
|
||||
* @access private
|
||||
*/
|
||||
function _isStaticMethod($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
if (! $interface->hasMethod($name)) {
|
||||
return false;
|
||||
}
|
||||
return $interface->getMethod($name)->isStatic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the source code matching the declaration
|
||||
* of a method.
|
||||
* @param string $name Method name.
|
||||
* @return string Method signature up to last
|
||||
* bracket.
|
||||
* @access public
|
||||
*/
|
||||
function getSignature($name) {
|
||||
if ($name == '__set') {
|
||||
return 'function __set($key, $value)';
|
||||
}
|
||||
if ($name == '__call') {
|
||||
return 'function __call($method, $arguments)';
|
||||
}
|
||||
if (version_compare(phpversion(), '5.1.0', '>=')) {
|
||||
if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
|
||||
return "function {$name}(\$key)";
|
||||
}
|
||||
}
|
||||
if ($name == '__toString') {
|
||||
return "function $name()";
|
||||
}
|
||||
if ($this->_isInterfaceMethod($name) ||
|
||||
$this->_isAbstractMethod($name) ||
|
||||
$this->_isAbstractMethodInParents($name) ||
|
||||
$this->_isStaticMethod($name)) {
|
||||
return $this->_getFullSignature($name);
|
||||
}
|
||||
return "function $name()";
|
||||
}
|
||||
|
||||
/**
|
||||
* For a signature specified in an interface, full
|
||||
* details must be replicated to be a valid implementation.
|
||||
* @param string $name Method name.
|
||||
* @return string Method signature up to last
|
||||
* bracket.
|
||||
* @access private
|
||||
*/
|
||||
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)) .
|
||||
")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code for each parameter.
|
||||
* @param ReflectionMethod $method Method object from
|
||||
* reflection API
|
||||
* @return array List of strings, each
|
||||
* a snippet of code.
|
||||
* @access private
|
||||
*/
|
||||
function _getParameterSignatures($method) {
|
||||
$signatures = array();
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$signature = '';
|
||||
$type = $parameter->getClass();
|
||||
if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
|
||||
$signature .= 'array ';
|
||||
} elseif (!is_null($type)) {
|
||||
$signature .= $type->getName() . ' ';
|
||||
}
|
||||
if ($parameter->isPassedByReference()) {
|
||||
$signature .= '&';
|
||||
}
|
||||
$signature .= '$' . $this->_suppressSpurious($parameter->getName());
|
||||
if ($this->_isOptional($parameter)) {
|
||||
$signature .= ' = null';
|
||||
}
|
||||
$signatures[] = $signature;
|
||||
}
|
||||
return $signatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SPL library has problems with the
|
||||
* Reflection library. In particular, you can
|
||||
* get extra characters in parameter names :(.
|
||||
* @param string $name Parameter name.
|
||||
* @return string Cleaner name.
|
||||
* @access private
|
||||
*/
|
||||
function _suppressSpurious($name) {
|
||||
return str_replace(array('[', ']', ' '), '', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a reflection parameter being optional
|
||||
* that works with early versions of PHP5.
|
||||
* @param reflectionParameter $parameter Is this optional.
|
||||
* @return boolean True if optional.
|
||||
* @access private
|
||||
*/
|
||||
function _isOptional($parameter) {
|
||||
if (method_exists($parameter, 'isOptional')) {
|
||||
return $parameter->isOptional();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,117 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/browser.php');
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Runs an XML formated test on a remote server.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class RemoteTestCase {
|
||||
var $_url;
|
||||
var $_dry_url;
|
||||
var $_size;
|
||||
|
||||
/**
|
||||
* Sets the location of the remote test.
|
||||
* @param string $url Test location.
|
||||
* @param string $dry_url Location for dry run.
|
||||
* @access public
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/browser.php');
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
/**#@-*/
|
||||
function RemoteTestCase($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an XML formated test on a remote server.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Runs the top level test for this class. Currently
|
||||
* reads the data as a single chunk. I'll fix this
|
||||
* once I have added iteration to the browser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @returns boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
class RemoteTestCase {
|
||||
var $_url;
|
||||
var $_dry_url;
|
||||
var $_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 run(&$reporter) {
|
||||
$browser = &$this->_createBrowser();
|
||||
$xml = $browser->get($this->_url);
|
||||
if (! $xml) {
|
||||
trigger_error('Cannot read remote test URL [' . $this->_url . ']');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_url;
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($xml)) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_url . ']');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the top level test for this class. Currently
|
||||
* reads the data as a single chunk. I'll fix this
|
||||
* once I have added iteration to the browser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @returns boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->_url);
|
||||
$xml = $browser->get($this->_dry_url);
|
||||
if (! $xml) {
|
||||
trigger_error('Cannot read remote test URL [' . $this->_url . ']');
|
||||
trigger_error('Cannot read remote test URL [' . $this->_dry_url . ']');
|
||||
return false;
|
||||
}
|
||||
$reporter = &new SimpleReporter();
|
||||
$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->_dry_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (! $xml) {
|
||||
trigger_error('Cannot read remote test URL [' . $this->_dry_url . ']');
|
||||
return false;
|
||||
}
|
||||
$reporter = &new SimpleReporter();
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($xml)) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_dry_url . ']');
|
||||
return false;
|
||||
}
|
||||
$this->_size = $reporter->getTestCaseCount();
|
||||
}
|
||||
return $this->_size;
|
||||
$this->_size = $reporter->getTestCaseCount();
|
||||
}
|
||||
return $this->_size;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+414
-393
@@ -1,426 +1,447 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Sample minimal test displayer. Generates only
|
||||
* failure messages and a pass count.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class HtmlReporter extends SimpleReporter {
|
||||
var $_character_set;
|
||||
|
||||
/**
|
||||
* Sample minimal test displayer. Generates only
|
||||
* failure messages and a pass count.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Does nothing yet. The first output will
|
||||
* be sent on the first test start. For use
|
||||
* by a web browser.
|
||||
* @access public
|
||||
*/
|
||||
class HtmlReporter extends SimpleReporter {
|
||||
var $_character_set;
|
||||
function HtmlReporter($character_set = 'ISO-8859-1') {
|
||||
$this->SimpleReporter();
|
||||
$this->_character_set = $character_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing yet. The first output will
|
||||
* be sent on the first test start. For use
|
||||
* by a web browser.
|
||||
* @access public
|
||||
*/
|
||||
function HtmlReporter($character_set = 'ISO-8859-1') {
|
||||
$this->SimpleReporter();
|
||||
$this->_character_set = $character_set;
|
||||
}
|
||||
/**
|
||||
* Paints the top of the web page setting the
|
||||
* title to the name of the starting test.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
$this->sendNoCacheHeaders();
|
||||
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
|
||||
print "<html>\n<head>\n<title>$test_name</title>\n";
|
||||
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
|
||||
$this->_character_set . "\">\n";
|
||||
print "<style type=\"text/css\">\n";
|
||||
print $this->_getCss() . "\n";
|
||||
print "</style>\n";
|
||||
print "</head>\n<body>\n";
|
||||
print "<h1>$test_name</h1>\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the top of the web page setting the
|
||||
* title to the name of the starting test.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
$this->sendNoCacheHeaders();
|
||||
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
|
||||
print "<html>\n<head>\n<title>$test_name</title>\n";
|
||||
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
|
||||
$this->_character_set . "\">\n";
|
||||
print "<style type=\"text/css\">\n";
|
||||
print $this->_getCss() . "\n";
|
||||
print "</style>\n";
|
||||
print "</head>\n<body>\n";
|
||||
print "<h1>$test_name</h1>\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the headers necessary to ensure the page is
|
||||
* reloaded on every request. Otherwise you could be
|
||||
* scratching your head over out of date test data.
|
||||
* @access public
|
||||
* @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");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the CSS. Add additional styles here.
|
||||
* @return string CSS code as text.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCss() {
|
||||
return ".fail { background-color: inherit; color: red; }" .
|
||||
".pass { background-color: inherit; color: green; }" .
|
||||
" pre { background-color: lightgray; color: inherit; }";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of the test with a summary of
|
||||
* the passes and failures.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
$colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
|
||||
print "<div style=\"";
|
||||
print "padding: 8px; margin-top: 1em; background-color: $colour; color: white;";
|
||||
print "\">";
|
||||
print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
|
||||
print " test cases complete:\n";
|
||||
print "<strong>" . $this->getPassCount() . "</strong> passes, ";
|
||||
print "<strong>" . $this->getFailCount() . "</strong> fails and ";
|
||||
print "<strong>" . $this->getExceptionCount() . "</strong> exceptions.";
|
||||
print "</div>\n";
|
||||
print "</body>\n</html>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test failure with a breadcrumbs
|
||||
* trail of the nesting test suites below the
|
||||
* top level test.
|
||||
* @param string $message Failure message displayed in
|
||||
* the context of the other tests.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print "<span class=\"fail\">Fail</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . $this->_htmlEntities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print "<span class=\"fail\">Exception</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP exception.
|
||||
* @param Exception $exception Exception to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
print "<span class=\"fail\">Exception</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print " -> <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print "<span class=\"pass\">Skipped</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . $this->_htmlEntities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints formatted text such as dumped variables.
|
||||
* @param string $message Text to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
print '<pre>' . $this->_htmlEntities($message) . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Character set adjusted entity conversion.
|
||||
* @param string $message Plain text or Unicode message.
|
||||
* @return string Browser readable message.
|
||||
* @access protected
|
||||
*/
|
||||
function _htmlEntities($message) {
|
||||
return htmlentities($message, ENT_COMPAT, $this->_character_set);
|
||||
/**
|
||||
* Send the headers necessary to ensure the page is
|
||||
* reloaded on every request. Otherwise you could be
|
||||
* scratching your head over out of date test data.
|
||||
* @access public
|
||||
* @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");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample minimal test displayer. Generates only
|
||||
* failure messages and a pass count. For command
|
||||
* line use. I've tried to make it look like JUnit,
|
||||
* but I wanted to output the errors as they arrived
|
||||
* which meant dropping the dots.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Paints the CSS. Add additional styles here.
|
||||
* @return string CSS code as text.
|
||||
* @access protected
|
||||
*/
|
||||
class TextReporter extends SimpleReporter {
|
||||
|
||||
/**
|
||||
* Does nothing yet. The first output will
|
||||
* be sent on the first test start.
|
||||
* @access public
|
||||
*/
|
||||
function TextReporter() {
|
||||
$this->SimpleReporter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the title only.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
if (! SimpleReporter::inCli()) {
|
||||
header('Content-type: text/plain');
|
||||
}
|
||||
print "$test_name\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of the test with a summary of
|
||||
* the passes and failures.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
if ($this->getFailCount() + $this->getExceptionCount() == 0) {
|
||||
print "OK\n";
|
||||
} else {
|
||||
print "FAILURES!!!\n";
|
||||
}
|
||||
print "Test cases run: " . $this->getTestCaseProgress() .
|
||||
"/" . $this->getTestCaseCount() .
|
||||
", Passes: " . $this->getPassCount() .
|
||||
", Failures: " . $this->getFailCount() .
|
||||
", Exceptions: " . $this->getExceptionCount() . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test failure as a stack trace.
|
||||
* @param string $message Failure message displayed in
|
||||
* the context of the other tests.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print $this->getFailCount() . ") $message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error or exception.
|
||||
* @param string $message Message to be shown.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error or exception.
|
||||
* @param Exception $exception Exception to describe.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print "Skip: $message\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints formatted text such as dumped variables.
|
||||
* @param string $message Text to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
print "$message\n";
|
||||
flush();
|
||||
}
|
||||
function _getCss() {
|
||||
return ".fail { background-color: inherit; color: red; }" .
|
||||
".pass { background-color: inherit; color: green; }" .
|
||||
" pre { background-color: lightgray; color: inherit; }";
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs just a single test group, a single case or
|
||||
* even a single test within that case.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Paints the end of the test with a summary of
|
||||
* the passes and failures.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
class SelectiveReporter extends SimpleReporterDecorator {
|
||||
var $_just_this_case =false;
|
||||
var $_just_this_test = false;
|
||||
var $_within_test_case = true;
|
||||
function paintFooter($test_name) {
|
||||
$colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
|
||||
print "<div style=\"";
|
||||
print "padding: 8px; margin-top: 1em; background-color: $colour; color: white;";
|
||||
print "\">";
|
||||
print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
|
||||
print " test cases complete:\n";
|
||||
print "<strong>" . $this->getPassCount() . "</strong> passes, ";
|
||||
print "<strong>" . $this->getFailCount() . "</strong> fails and ";
|
||||
print "<strong>" . $this->getExceptionCount() . "</strong> exceptions.";
|
||||
print "</div>\n";
|
||||
print "</body>\n</html>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the test case or group to be run,
|
||||
* and optionally a specific test.
|
||||
* @param SimpleScorer $reporter Reporter to receive events.
|
||||
* @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) {
|
||||
if (isset($just_this_case) && $just_this_case) {
|
||||
$this->_just_this_case = strtolower($just_this_case);
|
||||
$this->_within_test_case = false;
|
||||
}
|
||||
if (isset($just_this_test) && $just_this_test) {
|
||||
$this->_just_this_test = strtolower($just_this_test);
|
||||
}
|
||||
$this->SimpleReporterDecorator($reporter);
|
||||
/**
|
||||
* Paints the test failure with a breadcrumbs
|
||||
* trail of the nesting test suites below the
|
||||
* top level test.
|
||||
* @param string $message Failure message displayed in
|
||||
* the context of the other tests.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print "<span class=\"fail\">Fail</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . $this->_htmlEntities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print "<span class=\"fail\">Exception</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP exception.
|
||||
* @param Exception $exception Exception to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
print "<span class=\"fail\">Exception</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print " -> <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print "<span class=\"pass\">Skipped</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . $this->_htmlEntities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints formatted text such as dumped variables.
|
||||
* @param string $message Text to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
print '<pre>' . $this->_htmlEntities($message) . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Character set adjusted entity conversion.
|
||||
* @param string $message Plain text or Unicode message.
|
||||
* @return string Browser readable message.
|
||||
* @access protected
|
||||
*/
|
||||
function _htmlEntities($message) {
|
||||
return htmlentities($message, ENT_COMPAT, $this->_character_set);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample minimal test displayer. Generates only
|
||||
* failure messages and a pass count. For command
|
||||
* line use. I've tried to make it look like JUnit,
|
||||
* but I wanted to output the errors as they arrived
|
||||
* which meant dropping the dots.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class TextReporter extends SimpleReporter {
|
||||
|
||||
/**
|
||||
* Does nothing yet. The first output will
|
||||
* be sent on the first test start.
|
||||
* @access public
|
||||
*/
|
||||
function TextReporter() {
|
||||
$this->SimpleReporter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the title only.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
if (! SimpleReporter::inCli()) {
|
||||
header('Content-type: text/plain');
|
||||
}
|
||||
print "$test_name\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares criteria to actual the case/group name.
|
||||
* @param string $test_case The incoming test.
|
||||
* @return boolean True if matched.
|
||||
* @access protected
|
||||
*/
|
||||
function _isCaseMatch($test_case) {
|
||||
if ($this->_just_this_case) {
|
||||
return $this->_just_this_case == strtolower($test_case);
|
||||
}
|
||||
return false;
|
||||
/**
|
||||
* Paints the end of the test with a summary of
|
||||
* the passes and failures.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
if ($this->getFailCount() + $this->getExceptionCount() == 0) {
|
||||
print "OK\n";
|
||||
} else {
|
||||
print "FAILURES!!!\n";
|
||||
}
|
||||
print "Test cases run: " . $this->getTestCaseProgress() .
|
||||
"/" . $this->getTestCaseCount() .
|
||||
", Passes: " . $this->getPassCount() .
|
||||
", Failures: " . $this->getFailCount() .
|
||||
", Exceptions: " . $this->getExceptionCount() . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares criteria to actual the test name.
|
||||
* @param string $method The incoming test method.
|
||||
* @return boolean True if matched.
|
||||
* @access protected
|
||||
*/
|
||||
function _isTestMatch($method) {
|
||||
/**
|
||||
* Paints the test failure as a stack trace.
|
||||
* @param string $message Failure message displayed in
|
||||
* the context of the other tests.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print $this->getFailCount() . ") $message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error or exception.
|
||||
* @param string $message Message to be shown.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error or exception.
|
||||
* @param Exception $exception Exception to describe.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print "Skip: $message\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints formatted text such as dumped variables.
|
||||
* @param string $message Text to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
print "$message\n";
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs just a single test group, a single case or
|
||||
* even a single test within that case.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SelectiveReporter extends SimpleReporterDecorator {
|
||||
var $_just_this_case = false;
|
||||
var $_just_this_test = false;
|
||||
var $_on;
|
||||
|
||||
/**
|
||||
* Selects the test case or group to be run,
|
||||
* and optionally a specific test.
|
||||
* @param SimpleScorer $reporter Reporter to receive events.
|
||||
* @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) {
|
||||
if (isset($just_this_case) && $just_this_case) {
|
||||
$this->_just_this_case = strtolower($just_this_case);
|
||||
$this->_off();
|
||||
} else {
|
||||
$this->_on();
|
||||
}
|
||||
if (isset($just_this_test) && $just_this_test) {
|
||||
$this->_just_this_test = strtolower($just_this_test);
|
||||
}
|
||||
$this->SimpleReporterDecorator($reporter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares criteria to actual the case/group name.
|
||||
* @param string $test_case The incoming test.
|
||||
* @return boolean True if matched.
|
||||
* @access protected
|
||||
*/
|
||||
function _matchesTestCase($test_case) {
|
||||
return $this->_just_this_case == strtolower($test_case);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares criteria to actual the test name. If no
|
||||
* name was specified at the beginning, then all tests
|
||||
* can run.
|
||||
* @param string $method The incoming test method.
|
||||
* @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);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Veto everything that doesn't match the method wanted.
|
||||
* @param string $test_case 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, $method) {
|
||||
if ($this->_within_test_case && $this->_isTestMatch($method)) {
|
||||
return $this->_reporter->shouldInvoke($test_case, $method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_case, $size) {
|
||||
if ($this->_isCaseMatch($test_case)) {
|
||||
$this->_within_test_case = true;
|
||||
}
|
||||
if ($this->_within_test_case) {
|
||||
$this->_reporter->paintGroupStart($test_case, $size);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch on testing for the group or subgroup.
|
||||
* @access private
|
||||
*/
|
||||
function _on() {
|
||||
$this->_on = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch off testing for the group or subgroup.
|
||||
* @access private
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_case) {
|
||||
if ($this->_within_test_case) {
|
||||
$this->_reporter->paintGroupEnd($test_case);
|
||||
}
|
||||
if ($this->_isCaseMatch($test_case)) {
|
||||
$this->_within_test_case = false;
|
||||
}
|
||||
/**
|
||||
* Veto everything that doesn't match the method wanted.
|
||||
* @param string $test_case 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, $method) {
|
||||
if ($this->_shouldRunTest($test_case, $method)) {
|
||||
return $this->_reporter->shouldInvoke($test_case, $method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test case.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($test_case) {
|
||||
if ($this->_isCaseMatch($test_case)) {
|
||||
$this->_within_test_case = true;
|
||||
}
|
||||
if ($this->_within_test_case) {
|
||||
$this->_reporter->paintCaseStart($test_case);
|
||||
}
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_case, $size) {
|
||||
if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
|
||||
$this->_on();
|
||||
}
|
||||
$this->_reporter->paintGroupStart($test_case, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test case.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($test_case) {
|
||||
if ($this->_within_test_case) {
|
||||
$this->_reporter->paintCaseEnd($test_case);
|
||||
}
|
||||
if ($this->_isCaseMatch($test_case)) {
|
||||
$this->_within_test_case = false;
|
||||
}
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_case) {
|
||||
$this->_reporter->paintGroupEnd($test_case);
|
||||
if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
|
||||
$this->_off();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppresses skip messages.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NoSkipsReporter extends SimpleReporterDecorator {
|
||||
|
||||
/**
|
||||
* Does nothing.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) { }
|
||||
}
|
||||
?>
|
||||
+827
-827
File diff suppressed because it is too large
Load Diff
+120
-116
@@ -1,133 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* Base include file for SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by name attribute.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByName {
|
||||
var $_name;
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by name attribute.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $name Name attribute to match.
|
||||
*/
|
||||
class SimpleByName {
|
||||
var $_name;
|
||||
function SimpleByName($name) {
|
||||
$this->_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $name Name attribute to match.
|
||||
*/
|
||||
function SimpleByName($name) {
|
||||
$this->_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares with name attribute of widget.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
return ($widget->getName() == $this->_name);
|
||||
}
|
||||
function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by visible label or alt text.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Compares with name attribute of widget.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleByLabel {
|
||||
var $_label;
|
||||
function isMatch($widget) {
|
||||
return ($widget->getName() == $this->_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $label Visible text to match.
|
||||
*/
|
||||
function SimpleByLabel($label) {
|
||||
$this->_label = $label;
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by visible label or alt text.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByLabel {
|
||||
var $_label;
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $label Visible text to match.
|
||||
*/
|
||||
function SimpleByLabel($label) {
|
||||
$this->_label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares visible text of widget or
|
||||
* related label.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
if (! method_exists($widget, 'isLabel')) {
|
||||
return false;
|
||||
}
|
||||
return $widget->isLabel($this->_label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares visible text of widget or
|
||||
* related label.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
if (! method_exists($widget, 'isLabel')) {
|
||||
return false;
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches dy id attribute.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleById {
|
||||
var $_id;
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $id ID atribute to match.
|
||||
*/
|
||||
function SimpleById($id) {
|
||||
$this->_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares id attribute of widget.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
return $widget->isId($this->_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by visible label, name or alt text.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByLabelOrName {
|
||||
var $_label;
|
||||
|
||||
/**
|
||||
* Stashes the name/label for later comparison.
|
||||
* @param string $label Visible text to match.
|
||||
*/
|
||||
function SimpleByLabelOrName($label) {
|
||||
$this->_label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares visible text of widget or
|
||||
* related label or name.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
if (method_exists($widget, 'isLabel')) {
|
||||
if ($widget->isLabel($this->_label)) {
|
||||
return true;
|
||||
}
|
||||
return $widget->isLabel($this->_label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches dy id attribute.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleById {
|
||||
var $_id;
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $id ID atribute to match.
|
||||
*/
|
||||
function SimpleById($id) {
|
||||
$this->_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares id attribute of widget.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
return $widget->isId($this->_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by visible label, name or alt text.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByLabelOrName {
|
||||
var $_label;
|
||||
|
||||
/**
|
||||
* Stashes the name/label for later comparison.
|
||||
* @param string $label Visible text to match.
|
||||
*/
|
||||
function SimpleByLabelOrName($label) {
|
||||
$this->_label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares visible text of widget or
|
||||
* related label or name.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
if (method_exists($widget, 'isLabel')) {
|
||||
if ($widget->isLabel($this->_label)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ($widget->getName() == $this->_label);
|
||||
}
|
||||
return ($widget->getName() == $this->_label);
|
||||
}
|
||||
}
|
||||
?>
|
||||
+322
-322
@@ -1,333 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Wrapper for exec() functionality.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleShell {
|
||||
var $_output;
|
||||
|
||||
/**
|
||||
* Wrapper for exec() functionality.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Executes the shell comand and stashes the output.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleShell {
|
||||
var $_output;
|
||||
|
||||
/**
|
||||
* Executes the shell comand and stashes the output.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleShell() {
|
||||
$this->_output = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually runs the command. Does not trap the
|
||||
* error stream output as this need PHP 4.3+.
|
||||
* @param string $command The actual command line
|
||||
* to run.
|
||||
* @return integer Exit code.
|
||||
* @access public
|
||||
*/
|
||||
function execute($command) {
|
||||
$this->_output = false;
|
||||
exec($command, $this->_output, $ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return string Output as text.
|
||||
* @access public
|
||||
*/
|
||||
function getOutput() {
|
||||
return implode("\n", $this->_output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return array Output as array of lines.
|
||||
* @access public
|
||||
*/
|
||||
function getOutputAsList() {
|
||||
return $this->_output;
|
||||
}
|
||||
function SimpleShell() {
|
||||
$this->_output = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for testing of command line scripts and
|
||||
* utilities. Usually scripts that are external to the
|
||||
* PHP code, but support it in some way.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Actually runs the command. Does not trap the
|
||||
* error stream output as this need PHP 4.3+.
|
||||
* @param string $command The actual command line
|
||||
* to run.
|
||||
* @return integer Exit code.
|
||||
* @access public
|
||||
*/
|
||||
class ShellTestCase extends SimpleTestCase {
|
||||
var $_current_shell;
|
||||
var $_last_status;
|
||||
var $_last_command;
|
||||
|
||||
/**
|
||||
* Creates an empty test case. Should be subclassed
|
||||
* with test methods for a functional test case.
|
||||
* @param string $label Name of test case. Will use
|
||||
* 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 = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a command and buffers the results.
|
||||
* @param string $command Command to run.
|
||||
* @return boolean True if zero exit code.
|
||||
* @access public
|
||||
*/
|
||||
function execute($command) {
|
||||
$shell = &$this->_getShell();
|
||||
$this->_last_status = $shell->execute($command);
|
||||
$this->_last_command = $command;
|
||||
return ($this->_last_status === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the output of the last command.
|
||||
* @access public
|
||||
*/
|
||||
function dumpOutput() {
|
||||
$this->dump($this->getOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return string Output as text.
|
||||
* @access public
|
||||
*/
|
||||
function getOutput() {
|
||||
$shell = &$this->_getShell();
|
||||
return $shell->getOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return array Output as array of lines.
|
||||
* @access public
|
||||
*/
|
||||
function getOutputAsList() {
|
||||
$shell = &$this->_getShell();
|
||||
return $shell->getOutputAsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from within the test methods to register
|
||||
* passes and failures.
|
||||
* @param boolean $result Pass on true.
|
||||
* @param string $message Message to display describing
|
||||
* the test state.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertTrue($result, $message = false) {
|
||||
return $this->assert(new TrueExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true on false and vice versa. False
|
||||
* is the PHP definition of false, so that null,
|
||||
* empty strings, zero and an empty array all count
|
||||
* as false.
|
||||
* @param boolean $result Pass on false.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
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
|
||||
* is for testing hand extracted text, etc.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertEqual($first, $second, $message = "%s") {
|
||||
return $this->assert(
|
||||
new EqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* a different value. Otherwise a fail. This
|
||||
* is for testing hand extracted text, etc.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotEqual($first, $second, $message = "%s") {
|
||||
return $this->assert(
|
||||
new NotEqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the last status code from the shell.
|
||||
* @param integer $status Expected status of last
|
||||
* command.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to exactly match the combined STDERR and
|
||||
* STDOUT output.
|
||||
* @param string $expected Expected output.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertOutput($expected, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new EqualExpectation($expected),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the output for a Perl regex. If found
|
||||
* anywhere it passes, else it fails.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertOutputPattern($pattern, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Perl regex is found anywhere in the current
|
||||
* output then a failure is generated, else a pass.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNoOutputPattern($pattern, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* File existence check.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFileExists($path, $message = "%s") {
|
||||
$message = sprintf($message, "File [$path] should exist");
|
||||
return $this->assertTrue(file_exists($path), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* File non-existence check.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFileNotExists($path, $message = "%s") {
|
||||
$message = sprintf($message, "File [$path] should not exist");
|
||||
return $this->assertFalse(file_exists($path), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans a file for a Perl regex. If found
|
||||
* anywhere it passes, else it fails.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFilePattern($pattern, $path, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
implode('', file($path)),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Perl regex is found anywhere in the named
|
||||
* file then a failure is generated, else a pass.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNoFilePattern($pattern, $path, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
implode('', file($path)),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current shell. Used for testing the
|
||||
* the tester itself.
|
||||
* @return Shell Current shell.
|
||||
* @access protected
|
||||
*/
|
||||
function &_getShell() {
|
||||
return $this->_current_shell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for the shell to run the command on.
|
||||
* @return Shell New shell object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createShell() {
|
||||
$shell = &new SimpleShell();
|
||||
return $shell;
|
||||
}
|
||||
function execute($command) {
|
||||
$this->_output = false;
|
||||
exec($command, $this->_output, $ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return string Output as text.
|
||||
* @access public
|
||||
*/
|
||||
function getOutput() {
|
||||
return implode("\n", $this->_output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return array Output as array of lines.
|
||||
* @access public
|
||||
*/
|
||||
function getOutputAsList() {
|
||||
return $this->_output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for testing of command line scripts and
|
||||
* utilities. Usually scripts that are external to the
|
||||
* PHP code, but support it in some way.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class ShellTestCase extends SimpleTestCase {
|
||||
var $_current_shell;
|
||||
var $_last_status;
|
||||
var $_last_command;
|
||||
|
||||
/**
|
||||
* Creates an empty test case. Should be subclassed
|
||||
* with test methods for a functional test case.
|
||||
* @param string $label Name of test case. Will use
|
||||
* 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 = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a command and buffers the results.
|
||||
* @param string $command Command to run.
|
||||
* @return boolean True if zero exit code.
|
||||
* @access public
|
||||
*/
|
||||
function execute($command) {
|
||||
$shell = &$this->_getShell();
|
||||
$this->_last_status = $shell->execute($command);
|
||||
$this->_last_command = $command;
|
||||
return ($this->_last_status === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the output of the last command.
|
||||
* @access public
|
||||
*/
|
||||
function dumpOutput() {
|
||||
$this->dump($this->getOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return string Output as text.
|
||||
* @access public
|
||||
*/
|
||||
function getOutput() {
|
||||
$shell = &$this->_getShell();
|
||||
return $shell->getOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return array Output as array of lines.
|
||||
* @access public
|
||||
*/
|
||||
function getOutputAsList() {
|
||||
$shell = &$this->_getShell();
|
||||
return $shell->getOutputAsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from within the test methods to register
|
||||
* passes and failures.
|
||||
* @param boolean $result Pass on true.
|
||||
* @param string $message Message to display describing
|
||||
* the test state.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertTrue($result, $message = false) {
|
||||
return $this->assert(new TrueExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true on false and vice versa. False
|
||||
* is the PHP definition of false, so that null,
|
||||
* empty strings, zero and an empty array all count
|
||||
* as false.
|
||||
* @param boolean $result Pass on false.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
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
|
||||
* is for testing hand extracted text, etc.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertEqual($first, $second, $message = "%s") {
|
||||
return $this->assert(
|
||||
new EqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* a different value. Otherwise a fail. This
|
||||
* is for testing hand extracted text, etc.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotEqual($first, $second, $message = "%s") {
|
||||
return $this->assert(
|
||||
new NotEqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the last status code from the shell.
|
||||
* @param integer $status Expected status of last
|
||||
* command.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to exactly match the combined STDERR and
|
||||
* STDOUT output.
|
||||
* @param string $expected Expected output.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertOutput($expected, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new EqualExpectation($expected),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the output for a Perl regex. If found
|
||||
* anywhere it passes, else it fails.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertOutputPattern($pattern, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Perl regex is found anywhere in the current
|
||||
* output then a failure is generated, else a pass.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNoOutputPattern($pattern, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* File existence check.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFileExists($path, $message = "%s") {
|
||||
$message = sprintf($message, "File [$path] should exist");
|
||||
return $this->assertTrue(file_exists($path), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* File non-existence check.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFileNotExists($path, $message = "%s") {
|
||||
$message = sprintf($message, "File [$path] should not exist");
|
||||
return $this->assertFalse(file_exists($path), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans a file for a Perl regex. If found
|
||||
* anywhere it passes, else it fails.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFilePattern($pattern, $path, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
implode('', file($path)),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Perl regex is found anywhere in the named
|
||||
* file then a failure is generated, else a pass.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNoFilePattern($pattern, $path, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
implode('', file($path)),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current shell. Used for testing the
|
||||
* the tester itself.
|
||||
* @return Shell Current shell.
|
||||
* @access protected
|
||||
*/
|
||||
function &_getShell() {
|
||||
return $this->_current_shell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for the shell to run the command on.
|
||||
* @return Shell New shell object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createShell() {
|
||||
$shell = &new SimpleShell();
|
||||
return $shell;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
+452
-407
@@ -1,433 +1,478 @@
|
||||
<?php
|
||||
/**
|
||||
* Global state for SimpleTest and kicker script in future versions.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* Global state for SimpleTest and kicker script in future versions.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
/**#@+
|
||||
* 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__) . '/default_reporter.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Registry and test context. Includes a few
|
||||
* global options that I'm slowly getting rid of.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleTest {
|
||||
|
||||
/**
|
||||
* Reads the SimpleTest version from the release file.
|
||||
* @return string Version string.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
require_once(dirname(__FILE__) . '/reflection_php5.php');
|
||||
} else {
|
||||
require_once(dirname(__FILE__) . '/reflection_php4.php');
|
||||
function getVersion() {
|
||||
$content = file(dirname(__FILE__) . '/VERSION');
|
||||
return trim($content[0]);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Registry and test context. Includes a few
|
||||
* global options that I'm slowly getting rid of.
|
||||
* @package 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
|
||||
*/
|
||||
class SimpleTest {
|
||||
function ignore($class) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
$registry['IgnoreList'][strtolower($class)] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SimpleTest version from the release file.
|
||||
* @return string Version string.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function getVersion() {
|
||||
$content = file(dirname(__FILE__) . '/VERSION');
|
||||
return trim($content[0]);
|
||||
/**
|
||||
* Scans the now complete ignore list, and adds
|
||||
* all parent classes to the list. If a class
|
||||
* is not a runnable test case, then it's parents
|
||||
* wouldn't be either. This is syntactic sugar
|
||||
* to cut down on ommissions of ignore()'s or
|
||||
* missing abstract declarations. This cannot
|
||||
* be done whilst loading classes wiithout forcing
|
||||
* a particular order on the class declarations and
|
||||
* 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();
|
||||
foreach ($classes as $class) {
|
||||
if (SimpleTest::isIgnored($class)) {
|
||||
$reflection = new SimpleReflection($class);
|
||||
if ($parent = $reflection->getParent()) {
|
||||
SimpleTest::ignore($parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
$registry['IgnoreList'][strtolower($class)] = true;
|
||||
/**
|
||||
* Puts the object to the global pool of 'preferred' objects
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves 'preferred' objects from global pool. Class filter
|
||||
* 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) {
|
||||
if (! is_array($classes)) {
|
||||
$classes = array($classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the now complete ignore list, and adds
|
||||
* all parent classes to the list. If a class
|
||||
* is not a runnable test case, then it's parents
|
||||
* wouldn't be either. This is syntactic sugar
|
||||
* to cut down on ommissions of ignore()'s or
|
||||
* missing abstract declarations. This cannot
|
||||
* be done whilst loading classes wiithout forcing
|
||||
* a particular order on the class declarations and
|
||||
* 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();
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) {
|
||||
foreach ($classes as $class) {
|
||||
if (SimpleTest::isIgnored($class)) {
|
||||
$reflection = new SimpleReflection($class);
|
||||
if ($parent = $reflection->getParent()) {
|
||||
SimpleTest::ignore($parent);
|
||||
}
|
||||
if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) {
|
||||
return $registry['Preferred'][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a test case is in the ignore
|
||||
* list. Quite obviously the ignore list should
|
||||
* be a separate object and will be one day.
|
||||
* This method is internal to SimpleTest. Don't
|
||||
* 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();
|
||||
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
|
||||
* to false to disable. This will take effect
|
||||
* if there are no other proxy settings.
|
||||
* @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();
|
||||
$registry['DefaultProxy'] = $proxy;
|
||||
$registry['DefaultProxyUsername'] = $username;
|
||||
$registry['DefaultProxyPassword'] = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy host.
|
||||
* @return string Proxy URL.
|
||||
* @access public
|
||||
*/
|
||||
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();
|
||||
return $registry['DefaultProxyUsername'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy password.
|
||||
* @return string Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function getDefaultProxyPassword() {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return $registry['DefaultProxyPassword'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for global registry of options.
|
||||
* @return hash All stored values.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function &_getRegistry() {
|
||||
static $registry = false;
|
||||
if (! $registry) {
|
||||
$registry = SimpleTest::_getDefaults();
|
||||
}
|
||||
return $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the context of the current
|
||||
* test run.
|
||||
* @return SimpleTestContext Current test run.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &getContext() {
|
||||
static $context = false;
|
||||
if (! $context) {
|
||||
$context = new SimpleTestContext();
|
||||
}
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant default values.
|
||||
* @return hash All registry defaults.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _getDefaults() {
|
||||
return array(
|
||||
'StubBaseClass' => 'SimpleStub',
|
||||
'MockBaseClass' => 'SimpleMock',
|
||||
'IgnoreList' => array(),
|
||||
'DefaultProxy' => false,
|
||||
'DefaultProxyUsername' => false,
|
||||
'DefaultProxyPassword' => false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Container for all components for a specific
|
||||
* test run. Makes things like error queues
|
||||
* available to PHP event handlers, and also
|
||||
* gets around some nasty reference issues in
|
||||
* the mocks.
|
||||
* @package SimpleTest
|
||||
* Test to see if a test case is in the ignore
|
||||
* list. Quite obviously the ignore list should
|
||||
* be a separate object and will be one day.
|
||||
* This method is internal to SimpleTest. Don't
|
||||
* use it.
|
||||
* @param string $class Class name to test.
|
||||
* @return boolean True if should not be run.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
class SimpleTestContext {
|
||||
var $_test;
|
||||
var $_reporter;
|
||||
var $_resources;
|
||||
|
||||
/**
|
||||
* Clears down the current context.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_resources = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current test case instance. This
|
||||
* 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) {
|
||||
$this->clear();
|
||||
$this->_test = &$test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for currently running test case.
|
||||
* @return SimpleTestCase Current test.
|
||||
* @acess pubic
|
||||
*/
|
||||
function &getTest() {
|
||||
return $this->_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current reporter. This
|
||||
* global instance can be used by the mock objects
|
||||
* to send messages.
|
||||
* @param SimpleReporter $reporter Reporter to register.
|
||||
* @access public
|
||||
*/
|
||||
function setReporter(&$reporter) {
|
||||
$this->clear();
|
||||
$this->_reporter = &$reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current reporter.
|
||||
* @return SimpleReporter Current reporter.
|
||||
* @acess pubic
|
||||
*/
|
||||
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();
|
||||
}
|
||||
return $this->_resources[$resource];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrogates the stack trace to recover the
|
||||
* failure point.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleStackTrace {
|
||||
var $_prefixes;
|
||||
|
||||
/**
|
||||
* Stashes the list of target prefixes.
|
||||
* @param array $prefixes List of method prefixes
|
||||
* to search for.
|
||||
*/
|
||||
function SimpleStackTrace($prefixes) {
|
||||
$this->_prefixes = $prefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the last method name that was not within
|
||||
* Simpletest itself. Captures a stack trace if none given.
|
||||
* @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();
|
||||
foreach ($stack as $frame) {
|
||||
if ($this->_frameLiesWithinSimpleTestFolder($frame)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->_frameMatchesPrefix($frame)) {
|
||||
return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (isset($frame['file'])) {
|
||||
$path = substr(SIMPLE_TEST, 0, -1);
|
||||
if (strpos($frame['file'], $path) === 0) {
|
||||
if (dirname($frame['file']) == $path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs a current stack trace.
|
||||
* @return array Fulle trace.
|
||||
* @access private
|
||||
*/
|
||||
function _captureTrace() {
|
||||
if (function_exists('debug_backtrace')) {
|
||||
return array_reverse(debug_backtrace());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
function isIgnored($class) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return isset($registry['IgnoreList'][strtolower($class)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
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
|
||||
* to false to disable. This will take effect
|
||||
* if there are no other proxy settings.
|
||||
* @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();
|
||||
$registry['DefaultProxy'] = $proxy;
|
||||
$registry['DefaultProxyUsername'] = $username;
|
||||
$registry['DefaultProxyPassword'] = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy host.
|
||||
* @return string Proxy URL.
|
||||
* @access public
|
||||
*/
|
||||
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();
|
||||
return $registry['DefaultProxyUsername'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy password.
|
||||
* @return string Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function getDefaultProxyPassword() {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return $registry['DefaultProxyPassword'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for global registry of options.
|
||||
* @return hash All stored values.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function &_getRegistry() {
|
||||
static $registry = false;
|
||||
if (! $registry) {
|
||||
$registry = SimpleTest::_getDefaults();
|
||||
}
|
||||
return $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the context of the current
|
||||
* test run.
|
||||
* @return SimpleTestContext Current test run.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &getContext() {
|
||||
static $context = false;
|
||||
if (! $context) {
|
||||
$context = new SimpleTestContext();
|
||||
}
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant default values.
|
||||
* @return hash All registry defaults.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _getDefaults() {
|
||||
return array(
|
||||
'StubBaseClass' => 'SimpleStub',
|
||||
'MockBaseClass' => 'SimpleMock',
|
||||
'IgnoreList' => array(),
|
||||
'DefaultProxy' => false,
|
||||
'DefaultProxyUsername' => false,
|
||||
'DefaultProxyPassword' => false,
|
||||
'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Container for all components for a specific
|
||||
* test run. Makes things like error queues
|
||||
* available to PHP event handlers, and also
|
||||
* gets around some nasty reference issues in
|
||||
* the mocks.
|
||||
* @package SimpleTest
|
||||
*/
|
||||
class SimpleTestContext {
|
||||
var $_test;
|
||||
var $_reporter;
|
||||
var $_resources;
|
||||
|
||||
/**
|
||||
* Clears down the current context.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_resources = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current test case instance. This
|
||||
* 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) {
|
||||
$this->clear();
|
||||
$this->_test = &$test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for currently running test case.
|
||||
* @return SimpleTestCase Current test.
|
||||
* @access public
|
||||
*/
|
||||
function &getTest() {
|
||||
return $this->_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current reporter. This
|
||||
* global instance can be used by the mock objects
|
||||
* to send messages.
|
||||
* @param SimpleReporter $reporter Reporter to register.
|
||||
* @access public
|
||||
*/
|
||||
function setReporter(&$reporter) {
|
||||
$this->clear();
|
||||
$this->_reporter = &$reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current reporter.
|
||||
* @return SimpleReporter Current reporter.
|
||||
* @access public
|
||||
*/
|
||||
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();
|
||||
}
|
||||
return $this->_resources[$resource];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrogates the stack trace to recover the
|
||||
* failure point.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleStackTrace {
|
||||
var $_prefixes;
|
||||
|
||||
/**
|
||||
* Stashes the list of target prefixes.
|
||||
* @param array $prefixes List of method prefixes
|
||||
* to search for.
|
||||
*/
|
||||
function SimpleStackTrace($prefixes) {
|
||||
$this->_prefixes = $prefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the last method name that was not within
|
||||
* Simpletest itself. Captures a stack trace if none given.
|
||||
* @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();
|
||||
foreach ($stack as $frame) {
|
||||
if ($this->_frameLiesWithinSimpleTestFolder($frame)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->_frameMatchesPrefix($frame)) {
|
||||
return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (isset($frame['file'])) {
|
||||
$path = substr(SIMPLE_TEST, 0, -1);
|
||||
if (strpos($frame['file'], $path) === 0) {
|
||||
if (dirname($frame['file']) == $path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs a current stack trace.
|
||||
* @return array Fulle trace.
|
||||
* @access private
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
+192
-192
@@ -1,216 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Stashes an error for later. Useful for constructors
|
||||
* until PHP gets exceptions.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleStickyError {
|
||||
var $_error = 'Constructor not chained';
|
||||
|
||||
/**
|
||||
* Stashes an error for later. Useful for constructors
|
||||
* until PHP gets exceptions.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Sets the error to empty.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleStickyError {
|
||||
var $_error = 'Constructor not chained';
|
||||
|
||||
/**
|
||||
* Sets the error to empty.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleStickyError() {
|
||||
$this->_clearError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for an outstanding error.
|
||||
* @return boolean True if there is an error.
|
||||
* @access public
|
||||
*/
|
||||
function isError() {
|
||||
return ($this->_error != '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for an outstanding error.
|
||||
* @return string Empty string if no error otherwise
|
||||
* the error message.
|
||||
* @access public
|
||||
*/
|
||||
function getError() {
|
||||
return $this->_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal error.
|
||||
* @param string Error message to stash.
|
||||
* @access protected
|
||||
*/
|
||||
function _setError($error) {
|
||||
$this->_error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the error state to no error.
|
||||
* @access protected
|
||||
*/
|
||||
function _clearError() {
|
||||
$this->_setError('');
|
||||
}
|
||||
function SimpleStickyError() {
|
||||
$this->_clearError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for TCP/IP socket.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Test for an outstanding error.
|
||||
* @return boolean True if there is an error.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleSocket extends SimpleStickyError {
|
||||
var $_handle;
|
||||
var $_is_open = false;
|
||||
var $_sent = '';
|
||||
var $lock_size;
|
||||
function isError() {
|
||||
return ($this->_error != '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a socket for reading and writing.
|
||||
* @param string $host Hostname to send request to.
|
||||
* @param integer $port Port on remote machine to open.
|
||||
* @param integer $timeout Connection timeout in seconds.
|
||||
* @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");
|
||||
return;
|
||||
}
|
||||
$this->_is_open = true;
|
||||
$this->_block_size = $block_size;
|
||||
SimpleTestCompatibility::setTimeout($this->_handle, $timeout);
|
||||
/**
|
||||
* Accessor for an outstanding error.
|
||||
* @return string Empty string if no error otherwise
|
||||
* the error message.
|
||||
* @access public
|
||||
*/
|
||||
function getError() {
|
||||
return $this->_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal error.
|
||||
* @param string Error message to stash.
|
||||
* @access protected
|
||||
*/
|
||||
function _setError($error) {
|
||||
$this->_error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the error state to no error.
|
||||
* @access protected
|
||||
*/
|
||||
function _clearError() {
|
||||
$this->_setError('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for TCP/IP socket.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleSocket extends SimpleStickyError {
|
||||
var $_handle;
|
||||
var $_is_open = false;
|
||||
var $_sent = '';
|
||||
var $lock_size;
|
||||
|
||||
/**
|
||||
* Opens a socket for reading and writing.
|
||||
* @param string $host Hostname to send request to.
|
||||
* @param integer $port Port on remote machine to open.
|
||||
* @param integer $timeout Connection timeout in seconds.
|
||||
* @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");
|
||||
return;
|
||||
}
|
||||
$this->_is_open = true;
|
||||
$this->_block_size = $block_size;
|
||||
SimpleTestCompatibility::setTimeout($this->_handle, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if ($this->isError() || ! $this->isOpen()) {
|
||||
return false;
|
||||
}
|
||||
$count = fwrite($this->_handle, $message);
|
||||
if (! $count) {
|
||||
if ($count === false) {
|
||||
$this->_setError('Cannot write to socket');
|
||||
$this->close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
fflush($this->_handle);
|
||||
$this->_sent .= $message;
|
||||
return true;
|
||||
/**
|
||||
* 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) {
|
||||
if ($this->isError() || ! $this->isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
if ($this->isError() || ! $this->isOpen()) {
|
||||
return false;
|
||||
}
|
||||
$raw = @fread($this->_handle, $this->_block_size);
|
||||
if ($raw === false) {
|
||||
$this->_setError('Cannot read from socket');
|
||||
$count = fwrite($this->_handle, $message);
|
||||
if (! $count) {
|
||||
if ($count === false) {
|
||||
$this->_setError('Cannot write to 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() {
|
||||
$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 string $host Host to connect to.
|
||||
* @param integer $port Port on host.
|
||||
* @param integer $error_number Recipient of error code.
|
||||
* @param string $error Recipoent of error message.
|
||||
* @param integer $timeout Maximum time to wait for connection.
|
||||
* @access protected
|
||||
*/
|
||||
function _openSocket($host, $port, &$error_number, &$error, $timeout) {
|
||||
return @fsockopen($host, $port, $error_number, $error, $timeout);
|
||||
return false;
|
||||
}
|
||||
fflush($this->_handle);
|
||||
$this->_sent .= $message;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for TCP/IP socket over TLS.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* 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
|
||||
*/
|
||||
class SimpleSecureSocket extends SimpleSocket {
|
||||
|
||||
/**
|
||||
* Opens a secure socket for reading and writing.
|
||||
* @param string $host Hostname to send request to.
|
||||
* @param integer $port Port on remote machine to open.
|
||||
* @param integer $timeout Connection timeout in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleSecureSocket($host, $port, $timeout) {
|
||||
$this->SimpleSocket($host, $port, $timeout);
|
||||
function read() {
|
||||
if ($this->isError() || ! $this->isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually opens the low level socket.
|
||||
* @param string $host Host to connect to.
|
||||
* @param integer $port Port on host.
|
||||
* @param integer $error_number Recipient of error code.
|
||||
* @param string $error Recipient of error message.
|
||||
* @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);
|
||||
$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() {
|
||||
$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 string $host Host to connect to.
|
||||
* @param integer $port Port on host.
|
||||
* @param integer $error_number Recipient of error code.
|
||||
* @param string $error Recipoent of error message.
|
||||
* @param integer $timeout Maximum time to wait for connection.
|
||||
* @access protected
|
||||
*/
|
||||
function _openSocket($host, $port, &$error_number, &$error, $timeout) {
|
||||
return @fsockopen($host, $port, $error_number, $error, $timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for TCP/IP socket over TLS.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleSecureSocket extends SimpleSocket {
|
||||
|
||||
/**
|
||||
* Opens a secure socket for reading and writing.
|
||||
* @param string $host Hostname to send request to.
|
||||
* @param integer $port Port on remote machine to open.
|
||||
* @param integer $timeout Connection timeout in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleSecureSocket($host, $port, $timeout) {
|
||||
$this->SimpleSocket($host, $port, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually opens the low level socket.
|
||||
* @param string $host Host to connect to.
|
||||
* @param integer $port Port on host.
|
||||
* @param integer $error_number Recipient of error code.
|
||||
* @param string $error Recipient of error message.
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
?>
|
||||
+1359
-1333
File diff suppressed because it is too large
Load Diff
+653
-623
File diff suppressed because it is too large
Load Diff
+412
-411
@@ -1,419 +1,420 @@
|
||||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
/**#@-*/
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Standard unit test class for day to day testing
|
||||
* of PHP code XP style. Adds some useful standard
|
||||
* assertions.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class UnitTestCase extends SimpleTestCase {
|
||||
|
||||
/**
|
||||
* Standard unit test class for day to day testing
|
||||
* of PHP code XP style. Adds some useful standard
|
||||
* assertions.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* Creates an empty test case. Should be subclassed
|
||||
* with test methods for a functional test case.
|
||||
* @param string $label Name of test case. Will use
|
||||
* the class name if none specified.
|
||||
* @access public
|
||||
*/
|
||||
class UnitTestCase extends SimpleTestCase {
|
||||
|
||||
/**
|
||||
* Creates an empty test case. Should be subclassed
|
||||
* with test methods for a functional test case.
|
||||
* @param string $label Name of test case. Will use
|
||||
* the class name if none specified.
|
||||
* @access public
|
||||
*/
|
||||
function UnitTestCase($label = false) {
|
||||
if (! $label) {
|
||||
$label = get_class($this);
|
||||
}
|
||||
$this->SimpleTestCase($label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from within the test methods to register
|
||||
* passes and failures.
|
||||
* @param boolean $result Pass on true.
|
||||
* @param string $message Message to display describing
|
||||
* the test state.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertTrue($result, $message = false) {
|
||||
return $this->assert(new TrueExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true on false and vice versa. False
|
||||
* is the PHP definition of false, so that null,
|
||||
* empty strings, zero and an empty array all count
|
||||
* as false.
|
||||
* @param boolean $result Pass on false.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertFalse($result, $message = '%s') {
|
||||
return $this->assert(new FalseExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true if the value is null.
|
||||
* @param null $value Supposedly null value.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNull($value, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($value) . '] should be null');
|
||||
return $this->assertTrue(! isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true if the value is set.
|
||||
* @param mixed $value Supposedly set value.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNotNull($value, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($value) . '] should not be null');
|
||||
return $this->assertTrue(isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type and class test. Will pass if class
|
||||
* matches the type name or is a subclass or
|
||||
* if not an object, but the type is correct.
|
||||
* @param mixed $object Object to test.
|
||||
* @param string $type Type name as string.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertIsA($object, $type, $message = '%s') {
|
||||
return $this->assert(
|
||||
new IsAExpectation($type),
|
||||
$object,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type and class mismatch test. Will pass if class
|
||||
* name or underling type does not match the one
|
||||
* specified.
|
||||
* @param mixed $object Object to test.
|
||||
* @param string $type Type name as string.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNotA($object, $type, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotAExpectation($type),
|
||||
$object,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value only. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertEqual($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new EqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* a different value. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotEqual($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotEqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the if the first parameter
|
||||
* is near enough to the second by the margin.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertWithinMargin($first, $second, $margin, $message = '%s') {
|
||||
return $this->assert(
|
||||
new WithinMarginExpectation($first, $margin),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters differ
|
||||
* by more than the margin.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertOutsideMargin($first, $second, $margin, $message = '%s') {
|
||||
return $this->assert(
|
||||
new OutsideMarginExpectation($first, $margin),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value and same type. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertIdentical($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new IdenticalExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the different value or different type.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotIdentical($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotIdenticalExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if both parameters refer
|
||||
* to the same object. Fail otherwise.
|
||||
* @param mixed $first Object reference to check.
|
||||
* @param mixed $second Hopefully the same object.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertReference(&$first, &$second, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($first) .
|
||||
'] and [' . $dumper->describeValue($second) .
|
||||
'] should reference the same object');
|
||||
return $this->assertTrue(
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if both parameters refer
|
||||
* to different objects. Fail otherwise. The objects
|
||||
* have to be identical though.
|
||||
* @param mixed $first Object reference to check.
|
||||
* @param mixed $second Hopefully not the same object.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertClone(&$first, &$second, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($first) .
|
||||
'] and [' . $dumper->describeValue($second) .
|
||||
'] should not be the same object');
|
||||
$identical = &new IdenticalExpectation($first);
|
||||
return $this->assertTrue(
|
||||
$identical->test($second) &&
|
||||
! SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertCopy(&$first, &$second, $message = "%s") {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
"[" . $dumper->describeValue($first) .
|
||||
"] and [" . $dumper->describeValue($second) .
|
||||
"] should not be the same object");
|
||||
return $this->assertFalse(
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the Perl regex pattern
|
||||
* is found in the subject. Fail otherwise.
|
||||
* @param string $pattern Perl regex to look for including
|
||||
* the regex delimiters.
|
||||
* @param string $subject String to search in.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
$subject,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertWantedPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assertPattern($pattern, $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the perl regex pattern
|
||||
* is not present in subject. Fail if found.
|
||||
* @param string $pattern Perl regex to look for including
|
||||
* the regex delimiters.
|
||||
* @param string $subject String to search in.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNoPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
$subject,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoUnwantedPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assertNoPattern($pattern, $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function swallowErrors() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoErrors($message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
return $queue->assertNoErrors($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertError($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
return $queue->assertError($this->_coerceExpectation($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for an error. If the error mismatches it
|
||||
* passes through, otherwise it is swallowed. Any
|
||||
* left over errors trigger failures.
|
||||
* @param SimpleExpectation/string $expected The error to match.
|
||||
* @param string $message Message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function expectError($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->expectError($this->_coerceExpectation($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for an exception. If the error mismatches it
|
||||
* passes through, otherwise it is swallowed. Any
|
||||
* left over errors trigger failures.
|
||||
* @param SimpleExpectation/Exception $expected The error to match.
|
||||
* @param string $message Message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function expectException($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleExceptionTrap');
|
||||
$queue->expectException($expected, $message . $this->getAssertionLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an equality expectation if the
|
||||
* object/value is not already some type
|
||||
* of expectation.
|
||||
* @param mixed $expected Expected value.
|
||||
* @return SimpleExpectation Expectation object.
|
||||
* @access private
|
||||
*/
|
||||
function _coerceExpectation($expected) {
|
||||
if ($expected == false) {
|
||||
return new AnythingExpectation();
|
||||
}
|
||||
if (SimpleTestCompatibility::isA($expected, 'SimpleExpectation')) {
|
||||
return $expected;
|
||||
}
|
||||
if(is_string($expected)) {
|
||||
$expected = str_replace('%', '%%', $expected);
|
||||
}
|
||||
return new EqualExpectation($expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertErrorPattern($pattern, $message = '%s') {
|
||||
return $this->assertError(new PatternExpectation($pattern), $message);
|
||||
function UnitTestCase($label = false) {
|
||||
if (! $label) {
|
||||
$label = get_class($this);
|
||||
}
|
||||
$this->SimpleTestCase($label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from within the test methods to register
|
||||
* passes and failures.
|
||||
* @param boolean $result Pass on true.
|
||||
* @param string $message Message to display describing
|
||||
* the test state.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertTrue($result, $message = false) {
|
||||
return $this->assert(new TrueExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true on false and vice versa. False
|
||||
* is the PHP definition of false, so that null,
|
||||
* empty strings, zero and an empty array all count
|
||||
* as false.
|
||||
* @param boolean $result Pass on false.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertFalse($result, $message = '%s') {
|
||||
return $this->assert(new FalseExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true if the value is null.
|
||||
* @param null $value Supposedly null value.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNull($value, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($value) . '] should be null');
|
||||
return $this->assertTrue(! isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true if the value is set.
|
||||
* @param mixed $value Supposedly set value.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNotNull($value, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($value) . '] should not be null');
|
||||
return $this->assertTrue(isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type and class test. Will pass if class
|
||||
* matches the type name or is a subclass or
|
||||
* if not an object, but the type is correct.
|
||||
* @param mixed $object Object to test.
|
||||
* @param string $type Type name as string.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertIsA($object, $type, $message = '%s') {
|
||||
return $this->assert(
|
||||
new IsAExpectation($type),
|
||||
$object,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type and class mismatch test. Will pass if class
|
||||
* name or underling type does not match the one
|
||||
* specified.
|
||||
* @param mixed $object Object to test.
|
||||
* @param string $type Type name as string.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNotA($object, $type, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotAExpectation($type),
|
||||
$object,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value only. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertEqual($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new EqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* a different value. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotEqual($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotEqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the if the first parameter
|
||||
* is near enough to the second by the margin.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertWithinMargin($first, $second, $margin, $message = '%s') {
|
||||
return $this->assert(
|
||||
new WithinMarginExpectation($first, $margin),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters differ
|
||||
* by more than the margin.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertOutsideMargin($first, $second, $margin, $message = '%s') {
|
||||
return $this->assert(
|
||||
new OutsideMarginExpectation($first, $margin),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value and same type. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertIdentical($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new IdenticalExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the different value or different type.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotIdentical($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotIdenticalExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if both parameters refer
|
||||
* to the same object. Fail otherwise.
|
||||
* @param mixed $first Object reference to check.
|
||||
* @param mixed $second Hopefully the same object.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertReference(&$first, &$second, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($first) .
|
||||
'] and [' . $dumper->describeValue($second) .
|
||||
'] should reference the same object');
|
||||
return $this->assertTrue(
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if both parameters refer
|
||||
* to different objects. Fail otherwise. The objects
|
||||
* have to be identical though.
|
||||
* @param mixed $first Object reference to check.
|
||||
* @param mixed $second Hopefully not the same object.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertClone(&$first, &$second, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($first) .
|
||||
'] and [' . $dumper->describeValue($second) .
|
||||
'] should not be the same object');
|
||||
$identical = &new IdenticalExpectation($first);
|
||||
return $this->assertTrue(
|
||||
$identical->test($second) &&
|
||||
! SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertCopy(&$first, &$second, $message = "%s") {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
"[" . $dumper->describeValue($first) .
|
||||
"] and [" . $dumper->describeValue($second) .
|
||||
"] should not be the same object");
|
||||
return $this->assertFalse(
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the Perl regex pattern
|
||||
* is found in the subject. Fail otherwise.
|
||||
* @param string $pattern Perl regex to look for including
|
||||
* the regex delimiters.
|
||||
* @param string $subject String to search in.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
$subject,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertWantedPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assertPattern($pattern, $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the perl regex pattern
|
||||
* is not present in subject. Fail if found.
|
||||
* @param string $pattern Perl regex to look for including
|
||||
* the regex delimiters.
|
||||
* @param string $subject String to search in.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNoPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
$subject,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoUnwantedPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assertNoPattern($pattern, $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function swallowErrors() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoErrors($message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
return $queue->assertNoErrors($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertError($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
return $queue->assertError($this->_coerceExpectation($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for an error. If the error mismatches it
|
||||
* passes through, otherwise it is swallowed. Any
|
||||
* left over errors trigger failures.
|
||||
* @param SimpleExpectation/string $expected The error to match.
|
||||
* @param string $message Message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function expectError($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->expectError($this->_coerceExpectation($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for an exception. If the error mismatches it
|
||||
* passes through, otherwise it is swallowed. Any
|
||||
* left over errors trigger failures.
|
||||
* @param SimpleExpectation/Exception $expected The error to match.
|
||||
* @param string $message Message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function expectException($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleExceptionTrap');
|
||||
// :HACK: Directly substituting in seems to cause a segfault with
|
||||
// Zend Optimizer on some systems
|
||||
$line = $this->getAssertionLine();
|
||||
$queue->expectException($expected, $message . $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an equality expectation if the
|
||||
* object/value is not already some type
|
||||
* of expectation.
|
||||
* @param mixed $expected Expected value.
|
||||
* @return SimpleExpectation Expectation object.
|
||||
* @access private
|
||||
*/
|
||||
function _coerceExpectation($expected) {
|
||||
if ($expected == false) {
|
||||
return new TrueExpectation();
|
||||
}
|
||||
if (SimpleTestCompatibility::isA($expected, 'SimpleExpectation')) {
|
||||
return $expected;
|
||||
}
|
||||
return new EqualExpectation(
|
||||
is_string($expected) ? str_replace('%', '%%', $expected) : $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertErrorPattern($pattern, $message = '%s') {
|
||||
return $this->assertError(new PatternExpectation($pattern), $message);
|
||||
}
|
||||
}
|
||||
?>
|
||||
+499
-496
File diff suppressed because it is too large
Load Diff
+314
-315
@@ -1,333 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/cookies.php');
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
require_once(dirname(__FILE__) . '/authentication.php');
|
||||
/**#@-*/
|
||||
|
||||
if (! defined('DEFAULT_MAX_REDIRECTS')) {
|
||||
define('DEFAULT_MAX_REDIRECTS', 3);
|
||||
}
|
||||
if (! defined('DEFAULT_CONNECTION_TIMEOUT')) {
|
||||
define('DEFAULT_CONNECTION_TIMEOUT', 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches web pages whilst keeping track of
|
||||
* cookies and authentication.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleUserAgent {
|
||||
var $_cookie_jar;
|
||||
var $_cookies_enabled = true;
|
||||
var $_authenticator;
|
||||
var $_max_redirects = DEFAULT_MAX_REDIRECTS;
|
||||
var $_proxy = false;
|
||||
var $_proxy_username = false;
|
||||
var $_proxy_password = false;
|
||||
var $_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
|
||||
var $_additional_headers = array();
|
||||
|
||||
/**
|
||||
* Starts with no cookies, realms or proxies.
|
||||
* @access public
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/cookies.php');
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
require_once(dirname(__FILE__) . '/authentication.php');
|
||||
/**#@-*/
|
||||
|
||||
if (! defined('DEFAULT_MAX_REDIRECTS')) {
|
||||
define('DEFAULT_MAX_REDIRECTS', 3);
|
||||
function SimpleUserAgent() {
|
||||
$this->_cookie_jar = &new SimpleCookieJar();
|
||||
$this->_authenticator = &new SimpleAuthenticator();
|
||||
}
|
||||
|
||||
if (! defined('DEFAULT_CONNECTION_TIMEOUT')) {
|
||||
define('DEFAULT_CONNECTION_TIMEOUT', 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches web pages whilst keeping track of
|
||||
* cookies and authentication.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* Removes expired and temporary cookies as if
|
||||
* the browser was closed and re-opened. Authorisation
|
||||
* has to be obtained again as well.
|
||||
* @param string/integer $date Time when session restarted.
|
||||
* If omitted then all persistent
|
||||
* cookies are kept.
|
||||
* @access public
|
||||
*/
|
||||
class SimpleUserAgent {
|
||||
var $_cookie_jar;
|
||||
var $_cookies_enabled = true;
|
||||
var $_authenticator;
|
||||
var $_max_redirects = DEFAULT_MAX_REDIRECTS;
|
||||
var $_proxy = false;
|
||||
var $_proxy_username = false;
|
||||
var $_proxy_password = false;
|
||||
var $_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
|
||||
var $_additional_headers = array();
|
||||
|
||||
/**
|
||||
* Starts with no cookies, realms or proxies.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleUserAgent() {
|
||||
$this->_cookie_jar = &new SimpleCookieJar();
|
||||
$this->_authenticator = &new SimpleAuthenticator();
|
||||
function restart($date = false) {
|
||||
$this->_cookie_jar->restartSession($date);
|
||||
$this->_authenticator->restartSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a header to every fetch.
|
||||
* @param string $header Header line to add to every
|
||||
* request until cleared.
|
||||
* @access public
|
||||
*/
|
||||
function addHeader($header) {
|
||||
$this->_additional_headers[] = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages the cookies by the specified time.
|
||||
* @param integer $interval Amount in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function ageCookies($interval) {
|
||||
$this->_cookie_jar->agePrematurely($interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional cookie. If a cookie has
|
||||
* the same name and path it is replaced.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $host Host upon which the cookie is valid.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date.
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
||||
$this->_cookie_jar->setCookie($name, $value, $host, $path, $expiry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the most specific cookie value from the
|
||||
* browser cookies.
|
||||
* @param string $host Host to search.
|
||||
* @param string $path Applicable path.
|
||||
* @param string $name Name of cookie to read.
|
||||
* @return string False if not present, else the
|
||||
* value as a string.
|
||||
* @access public
|
||||
*/
|
||||
function getCookieValue($host, $path, $name) {
|
||||
return $this->_cookie_jar->getCookieValue($host, $path, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current cookies within the base URL.
|
||||
* @param string $name Key of cookie to find.
|
||||
* @param SimpleUrl $base Base URL to search from.
|
||||
* @return string/boolean Null if there is no base URL, false
|
||||
* if the cookie is not set.
|
||||
* @access public
|
||||
*/
|
||||
function getBaseCookieValue($name, $base) {
|
||||
if (! $base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes expired and temporary cookies as if
|
||||
* the browser was closed and re-opened. Authorisation
|
||||
* has to be obtained again as well.
|
||||
* @param string/integer $date Time when session restarted.
|
||||
* If omitted then all persistent
|
||||
* cookies are kept.
|
||||
* @access public
|
||||
*/
|
||||
function restart($date = false) {
|
||||
$this->_cookie_jar->restartSession($date);
|
||||
$this->_authenticator->restartSession();
|
||||
return $this->getCookieValue($base->getHost(), $base->getPath(), $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches off cookie sending and recieving.
|
||||
* @access public
|
||||
*/
|
||||
function ignoreCookies() {
|
||||
$this->_cookies_enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches back on the cookie sending and recieving.
|
||||
* @access public
|
||||
*/
|
||||
function useCookies() {
|
||||
$this->_cookies_enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the socket timeout for opening a connection.
|
||||
* @param integer $timeout Maximum time in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function setConnectionTimeout($timeout) {
|
||||
$this->_connection_timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of redirects before
|
||||
* a page will be loaded anyway.
|
||||
* @param integer $max Most hops allowed.
|
||||
* @access public
|
||||
*/
|
||||
function setMaximumRedirects($max) {
|
||||
$this->_max_redirects = $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets proxy to use on all requests for when
|
||||
* testing from behind a firewall. Set URL
|
||||
* to false to disable.
|
||||
* @param string $proxy Proxy URL.
|
||||
* @param string $username Proxy username for authentication.
|
||||
* @param string $password Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function useProxy($proxy, $username, $password) {
|
||||
if (! $proxy) {
|
||||
$this->_proxy = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a header to every fetch.
|
||||
* @param string $header Header line to add to every
|
||||
* request until cleared.
|
||||
* @access public
|
||||
*/
|
||||
function addHeader($header) {
|
||||
$this->_additional_headers[] = $header;
|
||||
if ((strncmp($proxy, 'http://', 7) != 0) && (strncmp($proxy, 'https://', 8) != 0)) {
|
||||
$proxy = 'http://'. $proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages the cookies by the specified time.
|
||||
* @param integer $interval Amount in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function ageCookies($interval) {
|
||||
$this->_cookie_jar->agePrematurely($interval);
|
||||
$this->_proxy = &new SimpleUrl($proxy);
|
||||
$this->_proxy_username = $username;
|
||||
$this->_proxy_password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the redirect limit is passed.
|
||||
* @param integer $redirects Count so far.
|
||||
* @return boolean True if over.
|
||||
* @access private
|
||||
*/
|
||||
function _isTooManyRedirects($redirects) {
|
||||
return ($redirects > $this->_max_redirects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity for the current realm.
|
||||
* @param string $host Host to which realm applies.
|
||||
* @param string $realm Full name of realm.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentity($host, $realm, $username, $password) {
|
||||
$this->_authenticator->setIdentityForRealm($host, $realm, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a URL as a response object. Will keep trying if redirected.
|
||||
* It will also collect authentication realm information.
|
||||
* @param string/SimpleUrl $url Target to fetch.
|
||||
* @param SimpleEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Hopefully the target page.
|
||||
* @access public
|
||||
*/
|
||||
function &fetchResponse($url, $encoding) {
|
||||
if ($encoding->getMethod() != 'POST') {
|
||||
$url->addRequestParameters($encoding);
|
||||
$encoding->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional cookie. If a cookie has
|
||||
* the same name and path it is replaced.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $host Host upon which the cookie is valid.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date.
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
||||
$this->_cookie_jar->setCookie($name, $value, $host, $path, $expiry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the most specific cookie value from the
|
||||
* browser cookies.
|
||||
* @param string $host Host to search.
|
||||
* @param string $path Applicable path.
|
||||
* @param string $name Name of cookie to read.
|
||||
* @return string False if not present, else the
|
||||
* value as a string.
|
||||
* @access public
|
||||
*/
|
||||
function getCookieValue($host, $path, $name) {
|
||||
return $this->_cookie_jar->getCookieValue($host, $path, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current cookies within the base URL.
|
||||
* @param string $name Key of cookie to find.
|
||||
* @param SimpleUrl $base Base URL to search from.
|
||||
* @return string/boolean Null if there is no base URL, false
|
||||
* if the cookie is not set.
|
||||
* @access public
|
||||
*/
|
||||
function getBaseCookieValue($name, $base) {
|
||||
if (! $base) {
|
||||
return null;
|
||||
}
|
||||
return $this->getCookieValue($base->getHost(), $base->getPath(), $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches off cookie sending and recieving.
|
||||
* @access public
|
||||
*/
|
||||
function ignoreCookies() {
|
||||
$this->_cookies_enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches back on the cookie sending and recieving.
|
||||
* @access public
|
||||
*/
|
||||
function useCookies() {
|
||||
$this->_cookies_enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the socket timeout for opening a connection.
|
||||
* @param integer $timeout Maximum time in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function setConnectionTimeout($timeout) {
|
||||
$this->_connection_timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of redirects before
|
||||
* a page will be loaded anyway.
|
||||
* @param integer $max Most hops allowed.
|
||||
* @access public
|
||||
*/
|
||||
function setMaximumRedirects($max) {
|
||||
$this->_max_redirects = $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets proxy to use on all requests for when
|
||||
* testing from behind a firewall. Set URL
|
||||
* to false to disable.
|
||||
* @param string $proxy Proxy URL.
|
||||
* @param string $username Proxy username for authentication.
|
||||
* @param string $password Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function useProxy($proxy, $username, $password) {
|
||||
if (! $proxy) {
|
||||
$this->_proxy = false;
|
||||
return;
|
||||
}
|
||||
if ((strncmp($proxy, 'http://', 7) != 0) && (strncmp($proxy, 'https://', 8) != 0)) {
|
||||
$proxy = 'http://'. $proxy;
|
||||
}
|
||||
$this->_proxy = &new SimpleUrl($proxy);
|
||||
$this->_proxy_username = $username;
|
||||
$this->_proxy_password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the redirect limit is passed.
|
||||
* @param integer $redirects Count so far.
|
||||
* @return boolean True if over.
|
||||
* @access private
|
||||
*/
|
||||
function _isTooManyRedirects($redirects) {
|
||||
return ($redirects > $this->_max_redirects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity for the current realm.
|
||||
* @param string $host Host to which realm applies.
|
||||
* @param string $realm Full name of realm.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentity($host, $realm, $username, $password) {
|
||||
$this->_authenticator->setIdentityForRealm($host, $realm, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a URL as a response object. Will keep trying if redirected.
|
||||
* It will also collect authentication realm information.
|
||||
* @param string/SimpleUrl $url Target to fetch.
|
||||
* @param SimpleEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Hopefully the target page.
|
||||
* @access public
|
||||
*/
|
||||
function &fetchResponse($url, $encoding) {
|
||||
if ($encoding->getMethod() != 'POST') {
|
||||
$url->addRequestParameters($encoding);
|
||||
$encoding->clear();
|
||||
}
|
||||
$response = &$this->_fetchWhileRedirected($url, $encoding);
|
||||
if ($headers = $response->getHeaders()) {
|
||||
if ($headers->isChallenge()) {
|
||||
$this->_authenticator->addRealm(
|
||||
$url,
|
||||
$headers->getAuthentication(),
|
||||
$headers->getRealm());
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the page until no longer redirected or
|
||||
* until the redirect limit runs out.
|
||||
* @param SimpleUrl $url Target to fetch.
|
||||
* @param SimpelFormEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Hopefully the target page.
|
||||
* @access private
|
||||
*/
|
||||
function &_fetchWhileRedirected($url, $encoding) {
|
||||
$redirects = 0;
|
||||
do {
|
||||
$response = &$this->_fetch($url, $encoding);
|
||||
if ($response->isError()) {
|
||||
return $response;
|
||||
}
|
||||
$headers = $response->getHeaders();
|
||||
$location = new SimpleUrl($headers->getLocation());
|
||||
$url = $location->makeAbsolute($url);
|
||||
if ($this->_cookies_enabled) {
|
||||
$headers->writeCookiesToJar($this->_cookie_jar, $url);
|
||||
}
|
||||
if (! $headers->isRedirect()) {
|
||||
break;
|
||||
}
|
||||
$encoding = new SimpleGetEncoding();
|
||||
} while (! $this->_isTooManyRedirects(++$redirects));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually make the web request.
|
||||
* @param SimpleUrl $url Target to fetch.
|
||||
* @param SimpleFormEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Headers and hopefully content.
|
||||
* @access protected
|
||||
*/
|
||||
function &_fetch($url, $encoding) {
|
||||
$request = &$this->_createRequest($url, $encoding);
|
||||
$response = &$request->fetch($this->_connection_timeout);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a full page request.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @param SimpleFormEncoding $encoding POST/GET parameters.
|
||||
* @return SimpleHttpRequest New request.
|
||||
* @access private
|
||||
*/
|
||||
function &_createRequest($url, $encoding) {
|
||||
$request = &$this->_createHttpRequest($url, $encoding);
|
||||
$this->_addAdditionalHeaders($request);
|
||||
if ($this->_cookies_enabled) {
|
||||
$request->readCookiesFromJar($this->_cookie_jar, $url);
|
||||
}
|
||||
$this->_authenticator->addHeaders($request, $url);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the appropriate HTTP request object.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @param SimpleFormEncoding $parameters POST/GET parameters.
|
||||
* @return SimpleHttpRequest New request object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createHttpRequest($url, $encoding) {
|
||||
$request = &new SimpleHttpRequest($this->_createRoute($url), $encoding);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up either a direct route or via a proxy.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @return SimpleRoute Route to take to fetch URL.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createRoute($url) {
|
||||
if ($this->_proxy) {
|
||||
$route = &new SimpleProxyRoute(
|
||||
$response = &$this->_fetchWhileRedirected($url, $encoding);
|
||||
if ($headers = $response->getHeaders()) {
|
||||
if ($headers->isChallenge()) {
|
||||
$this->_authenticator->addRealm(
|
||||
$url,
|
||||
$this->_proxy,
|
||||
$this->_proxy_username,
|
||||
$this->_proxy_password);
|
||||
} else {
|
||||
$route = &new SimpleRoute($url);
|
||||
$headers->getAuthentication(),
|
||||
$headers->getRealm());
|
||||
}
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional manual headers.
|
||||
* @param SimpleHttpRequest $request Outgoing request.
|
||||
* @access private
|
||||
*/
|
||||
function _addAdditionalHeaders(&$request) {
|
||||
foreach ($this->_additional_headers as $header) {
|
||||
$request->addHeaderLine($header);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the page until no longer redirected or
|
||||
* until the redirect limit runs out.
|
||||
* @param SimpleUrl $url Target to fetch.
|
||||
* @param SimpelFormEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Hopefully the target page.
|
||||
* @access private
|
||||
*/
|
||||
function &_fetchWhileRedirected($url, $encoding) {
|
||||
$redirects = 0;
|
||||
do {
|
||||
$response = &$this->_fetch($url, $encoding);
|
||||
if ($response->isError()) {
|
||||
return $response;
|
||||
}
|
||||
$headers = $response->getHeaders();
|
||||
$location = new SimpleUrl($headers->getLocation());
|
||||
$url = $location->makeAbsolute($url);
|
||||
if ($this->_cookies_enabled) {
|
||||
$headers->writeCookiesToJar($this->_cookie_jar, $url);
|
||||
}
|
||||
if (! $headers->isRedirect()) {
|
||||
break;
|
||||
}
|
||||
$encoding = new SimpleGetEncoding();
|
||||
} while (! $this->_isTooManyRedirects(++$redirects));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually make the web request.
|
||||
* @param SimpleUrl $url Target to fetch.
|
||||
* @param SimpleFormEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Headers and hopefully content.
|
||||
* @access protected
|
||||
*/
|
||||
function &_fetch($url, $encoding) {
|
||||
$request = &$this->_createRequest($url, $encoding);
|
||||
$response = &$request->fetch($this->_connection_timeout);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a full page request.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @param SimpleFormEncoding $encoding POST/GET parameters.
|
||||
* @return SimpleHttpRequest New request.
|
||||
* @access private
|
||||
*/
|
||||
function &_createRequest($url, $encoding) {
|
||||
$request = &$this->_createHttpRequest($url, $encoding);
|
||||
$this->_addAdditionalHeaders($request);
|
||||
if ($this->_cookies_enabled) {
|
||||
$request->readCookiesFromJar($this->_cookie_jar, $url);
|
||||
}
|
||||
$this->_authenticator->addHeaders($request, $url);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the appropriate HTTP request object.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @param SimpleFormEncoding $parameters POST/GET parameters.
|
||||
* @return SimpleHttpRequest New request object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createHttpRequest($url, $encoding) {
|
||||
$request = &new SimpleHttpRequest($this->_createRoute($url), $encoding);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up either a direct route or via a proxy.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @return SimpleRoute Route to take to fetch URL.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createRoute($url) {
|
||||
if ($this->_proxy) {
|
||||
$route = &new SimpleProxyRoute(
|
||||
$url,
|
||||
$this->_proxy,
|
||||
$this->_proxy_username,
|
||||
$this->_proxy_password);
|
||||
} else {
|
||||
$route = &new SimpleRoute($url);
|
||||
}
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional manual headers.
|
||||
* @param SimpleHttpRequest $request Outgoing request.
|
||||
* @access private
|
||||
*/
|
||||
function _addAdditionalHeaders(&$request) {
|
||||
foreach ($this->_additional_headers as $header) {
|
||||
$request->addHeaderLine($header);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
+1482
-1482
File diff suppressed because it is too large
Load Diff
+617
-617
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user