diff --git a/_documentation/Database Schema.mwb b/_documentation/Database Schema.mwb new file mode 100644 index 00000000..73614ee1 Binary files /dev/null and b/_documentation/Database Schema.mwb differ diff --git a/_documentation/ROADMAP.TXT b/_documentation/ROADMAP.TXT new file mode 100644 index 00000000..5153daa5 --- /dev/null +++ b/_documentation/ROADMAP.TXT @@ -0,0 +1,21 @@ + +Appleseed Roadmap + +Updated: 06-10-2010 +Version: 0.7.4 + +0.7 SERIES +---------- +Base features, API, framework, themability, internationalisation. + +0.8 SERIES +---------- +Optimization, Standards and Compatibility. + +0.9 SERIES +---------- +FEATURE FREEZE! Bug testing, code cleanup, etc. + +1.0 SERIES +---------- +Testing, security fixes, and optimization. diff --git a/_release/CHANGELOG.txt b/_release/CHANGELOG.txt new file mode 100644 index 00000000..32c76968 --- /dev/null +++ b/_release/CHANGELOG.txt @@ -0,0 +1,5 @@ +RELEASE CHANGES + +-- 0.7.4 -- + + diff --git a/_release/update-0.7.4.sql b/_release/update-0.7.4.sql new file mode 100644 index 00000000..e69de29b diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/AbstractTester.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/AbstractTester.php new file mode 100644 index 00000000..6e65075f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/AbstractTester.php @@ -0,0 +1,205 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/ITester.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Can be used as a foundation for new DatabaseTesters. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_AbstractTester implements PHPUnit_Extensions_Database_ITester +{ + + /** + * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + protected $setUpOperation; + + /** + * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + protected $tearDownOperation; + + /** + * @var PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected $dataSet; + + /** + * @var string + */ + protected $schema; + + /** + * Creates a new database tester. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection + */ + public function __construct() + { + $this->setUpOperation = PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT(); + $this->tearDownOperation = PHPUnit_Extensions_Database_Operation_Factory::NONE(); + } + + /** + * Closes the specified connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + */ + public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $connection->close(); + } + + /** + * Returns the test dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + public function getDataSet() + { + return $this->dataSet; + } + + /** + * TestCases must call this method inside setUp(). + */ + public function onSetUp() + { + $this->getSetUpOperation()->execute($this->getConnection(), $this->getDataSet()); + } + + /** + * TestCases must call this method inside tearDown(). + */ + public function onTearDown() + { + $this->getTearDownOperation()->execute($this->getConnection(), $this->getDataSet()); + } + + /** + * Sets the test dataset to use. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet + */ + public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + $this->dataSet = $dataSet; + } + + /** + * Sets the schema value. + * + * @param string $schema + */ + public function setSchema($schema) + { + $this->schema = $schema; + } + + /** + * Sets the DatabaseOperation to call when starting the test. + * + * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation + */ + public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation) + { + $this->setUpOperation = $setUpOperation; + } + + /** + * Sets the DatabaseOperation to call when ending the test. + * + * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation + */ + public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation) + { + $this->tearDownOperation = $tearDownOperation; + } + + /** + * Returns the schema value + * + * @return string + */ + protected function getSchema() + { + return $this->schema; + } + + /** + * Returns the database operation that will be called when starting the test. + * + * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation + */ + protected function getSetUpOperation() + { + return $this->setUpOperation; + } + + /** + * Returns the database operation that will be called when ending the test. + * + * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation + */ + protected function getTearDownOperation() + { + return $this->tearDownOperation; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Constraint/DataSetIsEqual.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Constraint/DataSetIsEqual.php new file mode 100644 index 00000000..a0505617 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Constraint/DataSetIsEqual.php @@ -0,0 +1,131 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/Constraint.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Asserts whether or not two dbunit datasets are equal. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Constraint_DataSetIsEqual extends PHPUnit_Framework_Constraint +{ + + /** + * @var PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected $value; + + /** + * @var string + */ + protected $failure_reason; + + /** + * Creates a new constraint. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $value + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $value) + { + $this->value = $value; + } + + /** + * Determines whether or not the given dataset matches the dataset used to + * create this constraint. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other + * @return bool + */ + public function evaluate($other) + { + if ($other instanceof PHPUnit_Extensions_Database_DataSet_IDataSet) { + try { + $this->value->assertEquals($other); + return TRUE; + } catch (Exception $e) { + $this->failure_reason = $e->getMessage(); + return FALSE; + } + } else { + throw new InvalidArgumentException("PHPUnit_Extensions_Database_DataSet_IDataSet expected"); + } + } + + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that actual %s %s Reason: %s', + + $other->__toString(), + $this->toString(), + $this->failure_reason + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf('is equal to expected %s', + $this->value->__toString()); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Constraint/TableIsEqual.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Constraint/TableIsEqual.php new file mode 100644 index 00000000..89422a6d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Constraint/TableIsEqual.php @@ -0,0 +1,132 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/Constraint.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Asserts whether or not two dbunit tables are equal. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Constraint_TableIsEqual extends PHPUnit_Framework_Constraint +{ + + /** + * @var PHPUnit_Extensions_Database_DataSet_ITable + */ + protected $value; + + /** + * @var string + */ + protected $failure_reason; + + /** + * Creates a new constraint. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $value + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $value) + { + $this->value = $value; + } + + /** + * Determines whether or not the given table matches the table used to + * create this constraint. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $other + * @return bool + */ + public function evaluate($other) + { + if ($other instanceof PHPUnit_Extensions_Database_DataSet_ITable) { + try { + $this->value->assertEquals($other); + return TRUE; + } catch (Exception $e) { + $this->failure_reason = $e->getMessage(); + return FALSE; + } + } else { + throw new InvalidArgumentException("PHPUnit_Extensions_Database_DataSet_ITable expected"); + } + } + + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that actual %s %s Reason: %s', + + $other->__toString(), + $this->toString(), + $this->failure_reason + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf('is equal to expected %s', + + PHPUnit_Util_Type::toString($this->value)); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/DataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/DataSet.php new file mode 100644 index 00000000..e3dffe14 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/DataSet.php @@ -0,0 +1,186 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; +require_once 'PHPUnit/Extensions/Database/DB/TableIterator.php'; +require_once 'PHPUnit/Extensions/Database/DB/Table.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides access to a database instance as a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_DataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + + /** + * An array of ITable objects. + * + * @var array + */ + protected $tables = array(); + + /** + * The database connection this dataset is using. + * + * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected $databaseConnection; + + /** + * Creates a new dataset using the given database connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection + */ + public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) + { + $this->databaseConnection = $databaseConnection; + } + + /** + * Creates the query necessary to pull all of the data from a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData + * @return unknown + */ + public static function buildTableSelect(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection = NULL) + { + if ($tableMetaData->getTableName() == '') { + $e = new Exception("Empty Table Name"); + echo $e->getTraceAsString(); + throw $e; + } + + $columns = $tableMetaData->getColumns(); + if ($databaseConnection) { + $columns = array_map(array($databaseConnection, 'quoteSchemaObject'), $columns); + } + $columnList = implode(', ', $columns); + + if ($databaseConnection) { + $tableName = $databaseConnection->quoteSchemaObject($tableMetaData->getTableName()); + } else { + $tableName = $tableMetaData->getTableName(); + } + + $primaryKeys = $tableMetaData->getPrimaryKeys(); + if ($databaseConnection) { + $primaryKeys = array_map(array($databaseConnection, 'quoteSchemaObject'), $primaryKeys); + } + if (count($primaryKeys)) { + $orderBy = 'ORDER BY ' . implode(' ASC, ', $primaryKeys) . ' ASC'; + } else { + $orderBy = ''; + } + + return "SELECT {$columnList} FROM {$tableName} {$orderBy}"; + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DB_TableIterator + */ + protected function createIterator($reverse = FALSE) + { + return new PHPUnit_Extensions_Database_DB_TableIterator($this->getTableNames(), $this, $reverse); + } + + /** + * Returns a table object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DB_Table + */ + public function getTable($tableName) + { + if (!in_array($tableName, $this->getTableNames())) { + throw new InvalidArgumentException("$tableName is not a table in the current database."); + } + + if (empty($this->tables[$tableName])) { + $this->tables[$tableName] = new PHPUnit_Extensions_Database_DB_Table($this->getTableMetaData($tableName), $this->databaseConnection); + } + + return $this->tables[$tableName]; + } + + /** + * Returns a table meta data object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData + */ + public function getTableMetaData($tableName) + { + return new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $this->databaseConnection->getMetaData()->getTableColumns($tableName), $this->databaseConnection->getMetaData()->getTablePrimaryKeys($tableName)); + } + + /** + * Returns a list of table names for the database + * + * @return Array + */ + public function getTableNames() + { + return $this->databaseConnection->getMetaData()->getTableNames(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php new file mode 100644 index 00000000..14ec2c3e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php @@ -0,0 +1,231 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/QueryTable.php'; +require_once 'PHPUnit/Extensions/Database/DB/IDatabaseConnection.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData.php'; +require_once 'PHPUnit/Extensions/Database/DB/ResultSetTable.php'; +require_once 'PHPUnit/Extensions/Database/DB/DataSet.php'; +require_once 'PHPUnit/Extensions/Database/DB/FilteredDataSet.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for communicating with a database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection implements PHPUnit_Extensions_Database_DB_IDatabaseConnection +{ + /** + * @var PDO + */ + protected $connection; + + /** + * @var string + */ + protected $schema; + + /** + * The metadata object used to retrieve table meta data from the database. + * + * @var PHPUnit_Extensions_Database_DB_IMetaData + */ + protected $metaData; + + /** + * Creates a new database connection + * + * @param PDO $connection + * @param string $schema - The name of the database schema you will be testing against. + */ + public function __construct(PDO $connection, $schema) + { + $this->connection = $connection; + $this->metaData = PHPUnit_Extensions_Database_DB_MetaData::createMetaData($connection, $schema); + $this->schema = $schema; + + $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + + /** + * Close this connection. + */ + public function close() + { + unset($this->connection); + } + + /** + * Returns a database metadata object that can be used to retrieve table + * meta data from the database. + * + * @return PHPUnit_Extensions_Database_DB_IMetaData + */ + public function getMetaData() + { + return $this->metaData; + } + + /** + * Returns the schema for the connection. + * + * @return string + */ + public function getSchema() + { + return $this->schema; + } + + /** + * Creates a dataset containing the specified table names. If no table + * names are specified then it will created a dataset over the entire + * database. + * + * @param array $tableNames + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + * @todo Implement the filtered data set. + */ + public function createDataSet(Array $tableNames = NULL) + { + if (empty($tableNames)) { + return new PHPUnit_Extensions_Database_DB_DataSet($this); + } else { + return new PHPUnit_Extensions_Database_DB_FilteredDataSet($this, $tableNames); + } + } + + /** + * Creates a table with the result of the specified SQL statement. + * + * @param string $resultName + * @param string $sql + * @return PHPUnit_Extensions_Database_DB_Table + */ + public function createQueryTable($resultName, $sql) + { + return new PHPUnit_Extensions_Database_DataSet_QueryTable($resultName, $sql, $this); + } + + /** + * Returns this connection database configuration + * + * @return PHPUnit_Extensions_Database_Database_DatabaseConfig + */ + public function getConfig() + { + + } + + /** + * Returns a PDO Connection + * + * @return PDO + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Returns the number of rows in the given table. You can specify an + * optional where clause to return a subset of the table. + * + * @param string $tableName + * @param string $whereClause + * @param int + */ + public function getRowCount($tableName, $whereClause = NULL) + { + $query = "SELECT COUNT(*) FROM ".$this->quoteSchemaObject($tableName); + + if (isset($whereClause)) { + $query .= " WHERE {$whereClause}"; + } + } + + /** + * Returns a quoted schema object. (table name, column name, etc) + * + * @param string $object + * @return string + */ + public function quoteSchemaObject($object) + { + return $this->getMetaData()->quoteSchemaObject($object); + } + + /** + * Returns the command used to truncate a table. + * + * @return string + */ + public function getTruncateCommand() + { + return $this->getMetaData()->getTruncateCommand(); + } + + /** + * Returns true if the connection allows cascading + * + * @return bool + */ + public function allowsCascading() + { + return $this->getMetaData()->allowsCascading(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/FilteredDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/FilteredDataSet.php new file mode 100644 index 00000000..3e608f61 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/FilteredDataSet.php @@ -0,0 +1,94 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DB/DataSet.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides access to a database instance as a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_FilteredDataSet extends PHPUnit_Extensions_Database_DB_DataSet +{ + + /** + * @var Array + */ + protected $tableNames; + + /** + * Creates a new dataset using the given database connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection + */ + public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection, Array $tableNames) + { + parent::__construct($databaseConnection); + $this->tableNames = $tableNames; + } + + /** + * Returns a list of table names for the database + * + * @return Array + */ + public function getTableNames() + { + return $this->tableNames; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/IDatabaseConnection.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/IDatabaseConnection.php new file mode 100644 index 00000000..1a243bd9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/IDatabaseConnection.php @@ -0,0 +1,144 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for communicating with a database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_DB_IDatabaseConnection +{ + + /** + * Close this connection. + */ + public function close(); + + /** + * Creates a dataset containing the specified table names. If no table + * names are specified then it will created a dataset over the entire + * database. + * + * @param array $tableNames + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + public function createDataSet(Array $tableNames = NULL); + + /** + * Creates a table with the result of the specified SQL statement. + * + * @param string $resultName + * @param string $sql + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function createQueryTable($resultName, $sql); + + /** + * Returns a PDO Connection + * + * @return PDO + */ + public function getConnection(); + + /** + * Returns a database metadata object that can be used to retrieve table + * meta data from the database. + * + * @return PHPUnit_Extensions_Database_DB_IMetaData + */ + public function getMetaData(); + + /** + * Returns the number of rows in the given table. You can specify an + * optional where clause to return a subset of the table. + * + * @param string $tableName + * @param string $whereClause + * @param int + */ + public function getRowCount($tableName, $whereClause = NULL); + + /** + * Returns the schema for the connection. + * + * @return string + */ + public function getSchema(); + + /** + * Returns a quoted schema object. (table name, column name, etc) + * + * @param string $object + * @return string + */ + public function quoteSchemaObject($object); + + /** + * Returns the command used to truncate a table. + * + * @return string + */ + public function getTruncateCommand(); + + /** + * Returns true if the connection allows cascading + * + * @return bool + */ + public function allowsCascading(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/IMetaData.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/IMetaData.php new file mode 100644 index 00000000..fa93728d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/IMetaData.php @@ -0,0 +1,113 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for retreiving metadata from a database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_DB_IMetaData +{ + + /** + * Returns an array containing the names of all the tables in the database. + * + * @return array + */ + public function getTableNames(); + + /** + * Returns an array containing the names of all the columns in the + * $tableName table, + * + * @param string $tableName + * @return array + */ + public function getTableColumns($tableName); + + /** + * Returns an array containing the names of all the primary key columns in + * the $tableName table. + * + * @param string $tableName + * @return array + */ + public function getTablePrimaryKeys($tableName); + + /** + * Returns the name of the default schema. + * + * @return string + */ + public function getSchema(); + + /** + * Returns a quoted schema object. (table name, column name, etc) + * + * @param string $object + * @return string + */ + public function quoteSchemaObject($object); + + /** + * Returns true if the rdbms allows cascading + * + * @return bool + */ + public function allowsCascading(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData.php new file mode 100644 index 00000000..da38ae80 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData.php @@ -0,0 +1,244 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DB/IMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic constructor for all meta data classes and a factory for + * generating the appropriate meta data class. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_DB_MetaData implements PHPUnit_Extensions_Database_DB_IMetaData +{ + protected static $metaDataClassMap = array( + 'pgsql' => 'PHPUnit_Extensions_Database_DB_MetaData_PgSQL', + 'mysql' => 'PHPUnit_Extensions_Database_DB_MetaData_MySQL', + 'oci' => 'PHPUnit_Extensions_Database_DB_MetaData_Oci', + 'sqlite' => 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite' + ); + + /** + * The PDO connection used to retreive database meta data + * + * @var PDO + */ + protected $pdo; + + /** + * The default schema name for the meta data object. + * + * @var string + */ + protected $schema; + + /** + * The character used to quote schema objects. + */ + protected $schemaObjectQuoteChar = '"'; + + /** + * The command used to perform a TRUNCATE operation. + */ + protected $truncateCommand = 'TRUNCATE'; + + /** + * Creates a new database meta data object using the given pdo connection + * and schema name. + * + * @param PDO $pdo + * @param string $schema + */ + public final function __construct(PDO $pdo, $schema) + { + $this->pdo = $pdo; + $this->schema = $schema; + } + + /** + * Creates a meta data object based on the driver of given $pdo object and + * $schema name. + * + * @param PDO $pdo + * @param string $schema + * @return PHPUnit_Extensions_Database_DB_MetaData + */ + public static function createMetaData(PDO $pdo, $schema) + { + $driverName = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); + if (isset(self::$metaDataClassMap[$driverName])) { + $className = self::$metaDataClassMap[$driverName]; + + if ($className instanceof ReflectionClass) { + return $className->newInstance($pdo, $schema); + } else { + return self::registerClassWithDriver($className, $driverName)->newInstance($pdo, $schema); + } + } else { + throw new Exception("Could not find a meta data driver for {$driverName} pdo driver."); + } + } + + /** + * Validates and registers the given $className with the given $pdoDriver. + * It should be noted that this function will not attempt to include / + * require the file. The $pdoDriver can be determined by the value of the + * PDO::ATTR_DRIVER_NAME attribute for a pdo object. + * + * A reflection of the $className is returned. + * + * @param string $className + * @param string $pdoDriver + * @return ReflectionClass + */ + public static function registerClassWithDriver($className, $pdoDriver) + { + if (!class_exists($className)) { + throw new Exception("Specified class for {$pdoDriver} driver ({$className}) does not exist."); + } + + $reflection = new ReflectionClass($className); + if ($reflection->isSubclassOf('PHPUnit_Extensions_Database_DB_MetaData')) { + return self::$metaDataClassMap[$pdoDriver] = $reflection; + } else { + throw new Exception("Specified class for {$pdoDriver} driver ({$className}) does not extend PHPUnit_Extensions_Database_DB_MetaData."); + } + } + + /** + * Returns the schema for the connection. + * + * @return string + */ + public function getSchema() + { + return $this->schema; + } + + /** + * Returns a quoted schema object. (table name, column name, etc) + * + * @param string $object + * @return string + */ + public function quoteSchemaObject($object) + { + $parts = explode('.', $object); + $quotedParts = array(); + + foreach ($parts as $part) { + $quotedParts[] = $this->schemaObjectQuoteChar . + str_replace($this->schemaObjectQuoteChar, $this->schemaObjectQuoteChar.$this->schemaObjectQuoteChar, $part). + $this->schemaObjectQuoteChar; + } + + return implode('.', $quotedParts); + } + + /** + * Seperates the schema and the table from a fully qualified table name. + * + * Returns an associative array containing the 'schema' and the 'table'. + * + * @param string $fullTableName + * @return array + */ + public function splitTableName($fullTableName) + { + if (($dot = strpos($fullTableName, '.')) !== FALSE) { + return array( + 'schema' => substr($fullTableName, 0, $dot), + 'table' => substr($fullTableName, $dot + 1) + ); + } else { + return array( + 'schema' => NULL, + 'table' => $fullTableName + ); + } + } + + /** + * Returns the command for the database to truncate a table. + * + * @return string + */ + public function getTruncateCommand() + { + return $this->truncateCommand; + } + + /** + * Returns true if the rdbms allows cascading + * + * @return bool + */ + public function allowsCascading() + { + return FALSE; + } +} + +/** + * I am not sure why these requires can't go above the class, but when they do + * the classes can't find the PHPUnit_Extensions_Database_DB_MetaData + * class. + */ +require_once 'PHPUnit/Extensions/Database/DB/MetaData/Sqlite.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData/MySQL.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData/PgSQL.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php new file mode 100644 index 00000000..14b5932e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php @@ -0,0 +1,183 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides functionality to retrieve meta data from a database with information_schema support. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_MetaData_InformationSchema extends PHPUnit_Extensions_Database_DB_MetaData +{ + + protected $columns = array(); + + protected $keys = array(); + + /** + * Returns an array containing the names of all the tables in the database. + * + * @return array + */ + public function getTableNames() + { + $query = " + SELECT DISTINCT + TABLE_NAME + FROM INFORMATION_SCHEMA.TABLES + WHERE + TABLE_TYPE='BASE TABLE' AND + TABLE_SCHEMA = ? + ORDER BY TABLE_NAME + "; + + $statement = $this->pdo->prepare($query); + $statement->execute(array($this->getSchema())); + + $tableNames = array(); + while ($tableName = $statement->fetchColumn(0)) { + $tableNames[] = $tableName; + } + + return $tableNames; + } + + /** + * Returns an array containing the names of all the columns in the + * $tableName table, + * + * @param string $tableName + * @return array + */ + public function getTableColumns($tableName) + { + if (!isset($this->columns[$tableName])) { + $this->loadColumnInfo($tableName); + } + + return $this->columns[$tableName]; + } + + /** + * Returns an array containing the names of all the primary key columns in + * the $tableName table. + * + * @param string $tableName + * @return array + */ + public function getTablePrimaryKeys($tableName) + { + if (!isset($this->keys[$tableName])) { + $this->loadColumnInfo($tableName); + } + + return $this->keys[$tableName]; + } + + /** + * Loads column info from a sqlite database. + * + * @param string $tableName + */ + protected function loadColumnInfo($tableName) + { + $this->columns[$tableName] = array(); + $this->keys[$tableName] = array(); + + $columnQuery = " + SELECT DISTINCT + COLUMN_NAME + FROM INFORMATION_SCHEMA.COLUMNS + WHERE + TABLE_NAME = ? AND + TABLE_SCHEMA = ? + ORDER BY ORDINAL_POSITION + "; + + $columnStatement = $this->pdo->prepare($columnQuery); + $columnStatement->execute(array($tableName, $this->getSchema())); + + while ($columName = $columnStatement->fetchColumn(0)) { + $this->columns[$tableName][] = $columName; + } + + $keyQuery = " + SELECT + KCU.COLUMN_NAME + FROM + INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC, + INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU + WHERE + TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND + TC.TABLE_NAME = KCU.TABLE_NAME AND + TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA AND + TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND + TC.TABLE_NAME = ? AND + TC.TABLE_SCHEMA = ? + ORDER BY + KCU.ORDINAL_POSITION ASC + "; + + $keyStatement = $this->pdo->prepare($keyQuery); + $keyStatement->execute(array($tableName, $this->getSchema())); + + while ($columName = $keyStatement->fetchColumn(0)) { + $this->keys[$tableName][] = $columName; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/MySQL.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/MySQL.php new file mode 100644 index 00000000..07722061 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/MySQL.php @@ -0,0 +1,136 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides functionality to retrieve meta data from a database with information_schema support. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_MetaData_MySQL extends PHPUnit_Extensions_Database_DB_MetaData +{ + protected $schemaObjectQuoteChar = '`'; + + protected $columns = array(); + + protected $keys = array(); + + /** + * Returns an array containing the names of all the tables in the database. + * + * @return array + */ + public function getTableNames() + { + $query = 'SHOW TABLES'; + $statement = $this->pdo->prepare($query); + $statement->execute(); + + $tableNames = array(); + while (($tableName = $statement->fetchColumn(0))) { + $tableNames[] = $tableName; + } + + return $tableNames; + } + + /** + * Returns an array containing the names of all the columns in the + * $tableName table, + * + * @param string $tableName + * @return array + */ + public function getTableColumns($tableName) + { + $query = 'SHOW COLUMNS FROM ' . $this->quoteSchemaObject($tableName); + $statement = $this->pdo->prepare($query); + $statement->execute(); + + $columnNames = array(); + while (($columnName = $statement->fetchColumn(0))) { + $columnNames[] = $columnName; + } + + return $columnNames; + } + + /** + * Returns an array containing the names of all the primary key columns in + * the $tableName table. + * + * @param string $tableName + * @return array + */ + public function getTablePrimaryKeys($tableName) + { + $query = 'SHOW INDEX FROM ' . $this->quoteSchemaObject($tableName); + $statement = $this->pdo->prepare($query); + $statement->execute(); + $statement->setFetchMode(PDO::FETCH_ASSOC); + + $columnNames = array(); + while (($column = $statement->fetch())) { + if ($column['Key_name'] == 'PRIMARY') { + $columnNames[] = $column['Column_name']; + } + } + + return $columnNames; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/Oci.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/Oci.php new file mode 100644 index 00000000..b9a40c60 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/Oci.php @@ -0,0 +1,180 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Trond Hansen + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.3 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides functionality to retrieve meta data from an Oracle database. + * + * @category Testing + * @package PHPUnit + * @author Trond Hansen + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.3 + */ +class PHPUnit_Extensions_Database_DB_MetaData_Oci extends PHPUnit_Extensions_Database_DB_MetaData +{ + /** + * No character used to quote schema objects. + */ + protected $schemaObjectQuoteChar = ''; + + /** + * The command used to perform a TRUNCATE operation. + */ + protected $truncateCommand = 'TRUNCATE TABLE'; + + protected $columns = array(); + protected $keys = array(); + + /** + * Returns an array containing the names of all the tables in the database. + * + * @return array + */ + public function getTableNames() + { + $tableNames = array(); + + $query = "SELECT table_name + FROM cat + WHERE table_type='TABLE' + ORDER BY table_name"; + + $result = $this->pdo->query($query); + + while ($tableName = $result->fetchColumn(0)) { + $tableNames[] = $tableName; + } + + return $tableNames; + } + + /** + * Returns an array containing the names of all the columns in the + * $tableName table, + * + * @param string $tableName + * @return array + */ + public function getTableColumns($tableName) + { + if (!isset($this->columns[$tableName])) { + $this->loadColumnInfo($tableName); + } + + return $this->columns[$tableName]; + } + + /** + * Returns an array containing the names of all the primary key columns in + * the $tableName table. + * + * @param string $tableName + * @return array + */ + public function getTablePrimaryKeys($tableName) + { + if (!isset($this->keys[$tableName])) { + $this->loadColumnInfo($tableName); + } + + return $this->keys[$tableName]; + } + + /** + * Loads column info from a oracle database. + * + * @param string $tableName + */ + protected function loadColumnInfo($tableName) + { + $ownerQuery = ''; + $conOwnerQuery = ''; + $tableParts = $this->splitTableName($tableName); + + $this->columns[$tableName] = array(); + $this->keys[$tableName] = array(); + + if (!empty($tableParts['schema'])) + { + $ownerQuery = " AND OWNER = '{$tableParts['schema']}'"; + $conOwnerQuery = " AND a.owner = '{$tableParts['schema']}'"; + } + + $query = "SELECT DISTINCT COLUMN_NAME + FROM USER_TAB_COLUMNS + WHERE TABLE_NAME='".$tableParts['table']."' + $ownerQuery + ORDER BY COLUMN_NAME"; + + $result = $this->pdo->query($query); + + while ($columnName = $result->fetchColumn(0)) { + $this->columns[$tableName][] = $columnName; + } + + $keyQuery = "SELECT b.column_name + FROM user_constraints a, user_cons_columns b + WHERE a.constraint_type='P' + AND a.constraint_name=b.constraint_name + $conOwnerQuery + AND a.table_name = '".$tableParts['table']."' "; + + $result = $this->pdo->query($keyQuery); + + while ($columnName = $result->fetchColumn(0)) { + $this->keys[$tableName][] = $columnName; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/PgSQL.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/PgSQL.php new file mode 100644 index 00000000..a71e0264 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/PgSQL.php @@ -0,0 +1,163 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides functionality to retrieve meta data from a postgres database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_MetaData_PgSQL extends PHPUnit_Extensions_Database_DB_MetaData_InformationSchema +{ + + /** + * Returns an array containing the names of all the tables in the database. + * + * @return array + */ + public function getTableNames() + { + $query = " + SELECT DISTINCT + TABLE_NAME + FROM INFORMATION_SCHEMA.TABLES + WHERE + TABLE_TYPE='BASE TABLE' AND + TABLE_CATALOG = ? AND + TABLE_SCHEMA = 'public' + ORDER BY TABLE_NAME + "; + + $statement = $this->pdo->prepare($query); + $statement->execute(array($this->getSchema())); + + $tableNames = array(); + while ($tableName = $statement->fetchColumn(0)) { + $tableNames[] = $tableName; + } + + return $tableNames; + } + + /** + * Loads column info from a sqlite database. + * + * @param string $tableName + */ + protected function loadColumnInfo($tableName) + { + $this->columns[$tableName] = array(); + $this->keys[$tableName] = array(); + + $columnQuery = " + SELECT DISTINCT + COLUMN_NAME, + ORDINAL_POSITION + FROM INFORMATION_SCHEMA.COLUMNS + WHERE + TABLE_NAME = ? AND + TABLE_SCHEMA = 'public' AND + TABLE_CATALOG = ? + ORDER BY ORDINAL_POSITION + "; + + $columnStatement = $this->pdo->prepare($columnQuery); + $columnStatement->execute(array($tableName, $this->getSchema())); + + while ($columName = $columnStatement->fetchColumn(0)) { + $this->columns[$tableName][] = $columName; + } + + $keyQuery = " + SELECT + KCU.COLUMN_NAME, + KCU.ORDINAL_POSITION + FROM + INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC, + INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU + WHERE + TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND + TC.TABLE_NAME = KCU.TABLE_NAME AND + TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA AND + TC.TABLE_CATALOG = KCU.TABLE_CATALOG AND + TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND + TC.TABLE_NAME = ? AND + TC.TABLE_SCHEMA = 'public' AND + TC.TABLE_CATALOG = ? + ORDER BY + KCU.ORDINAL_POSITION ASC + "; + + $keyStatement = $this->pdo->prepare($keyQuery); + $keyStatement->execute(array($tableName, $this->getSchema())); + + while ($columName = $keyStatement->fetchColumn(0)) { + $this->keys[$tableName][] = $columName; + } + } + + /** + * Returns true if the rdbms allows cascading + * + * @return bool + */ + public function allowsCascading() + { + return TRUE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/Sqlite.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/Sqlite.php new file mode 100644 index 00000000..4ce0f8d6 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/MetaData/Sqlite.php @@ -0,0 +1,151 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DB/MetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides functionality to retrieve meta data from a sqlite database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_MetaData_Sqlite extends PHPUnit_Extensions_Database_DB_MetaData +{ + + protected $columns = array(); + + protected $keys = array(); + + protected $truncateCommand = 'DELETE FROM'; + /** + * Returns an array containing the names of all the tables in the database. + * + * @return array + */ + public function getTableNames() + { + $query = " + SELECT name + FROM sqlite_master + WHERE + type='table' AND + name <> 'sqlite_sequence' + ORDER BY name + "; + + $result = $this->pdo->query($query); + + while ($tableName = $result->fetchColumn(0)) { + $tableNames[] = $tableName; + } + + return $tableNames; + } + + /** + * Returns an array containing the names of all the columns in the + * $tableName table, + * + * @param string $tableName + * @return array + */ + public function getTableColumns($tableName) + { + if (!isset($this->columns[$tableName])) { + $this->loadColumnInfo($tableName); + } + + return $this->columns[$tableName]; + } + + /** + * Returns an array containing the names of all the primary key columns in + * the $tableName table. + * + * @param string $tableName + * @return array + */ + public function getTablePrimaryKeys($tableName) + { + if (!isset($this->keys[$tableName])) { + $this->loadColumnInfo($tableName); + } + + return $this->keys[$tableName]; + } + + /** + * Loads column info from a sqlite database. + * + * @param string $tableName + */ + protected function loadColumnInfo($tableName) + { + $query = "PRAGMA table_info('{$tableName}')"; + $statement = $this->pdo->query($query); + + /* @var $statement PDOStatement */ + $this->columns[$tableName] = array(); + $this->keys[$tableName] = array(); + while ($columnData = $statement->fetch(PDO::FETCH_NUM)) { + $this->columns[$tableName][] = $columnData[1]; + + if ($columnData[5] == 1) { + $this->keys[$tableName][] = $columnData[1]; + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/ResultSetTable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/ResultSetTable.php new file mode 100644 index 00000000..a534d005 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/ResultSetTable.php @@ -0,0 +1,91 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTable.php'; + +/** + * Provides the functionality to represent a database result set as a DBUnit + * table. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @deprecated The PHPUnit_Extension_Database_DataSet_QueryTable should be used instead + * @see PHPUnit_Extension_Database_DataSet_QueryTable + * @see PHPUnit_Extension_Database_DataSet_QueryDataSet + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_ResultSetTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable +{ + + /** + * Creates a new result set table. + * + * @param string $tableName + * @param PDOStatement $pdoStatement + */ + public function __construct($tableName, PDOStatement $pdoStatement) + { + $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC); + + if (count($this->data)) { + $columns = array_keys($this->data[0]); + } else { + $columns = array(); + } + + $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns)); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/Table.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/Table.php new file mode 100644 index 00000000..85a27816 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/Table.php @@ -0,0 +1,83 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides the functionality to represent a database table. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_Table extends PHPUnit_Extensions_Database_DataSet_AbstractTable +{ + + /** + * Creates a new database table object. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) + { + $this->setTableMetaData($tableMetaData); + + $pdoStatement = $databaseConnection->getConnection()->prepare(PHPUnit_Extensions_Database_DB_DataSet::buildTableSelect($tableMetaData, $databaseConnection)); + $pdoStatement->execute(); + $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/TableIterator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/TableIterator.php new file mode 100644 index 00000000..50984aed --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/TableIterator.php @@ -0,0 +1,175 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/ITableIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides iterative access to tables from a database instance. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_TableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator +{ + + /** + * An array of tablenames. + * + * @var Array + */ + protected $tableNames; + + /** + * If this property is true then the tables will be iterated in reverse + * order. + * + * @var bool + */ + protected $reverse; + + /** + * The database dataset that this iterator iterates over. + * + * @var PHPUnit_Extensions_Database_DB_DataSet + */ + protected $dataSet; + + public function __construct($tableNames, PHPUnit_Extensions_Database_DB_DataSet $dataSet, $reverse = FALSE) + { + $this->tableNames = $tableNames; + $this->dataSet = $dataSet; + $this->reverse = $reverse; + + $this->rewind(); + } + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function getTable() + { + return $this->current(); + } + + /** + * Returns the current table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData() + { + return $this->current()->getTableMetaData(); + } + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function current() + { + $tableName = current($this->tableNames); + return $this->dataSet->getTable($tableName); + } + + /** + * Returns the name of the current table. + * + * @return string + */ + public function key() + { + return $this->current()->getTableMetaData()->getTableName(); + } + + /** + * advances to the next element. + * + */ + public function next() + { + if ($this->reverse) { + prev($this->tableNames); + } else { + next($this->tableNames); + } + } + + /** + * Rewinds to the first element + */ + public function rewind() + { + if ($this->reverse) { + end($this->tableNames); + } else { + reset($this->tableNames); + } + } + + /** + * Returns true if the current index is valid + * + * @return bool + */ + public function valid() + { + return (current($this->tableNames) !== FALSE); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/TableMetaData.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/TableMetaData.php new file mode 100644 index 00000000..91fb79e7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DB/TableMetaData.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This class loads a table metadata object with database metadata. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DB_TableMetaData extends PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData +{ + + public function __construct($tableName, PHPUnit_Extensions_Database_DB_IMetaData $databaseMetaData) + { + $this->tableName = $tableName; + $this->columns = $databaseMetaData->getTableColumns($tableName); + $this->primaryKeys = $databaseMetaData->getTablePrimaryKeys($tableName); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php new file mode 100644 index 00000000..ddbcda35 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php @@ -0,0 +1,177 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/IDataSet.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Implements the basic functionality of data sets. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_DataSet_AbstractDataSet implements PHPUnit_Extensions_Database_DataSet_IDataSet +{ + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected abstract function createIterator($reverse = FALSE); + + /** + * Returns an array of table names contained in the dataset. + * + * @return array + */ + public function getTableNames() + { + $tableNames = array(); + + foreach ($this->getIterator() as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + $tableNames[] = $table->getTableMetaData()->getTableName(); + } + + return $tableNames; + } + + /** + * Returns a table meta data object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData($tableName) + { + return $this->getTable($tableName)->getTableMetaData(); + } + + /** + * Returns a table object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function getTable($tableName) + { + foreach ($this->getIterator() as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + if ($table->getTableMetaData()->getTableName() == $tableName) { + return $table; + } + } + } + + /** + * Returns an iterator for all table objects in the given dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + public function getIterator() + { + return $this->createIterator(); + } + + /** + * Returns a reverse iterator for all table objects in the given dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + public function getReverseIterator() + { + return $this->createIterator(TRUE); + } + + /** + * Asserts that the given data set matches this data set. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_IDataSet $other) + { + $thisTableNames = $this->getTableNames(); + $otherTableNames = $other->getTableNames(); + + sort($thisTableNames); + sort($otherTableNames); + + if ($thisTableNames != $otherTableNames) { + throw new Exception("Expected following tables: " . implode(', ', $thisTableNames) . "; has columns: " . implode(', ', $otherTableNames)); + } + + foreach ($thisTableNames as $tableName) { + $this->getTable($tableName)->assertEquals($other->getTable($tableName)); + } + + return TRUE; + } + + public function __toString() + { + $iterator = $this->getIterator(); + + $dataSetString = ''; + foreach ($iterator as $table) { + $dataSetString .= $table->__toString(); + } + + return $dataSetString; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractTable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractTable.php new file mode 100644 index 00000000..724889cb --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractTable.php @@ -0,0 +1,217 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/ITable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic functionality for dbunit tables + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_AbstractTable implements PHPUnit_Extensions_Database_DataSet_ITable +{ + + /** + * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + protected $tableMetaData; + + /** + * A 2-dimensional array containing the data for this table. + * + * @var array + */ + protected $data; + + /** + * Sets the metadata for this table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData + * @deprecated + */ + protected function setTableMetaData(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData) + { + $this->tableMetaData = $tableMetaData; + } + + /** + * Returns the table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData() + { + return $this->tableMetaData; + } + + /** + * Returns the number of rows in this table. + * + * @return int + */ + public function getRowCount() + { + return count($this->data); + } + + /** + * Returns the value for the given column on the given row. + * + * @param int $row + * @param int $column + * @todo reorganize this function to throw the exception first. + */ + public function getValue($row, $column) + { + if (isset($this->data[$row][$column])) { + return (string)$this->data[$row][$column]; + } else { + if (!in_array($column, $this->getTableMetaData()->getColumns()) || $this->getRowCount() <= $row) { + throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}"); + } else { + return NULL; + } + } + } + + /** + * Returns the an associative array keyed by columns for the given row. + * + * @param int $row + * @return array + */ + public function getRow($row) + { + if (isset($this->data[$row])) { + return $this->data[$row]; + } else { + if ($this->getRowCount() <= $row) { + throw new InvalidArgumentException("The given row ({$row}) does not exist in table {$this->getTableMetaData()->getTableName()}"); + } else { + return NULL; + } + } + } + + /** + * Asserts that the given table matches this table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_ITable $other) + { + $thisMetaData = $this->getTableMetaData(); + $otherMetaData = $other->getTableMetaData(); + + $thisMetaData->assertEquals($otherMetaData); + + if ($this->getRowCount() != $other->getRowCount()) { + throw new Exception("Expected row count of {$this->getRowCount()}, has a row count of {$other->getRowCount()}"); + } + + $columns = $thisMetaData->getColumns(); + for ($i = 0; $i < $this->getRowCount(); $i++) { + foreach ($columns as $columnName) { + if ($this->getValue($i, $columnName) != $other->getValue($i, $columnName)) { + throw new Exception("Expected value of {$this->getValue($i, $columnName)} for row {$i} column {$columnName}, has a value of {$other->getValue($i, $columnName)}"); + } + } + } + + return TRUE; + } + + public function __toString() + { + $columns = $this->getTableMetaData()->getColumns(); + + $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n"; + $lineLength = strlen($lineSeperator) - 1; + + $tableString = $lineSeperator; + $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n"; + $tableString .= $lineSeperator; + $tableString .= $this->rowToString($columns); + $tableString .= $lineSeperator; + + for ($i = 0; $i < $this->getRowCount(); $i++) { + $values = array(); + foreach ($columns as $columnName) { + $values[] = $this->getValue($i, $columnName); + } + + $tableString .= $this->rowToString($values); + $tableString .= $lineSeperator; + } + + return "\n" . $tableString . "\n"; + } + + protected function rowToString(Array $row) + { + $rowString = ''; + foreach ($row as $value) { + if (is_null($value)) { + $value = 'NULL'; + } + $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' '; + } + + return $rowString . "|\n"; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php new file mode 100644 index 00000000..059c053f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php @@ -0,0 +1,135 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/ITableMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides basic functionality for table meta data. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData implements PHPUnit_Extensions_Database_DataSet_ITableMetaData +{ + + /** + * The names of all columns in the table. + * + * @var Array + */ + protected $columns; + + /** + * The names of all the primary keys in the table. + * + * @var Array + */ + protected $primaryKeys; + + /** + * @var string + */ + protected $tableName; + + /** + * Returns the names of the columns in the table. + * + * @return array + */ + public function getColumns() + { + return $this->columns; + } + + /** + * Returns the names of the primary key columns in the table. + * + * @return array + */ + public function getPrimaryKeys() + { + return $this->primaryKeys; + } + + /** + * Returns the name of the table. + * + * @return string + */ + public function getTableName() + { + return $this->tableName; + } + + /** + * Asserts that the given tableMetaData matches this tableMetaData. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other) + { + if ($this->getTableName() != $other->getTableName()) { + throw new Exception("Expected table name of {$this->getTableName()}, has a name of {$other->getTableName()}"); + } + + if ($this->getColumns() != $other->getColumns()) { + throw new Exception("Expected following columns: " . implode(', ', $this->getColumns()) . "; has columns: " . implode(', ', $other->getColumns())); + } + + return TRUE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php new file mode 100644 index 00000000..9aae6560 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php @@ -0,0 +1,149 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default implementation of a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + + /** + * @var array + */ + protected $tables; + + /** + * @var SimpleXmlElement + */ + protected $xmlFileContents; + + /** + * Creates a new dataset using the given tables. + * + * @param array $tables + */ + public function __construct($xmlFile) + { + if (!is_file($xmlFile)) { + throw new InvalidArgumentException("Could not find xml file: {$xmlFile}"); + } + $this->xmlFileContents = @simplexml_load_file($xmlFile); + + if ($this->xmlFileContents === FALSE) { + throw new InvalidArgumentException("File is not valid xml: {$xmlFile}"); + } + + $tableColumns = array(); + $tableValues = array(); + + $this->getTableInfo($tableColumns, $tableValues); + $this->createTables($tableColumns, $tableValues); + } + + /** + * Reads the simple xml object and creates the appropriate tables and meta + * data for this dataset. + */ + protected abstract function getTableInfo(Array &$tableColumns, Array &$tableValues); + + protected function createTables(Array &$tableColumns, Array &$tableValues) + { + foreach ($tableValues as $tableName => $values) { + $table = $this->getOrCreateTable($tableName, $tableColumns[$tableName]); + foreach ($values as $value) { + $table->addRow($value); + } + } + } + + /** + * Returns the table with the matching name. If the table does not exist + * an empty one is created. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + protected function getOrCreateTable($tableName, $tableColumns) + { + if (empty($this->tables[$tableName])) { + $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $tableColumns); + $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable($tableMetaData); + } + + return $this->tables[$tableName]; + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/CompositeDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/CompositeDataSet.php new file mode 100644 index 00000000..a0be9bc5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/CompositeDataSet.php @@ -0,0 +1,129 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Creates Composite Datasets + * + * Allows for creating datasets from multiple sources (csv, query, xml, etc.) + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Database_DataSet_CompositeDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + protected $dataSets = array(); + + /** + * Creates a new Composite dataset + * + * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet + * + * @param string $delimiter + * @param string $enclosure + * @param string $escape + */ + public function __construct(Array $dataSets) + { + foreach ($dataSets as $dataSet) + { + $this->addDataSet($dataSet); + } + } + + /** + * Adds a new data set to the composite. + * + * The dataset may not define tables that already exist in the composite. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet + */ + public function addDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + foreach ($dataSet->getTableNames() as $tableName) + { + if (in_array($tableName, $this->getTableNames())) + { + throw new InvalidArgumentException("DataSet contains a table that already exists: {$tableName}"); + } + } + + $this->dataSets[] = $dataSet; + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + $iterator = new AppendIterator(); + + $dataSets = $reverse ? array_reverse($this->dataSets) : $this->dataSets; + + foreach ($dataSets as $dataSet) + { + /* @var $dataSet PHPUnit_Extensions_Database_DataSet_IDataSet */ + $dataSetIterator = $reverse ? $dataSet->getReverseIterator() : $dataSet->getIterator(); + $iterator->append($dataSetIterator); + } + return $iterator; + } +} +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/CsvDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/CsvDataSet.php new file mode 100644 index 00000000..52e84f7f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/CsvDataSet.php @@ -0,0 +1,157 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTable.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Creates CsvDataSets. + * + * You can incrementally add CSV files as tables to your datasets + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Database_DataSet_CsvDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + protected $tables = array(); + protected $delimiter = ','; + protected $enclosure = '"'; + protected $escape = '"'; + + /** + * Creates a new CSV dataset + * + * You can pass in the parameters for how csv files will be read. + * + * @param string $delimiter + * @param string $enclosure + * @param string $escape + */ + public function __construct($delimiter = ',', $enclosure = '"', $escape = '"') + { + $this->delimiter = $delimiter; + $this->enclosure = $enclosure; + $this->escape = $escape; + } + + /** + * Adds a table to the dataset + * + * The table will be given the passed name. $csvFile should be a path to + * a valid csv file (based on the arguments passed to the constructor.) + * + * @param string $tableName + * @param string $csvFile + */ + public function addTable($tableName, $csvFile) + { + if (!is_file($csvFile)) { + throw new InvalidArgumentException("Could not find csv file: {$csvFile}"); + } + + if (!is_readable($csvFile)) { + throw new InvalidArgumentException("Could not read csv file: {$csvFile}"); + } + + $fh = fopen($csvFile, 'r'); + $columns = $this->getCsvRow($fh); + + if ($columns === FALSE) + { + throw new InvalidArgumentException("Could not determine the headers from the given file {$csvFile}"); + } + + $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns); + $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData); + + while (($row = $this->getCsvRow($fh)) !== FALSE) + { + $table->addRow(array_combine($columns, $row)); + } + + $this->tables[$tableName] = $table; + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); + } + + /** + * Returns a row from the csv file in an indexed array. + * + * @param resource $fh + * @return array + */ + protected function getCsvRow($fh) + { + if (version_compare(PHP_VERSION, '5.3.0', '>')) { + return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure, $this->escape); + } else { + return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DataSetFilter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DataSetFilter.php new file mode 100644 index 00000000..d8ef4e9d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DataSetFilter.php @@ -0,0 +1,207 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/TableFilter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A dataset decorator that allows filtering out tables and table columns from + * results. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_DataSetFilter extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + + /** + * The dataset being decorated. + * @var PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected $originalDataSet; + + /** + * The tables to exclude from the data set. + * @var Array + */ + protected $excludeTables = array(); + + /** + * The tables to exclude from the data set. + * @var Array + */ + protected $includeTables = array(); + + /** + * The columns to exclude from the data set. + * @var Array + */ + protected $excludeColumns = array(); + + /** + * The columns to exclude from the data set. + * @var Array + */ + protected $includeColumns = array(); + + /** + * Creates a new filtered data set. + * + * The $exclude tables should be an associative array using table names as + * the key and an array of column names to exclude for the value. If you + * would like to exclude a full table set the value of the table's entry + * to the special string '*'. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet + * @param Array $excludeTables @deprecated use set* methods instead. + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet, Array $excludeTables = array()) + { + $this->originalDataSet = $originalDataSet; + + $tables = array(); + foreach ($excludeTables as $tableName => $values) { + if (is_array($values)) { + $this->setExcludeColumnsForTable($tableName, $values); + } elseif ($values == '*') { + $tables[] = $tableName; + } else { + $this->setExcludeColumnsForTable($tableName, (array)$values); + } + } + + $this->addExcludeTables($tables); + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + $original_tables = $this->originalDataSet->getIterator($reverse); + $new_tables = array(); + + foreach ($original_tables as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + $tableName = $table->getTableMetaData()->getTableName(); + + if ((!in_array($tableName, $this->includeTables) && !empty($this->includeTables)) || + in_array($tableName, $this->excludeTables) + ) { + continue; + } elseif (!empty($this->excludeColumns[$tableName]) || !empty($this->includeColumns[$tableName])) { + $new_table = new PHPUnit_Extensions_Database_DataSet_TableFilter($table); + + if (!empty($this->includeColumns[$tableName])) { + $new_table->addIncludeColumns($this->includeColumns[$tableName]); + } + + if (!empty($this->excludeColumns[$tableName])) { + $new_table->addExcludeColumns($this->excludeColumns[$tableName]); + } + + $new_tables[] = $new_table; + } else { + $new_tables[] = $table; + } + } + + return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($new_tables); + } + + /** + * Adds tables to be included in the data set. + * @param array $tables + */ + public function addIncludeTables(Array $tables) + { + $this->includeTables = array_unique(array_merge($this->includeTables, $tables)); + } + + /** + * Adds tables to be included in the data set. + * @param array $tables + */ + public function addExcludeTables(Array $tables) + { + $this->excludeTables = array_unique(array_merge($this->excludeTables, $tables)); + } + + /** + * Adds columns to include in the data set for the given table. + * @param string $table + * @param Array $columns + */ + public function setIncludeColumnsForTable($table, Array $columns) + { + $this->includeColumns[$table] = $columns; + } + + /** + * Adds columns to include in the data set for the given table. + * @param string $table + * @param Array $columns + */ + public function setExcludeColumnsForTable($table, Array $columns) + { + $this->excludeColumns[$table] = $columns; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultDataSet.php new file mode 100644 index 00000000..f1cb3e45 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultDataSet.php @@ -0,0 +1,108 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default implementation of a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_DefaultDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + + /** + * An array of ITable objects. + * + * @var array + */ + protected $tables; + + /** + * Creates a new dataset using the given tables. + * + * @param array $tables + */ + public function __construct(Array $tables = array()) + { + $this->tables = $tables; + } + + /** + * Adds a table to the dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + public function addTable(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + $this->tables[] = $table; + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTable.php new file mode 100644 index 00000000..f98778fa --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTable.php @@ -0,0 +1,137 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides default table functionality. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_DefaultTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable +{ + + /** + * Creates a new table object using the given $tableMetaData + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData) + { + $this->setTableMetaData($tableMetaData); + $this->data = array(); + } + + /** + * Adds a row to the table with optional values. + * + * @param array $values + */ + public function addRow($values = array()) + { + $columnNames = $this->getTableMetaData()->getColumns(); + + if (function_exists('array_fill_keys')) { + $this->data[] = array_merge( + array_fill_keys($columnNames, NULL), + $values + ); + } else { + $this->data[] = array_merge( + array_combine( + $columnNames, + array_fill(0, count($columnNames), NULL) + ), + $values + ); + } + } + + /** + * Adds the rows in the passed table to the current table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + public function addTableRows(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + $tableColumns = $this->getTableMetaData()->getColumns(); + for ($i = 0; $i < $table->getRowCount(); $i++) { + $newRow = array(); + foreach ($tableColumns as $columnName) { + $newRow[$columnName] = $table->getValue($i, $columnName); + } + $this->addRow($newRow); + } + } + + /** + * Sets the specified column of the specied row to the specified value. + * + * @param int $row + * @param string $column + * @param mixed $value + */ + public function setValue($row, $column, $value) + { + if (isset($this->data[$row])) { + $this->data[$row][$column] = $value; + } else { + throw new InvalidArgumentException("The row given does not exist."); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php new file mode 100644 index 00000000..b200ea77 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php @@ -0,0 +1,172 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/ITableIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default table iterator + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_DefaultTableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator +{ + + /** + * An array of tables in the iterator. + * + * @var Array + */ + protected $tables; + + /** + * If this property is true then the tables will be iterated in reverse + * order. + * + * @var bool + */ + protected $reverse; + + /** + * Creates a new default table iterator object. + * + * @param array $tables + * @param bool $reverse + */ + public function __construct(Array $tables, $reverse = FALSE) + { + $this->tables = $tables; + $this->reverse = $reverse; + + $this->rewind(); + } + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function getTable() + { + $this->current(); + } + + /** + * Returns the current table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData() + { + $this->current()->getTableMetaData(); + } + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function current() + { + return current($this->tables); + } + + /** + * Returns the name of the current table. + * + * @return string + */ + public function key() + { + return $this->current()->getTableMetaData()->getTableName(); + } + + /** + * advances to the next element. + * + */ + public function next() + { + if ($this->reverse) { + prev($this->tables); + } else { + next($this->tables); + } + } + + /** + * Rewinds to the first element + */ + public function rewind() + { + if ($this->reverse) { + end($this->tables); + } else { + reset($this->tables); + } + } + + /** + * Returns true if the current index is valid + * + * @return bool + */ + public function valid() + { + return ($this->current() !== FALSE); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php new file mode 100644 index 00000000..da1b55a9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php @@ -0,0 +1,90 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default implementation of table meta data + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData +{ + + /** + * Creates a new default table meta data object. + * + * @param string $tableName + * @param array $columns + * @param array $primaryKeys + */ + public function __construct($tableName, Array $columns, Array $primaryKeys = array()) + { + $this->tableName = $tableName; + $this->columns = $columns; + $this->primaryKeys = array(); + + foreach ($primaryKeys as $columnName) { + if (!in_array($columnName, $this->columns)) { + throw new InvalidArgumentException("Primary key column passed that is not in the column list."); + } else { + $this->primaryKeys[] = $columnName; + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php new file mode 100644 index 00000000..7d62cce9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php @@ -0,0 +1,110 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default implementation of a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet +{ + + protected function getTableInfo(Array &$tableColumns, Array &$tableValues) + { + if ($this->xmlFileContents->getName() != 'dataset') { + throw new Exception("The root element of a flat xml data set file must be called "); + } + + foreach ($this->xmlFileContents->children() as $row) { + $tableName = $row->getName(); + + if (!isset($tableColumns[$tableName])) { + $tableColumns[$tableName] = array(); + $tableValues[$tableName] = array(); + } + + $values = array(); + foreach ($row->attributes() as $name => $value) { + if (!in_array($name, $tableColumns[$tableName])) { + $tableColumns[$tableName][] = $name; + } + + $values[$name] = $value; + } + + if (count($values)) { + $tableValues[$tableName][] = $values; + } + } + } + + public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) + { + $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml(); + $pers->setFileName($filename); + + try { + $pers->write($dataset); + } catch (RuntimeException $e) { + throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/IDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/IDataSet.php new file mode 100644 index 00000000..b3285a24 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/IDataSet.php @@ -0,0 +1,103 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for creating and reading data from data sets. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_DataSet_IDataSet extends IteratorAggregate +{ + + /** + * Returns an array of table names contained in the dataset. + * + * @return array + */ + public function getTableNames(); + + /** + * Returns a table meta data object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData($tableName); + + /** + * Returns a table object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function getTable($tableName); + + /** + * Returns a reverse iterator for all table objects in the given dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + public function getReverseIterator(); + + /** + * Asserts that the given data set matches this data set. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_IDataSet $other); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/IPersistable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/IPersistable.php new file mode 100644 index 00000000..675e73c3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/IPersistable.php @@ -0,0 +1,76 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/IDataSet.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * An interface for persisting datasets + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +interface PHPUnit_Extensions_Database_DataSet_IPersistable +{ + /** + * Writes the given dataset + * + * The previous dataset will be overwritten. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ISpec.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ISpec.php new file mode 100644 index 00000000..581819aa --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ISpec.php @@ -0,0 +1,68 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0CSV + */ + +/** + * Provides an interface for creating data sets from data set spec strings. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_DataSet_ISpec +{ + /** + * Creates a data set from a data set spec string. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + public function getDataSet($dataSetSpec); +} +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITable.php new file mode 100644 index 00000000..165ba407 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITable.php @@ -0,0 +1,103 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for creating and reading data from data sets. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_DataSet_ITable +{ + + /** + * Returns the table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData(); + + /** + * Returns the number of rows in this table. + * + * @return int + */ + public function getRowCount(); + + /** + * Returns the value for the given column on the given row. + * + * @param int $row + * @param int $column + */ + public function getValue($row, $column); + + /** + * Returns the an associative array keyed by columns for the given row. + * + * @param int $row + * @return array + */ + public function getRow($row); + + /** + * Asserts that the given table matches this table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_ITable $other); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITableIterator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITableIterator.php new file mode 100644 index 00000000..4d7d06d3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITableIterator.php @@ -0,0 +1,80 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for creating and reading data from data sets. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_DataSet_ITableIterator extends Iterator +{ + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function getTable(); + + /** + * Returns the current table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITableMetaData.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITableMetaData.php new file mode 100644 index 00000000..a072f214 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ITableMetaData.php @@ -0,0 +1,94 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface for returning table meta data. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_DataSet_ITableMetaData +{ + + /** + * Returns the names of the columns in the table. + * + * @return array + */ + public function getColumns(); + + /** + * Returns the names of the primary key columns in the table. + * + * @return array + */ + public function getPrimaryKeys(); + + /** + * Returns the name of the table. + * + * @return string + */ + public function getTableName(); + + /** + * Asserts that the given tableMetaData matches this tableMetaData. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php new file mode 100644 index 00000000..a56a97c2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php @@ -0,0 +1,136 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/IPersistable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + + +/** + * An abstract implementation of a dataset persistor. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_DataSet_Persistors_Abstract implements PHPUnit_Extensions_Database_DataSet_IPersistable +{ + public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + $this->saveDataSet($dataset); + } + + /** + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + protected function saveDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + $this->startDataSet($dataset); + foreach ($dataset as $table) + { + $this->saveTable($table); + } + $this->endDataSet($dataset); + } + + /** + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function saveTable(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + $this->startTable($table); + for ($i = 0; $i < $table->getRowCount(); $i++) + { + $this->row($table->getRow($i), $table); + } + $this->endTable($table); + } + + /** + * Override to save the start of a dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + abstract protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset); + + /** + * Override to save the end of a dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + abstract protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset); + + /** + * Override to save the start of a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + abstract protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table); + + /** + * Override to save the end of a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + abstract protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table); + + /** + * Override to save a table row. + * + * @param array $row + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + abstract protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table); +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Factory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Factory.php new file mode 100644 index 00000000..f13c13e4 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Factory.php @@ -0,0 +1,93 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Creates the appropriate Persistor based on a given type and spec. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Persistors_Factory +{ + /** + * Returns the persistor. + * + * @param string $type + * @param string $spec + * @return PHPUnit_Extensions_Database_DataSet_IPersistable + */ + public function getPersistorBySpec($type, $spec) + { + switch (strtolower($type)) { + case 'xml': + require_once ('PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php'); + $xmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml(); + $xmlPersistor->setFileName($spec); + return $xmlPersistor; + + case 'flatxml': + require_once ('PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php'); + $flatXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml(); + $flatXmlPersistor->setFileName($spec); + return $flatXmlPersistor; + + case 'yaml': + require_once ('PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php'); + $yamlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml(); + $yamlPersistor->setFileName($spec); + return $yamlPersistor; + + default: + throw new Exception("I don't know what you want from me. PERSISTOR"); + } + } +} +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php new file mode 100644 index 00000000..e140ef18 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php @@ -0,0 +1,156 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A Flat XML dataset persistor. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract +{ + /** + * @var string + */ + protected $filename; + + /** + * @var resource + */ + protected $fh; + + /** + * Sets the filename that this persistor will save to. + * + * @param string $filename + */ + public function setFileName($filename) + { + $this->filename = $filename; + } + + /** + * Override to save the start of a dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + $this->fh = fopen($this->filename, 'w'); + + if ($this->fh === FALSE) { + throw new PHPUnit_Framework_Exception("Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"); + } + + fwrite($this->fh, "\n"); + fwrite($this->fh, "\n"); + } + + /** + * Override to save the end of a dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + fwrite($this->fh, "\n"); + } + + /** + * Override to save the start of a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + if ($table->getRowCount() == 0) { + fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()} />\n"); + } + } + + /** + * Override to save the end of a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + //do nothing + } + + /** + * Override to save a table row. + * + * @param array $row + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) + { + fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()}\n"); + + foreach ($table->getTableMetaData()->getColumns() as $columnName) { + if (isset($row[$columnName])) { + fwrite($this->fh, "\t\t{$columnName}=\"". htmlspecialchars($row[$columnName]) . "\"\n"); + } + } + + fwrite($this->fh, "\t/>\n"); + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php new file mode 100644 index 00000000..ea09e42b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php @@ -0,0 +1,160 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A XML dataset persistor. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_Persistors_Xml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract +{ + /** + * @var string + */ + protected $filename; + + /** + * @var resource + */ + protected $fh; + + /** + * Sets the filename that this persistor will save to. + * + * @param string $filename + */ + public function setFileName($filename) + { + $this->filename = $filename; + } + + /** + * Override to save the start of a dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + $this->fh = fopen($this->filename, 'w'); + + if ($this->fh === FALSE) { + throw new PHPUnit_Framework_Exception("Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"); + } + + fwrite($this->fh, "\n"); + fwrite($this->fh, "\n"); + } + + /** + * Override to save the end of a dataset. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + fwrite($this->fh, "\n"); + } + + /** + * Override to save the start of a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + fwrite($this->fh, "\tgetTableMetaData()->getTableName()}\">\n"); + + foreach ($table->getTableMetaData()->getColumns() as $columnName) { + fwrite($this->fh, "\t\t{$columnName}\n"); + } + } + + /** + * Override to save the end of a table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) + { + fwrite($this->fh, "\t
\n"); + } + + /** + * Override to save a table row. + * + * @param array $row + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + */ + protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) + { + fwrite($this->fh, "\t\t\n"); + + foreach ($table->getTableMetaData()->getColumns() as $columnName) { + if (isset($row[$columnName])) { + fwrite($this->fh, "\t\t\t" . htmlspecialchars($row[$columnName]) . "\n"); + } else { + fwrite($this->fh, "\t\t\t\n"); + } + } + + fwrite($this->fh, "\t\t\n"); + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php new file mode 100644 index 00000000..64ab9f94 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php @@ -0,0 +1,108 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/IPersistable.php'; +require_once 'SymfonyComponents/YAML/sfYaml.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + + +/** + * A yaml dataset persistor + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_Persistors_Yaml implements PHPUnit_Extensions_Database_DataSet_IPersistable +{ + /** + * @var string + */ + protected $filename; + + /** + * Sets the filename that this persistor will save to. + * + * @param string $filename + */ + public function setFileName($filename) + { + $this->filename = $filename; + } + + /** + * Writes the dataset to a yaml file + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + */ + public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) + { + $phpArr = array(); + + foreach ($dataset as $table) + { + $tableName = $table->getTableMetaData()->getTableName(); + $phpArr[$tableName] = array(); + + for ($i = 0; $i < $table->getRowCount(); $i++) + { + $phpArr[$tableName][] = $table->getRow($i); + } + } + + file_put_contents($this->filename, sfYaml::dump($phpArr, 3)); + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/QueryDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/QueryDataSet.php new file mode 100644 index 00000000..5a86e67d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/QueryDataSet.php @@ -0,0 +1,141 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/QueryTable.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides access to a database instance as a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_QueryDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + + /** + * An array of ITable objects. + * + * @var array + */ + protected $tables = array(); + + /** + * The database connection this dataset is using. + * + * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected $databaseConnection; + + /** + * Creates a new dataset using the given database connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection + */ + public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) + { + $this->databaseConnection = $databaseConnection; + } + + public function addTable($tableName, $query = NULL) + { + if ($query === NULL) { + $query = 'SELECT * FROM ' . $tableName; + } + + $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_QueryTable($tableName, $query, $this->databaseConnection); + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DB_TableIterator + */ + protected function createIterator($reverse = FALSE) + { + return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); + } + + /** + * Returns a table object for the given table. + * + * @param string $tableName + * @return PHPUnit_Extensions_Database_DB_Table + */ + public function getTable($tableName) + { + if (!isset($this->tables[$tableName])) { + throw new InvalidArgumentException("$tableName is not a table in the current database."); + } + + return $this->tables[$tableName]; + } + + /** + * Returns a list of table names for the database + * + * @return Array + */ + public function getTableNames() + { + return array_keys($this->tables); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/QueryTable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/QueryTable.php new file mode 100644 index 00000000..5d854f69 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/QueryTable.php @@ -0,0 +1,171 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTable.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides the functionality to represent a database table. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_QueryTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable +{ + /** + * @var string + */ + protected $query; + + /** + * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected $databaseConnection; + + /** + * @var string + */ + protected $tableName; + + /** + * Creates a new database query table object. + * + * @param string $table_name + * @param string $query + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection + */ + public function __construct($tableName, $query, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) + { + $this->query = $query; + $this->databaseConnection = $databaseConnection; + $this->tableName = $tableName; + } + + /** + * Returns the table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData() + { + $this->createTableMetaData(); + return parent::getTableMetaData(); + } + + /** + * Returns the number of rows in this table. + * + * @return int + */ + public function getRowCount() + { + $this->loadData(); + return parent::getRowCount(); + } + + /** + * Returns the value for the given column on the given row. + * + * @param int $row + * @param int $column + */ + public function getValue($row, $column) + { + $this->loadData(); + return parent::getValue($row, $column); + } + + /** + * Returns the an associative array keyed by columns for the given row. + * + * @param int $row + * @return array + */ + public function getRow($row) + { + $this->loadData(); + return parent::getRow($row); + } + + /** + * Asserts that the given table matches this table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_ITable $other) + { + $this->loadData(); + return parent::assertEquals($other); + } + + protected function loadData() + { + if ($this->data === NULL) { + $pdoStatement = $this->databaseConnection->getConnection()->query($this->query); + $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC); + } + } + + protected function createTableMetaData() + { + if ($this->tableMetaData === NULL) + { + $this->loadData(); + $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, array_keys($this->data[0])); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementDataSet.php new file mode 100644 index 00000000..f8233ffc --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementDataSet.php @@ -0,0 +1,139 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/ReplacementTableIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Allows for replacing arbitrary values or portions of values with new data. + * + * A usage for this is replacing all values == '[NULL'] with a true NULL value + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Database_DataSet_ReplacementDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + /** + * @var PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected $dataSet; + + /** + * @var array + */ + protected $fullReplacements; + + /** + * @var array + */ + protected $subStrReplacements; + + /** + * Creates a new replacement dataset + * + * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet + * + * @param string $delimiter + * @param string $enclosure + * @param string $escape + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet, Array $fullReplacements = array(), Array $subStrReplacements = array()) + { + $this->dataSet = $dataSet; + $this->fullReplacements = $fullReplacements; + $this->subStrReplacements = $subStrReplacements; + } + + /** + * Adds a new full replacement + * + * Full replacements will only replace values if the FULL value is a match + * + * @param string $value + * @param string $replacement + */ + public function addFullReplacement($value, $replacement) + { + $this->fullReplacements[$value] = $replacement; + } + + /** + * Adds a new substr replacement + * + * Substr replacements will replace all occurances of the substr in every column + * + * @param string $value + * @param string $replacement + */ + public function addSubStrReplacement($value, $replacement) + { + $this->subStrReplacements[$value] = $replacement; + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + $innerIterator = $reverse ? $this->dataSet->getReverseIterator() : $this->dataSet->getIterator(); + return new PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator($innerIterator, $this->fullReplacements, $this->subStrReplacements); + } +} +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementTable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementTable.php new file mode 100644 index 00000000..0b68ab6c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementTable.php @@ -0,0 +1,249 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/ITable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Allows for replacing arbitrary strings in your data sets with other values. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @todo When setTableMetaData() is taken out of the AbstractTable this class should extend AbstractTable. + */ +class PHPUnit_Extensions_Database_DataSet_ReplacementTable implements PHPUnit_Extensions_Database_DataSet_ITable +{ + /** + * @var PHPUnit_Extensions_Database_DataSet_ITable + */ + protected $table; + + /** + * @var array + */ + protected $fullReplacements; + + /** + * @var array + */ + protected $subStrReplacements; + + /** + * Creates a new replacement table + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $table + * @param array $fullReplacements + * @param array $subStrReplacements + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $table, Array $fullReplacements = array(), Array $subStrReplacements = array()) + { + $this->table = $table; + $this->fullReplacements = $fullReplacements; + $this->subStrReplacements = $subStrReplacements; + } + + /** + * Adds a new full replacement + * + * Full replacements will only replace values if the FULL value is a match + * + * @param string $value + * @param string $replacement + */ + public function addFullReplacement($value, $replacement) + { + $this->fullReplacements[$value] = $replacement; + } + + /** + * Adds a new substr replacement + * + * Substr replacements will replace all occurances of the substr in every column + * + * @param string $value + * @param string $replacement + */ + public function addSubStrReplacement($value, $replacement) + { + $this->subStrReplacements[$value] = $replacement; + } + + /** + * Returns the table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData() + { + return $this->table->getTableMetaData(); + } + + /** + * Returns the number of rows in this table. + * + * @return int + */ + public function getRowCount() + { + return $this->table->getRowCount(); + } + + /** + * Returns the value for the given column on the given row. + * + * @param int $row + * @param int $column + */ + public function getValue($row, $column) + { + return $this->getReplacedValue($this->table->getValue($row, $column)); + } + + /** + * Returns the an associative array keyed by columns for the given row. + * + * @param int $row + * @return array + */ + public function getRow($row) + { + $row = $this->table->getRow($row); + + return array_map(array($this, 'getReplacedValue'), $row); + } + + /** + * Asserts that the given table matches this table. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $other + */ + public function assertEquals(PHPUnit_Extensions_Database_DataSet_ITable $other) + { + $thisMetaData = $this->getTableMetaData(); + $otherMetaData = $other->getTableMetaData(); + + $thisMetaData->assertEquals($otherMetaData); + + if ($this->getRowCount() != $other->getRowCount()) { + throw new Exception("Expected row count of {$this->getRowCount()}, has a row count of {$other->getRowCount()}"); + } + + $columns = $thisMetaData->getColumns(); + for ($i = 0; $i < $this->getRowCount(); $i++) { + foreach ($columns as $columnName) { + if ($this->getValue($i, $columnName) != $other->getValue($i, $columnName)) { + throw new Exception("Expected value of {$this->getValue($i, $columnName)} for row {$i} column {$columnName}, has a value of {$other->getValue($i, $columnName)}"); + } + } + } + + return TRUE; + } + + public function __toString() + { + $columns = $this->getTableMetaData()->getColumns(); + + $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n"; + $lineLength = strlen($lineSeperator) - 1; + + $tableString = $lineSeperator; + $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n"; + $tableString .= $lineSeperator; + $tableString .= $this->rowToString($columns); + $tableString .= $lineSeperator; + + for ($i = 0; $i < $this->getRowCount(); $i++) { + $values = array(); + foreach ($columns as $columnName) { + $values[] = $this->getValue($i, $columnName); + } + + $tableString .= $this->rowToString($values); + $tableString .= $lineSeperator; + } + + return "\n" . $tableString . "\n"; + } + + protected function rowToString(Array $row) + { + $rowString = ''; + foreach ($row as $value) { + if (is_null($value)) { + $value = 'NULL'; + } + $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' '; + } + + return $rowString . "|\n"; + } + + protected function getReplacedValue($value) + { + if (is_scalar($value) && array_key_exists((string)$value, $this->fullReplacements)) + { + return $this->fullReplacements[$value]; + } + elseif (count($this->subStrReplacements)) + { + return str_replace(array_keys($this->subStrReplacements), array_values($this->subStrReplacements), $value); + } + else + { + return $value; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementTableIterator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementTableIterator.php new file mode 100644 index 00000000..694eba89 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/ReplacementTableIterator.php @@ -0,0 +1,196 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/ITableIterator.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/ReplacementTable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default table iterator + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator implements OuterIterator, PHPUnit_Extensions_Database_DataSet_ITableIterator +{ + + /** + * @var PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected $innerIterator; + + /** + * @var array + */ + protected $fullReplacements; + + /** + * @var array + */ + protected $subStrReplacements; + + /** + * Creates a new replacement table iterator object. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator + * @param array $fullReplacements + * @param array $subStrReplacements + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator, Array $fullReplacements = array(), Array $subStrReplacements = array()) + { + $this->innerIterator = $innerIterator; + $this->fullReplacements = $fullReplacements; + $this->subStrReplacements = $subStrReplacements; + } + + /** + * Adds a new full replacement + * + * Full replacements will only replace values if the FULL value is a match + * + * @param string $value + * @param string $replacement + */ + public function addFullReplacement($value, $replacement) + { + $this->fullReplacements[$value] = $replacement; + } + + /** + * Adds a new substr replacement + * + * Substr replacements will replace all occurances of the substr in every column + * + * @param string $value + * @param string $replacement + */ + public function addSubStrReplacement($value, $replacement) + { + $this->subStrReplacements[$value] = $replacement; + } + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function getTable() + { + return $this->current(); + } + + /** + * Returns the current table's meta data. + * + * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + public function getTableMetaData() + { + $this->current()->getTableMetaData(); + } + + /** + * Returns the current table. + * + * @return PHPUnit_Extensions_Database_DataSet_ITable + */ + public function current() + { + return new PHPUnit_Extensions_Database_DataSet_ReplacementTable($this->innerIterator->current(), $this->fullReplacements, $this->subStrReplacements); + } + + /** + * Returns the name of the current table. + * + * @return string + */ + public function key() + { + return $this->current()->getTableMetaData()->getTableName(); + } + + /** + * advances to the next element. + * + */ + public function next() + { + $this->innerIterator->next(); + } + + /** + * Rewinds to the first element + */ + public function rewind() + { + $this->innerIterator->rewind(); + } + + /** + * Returns true if the current index is valid + * + * @return bool + */ + public function valid() + { + return $this->innerIterator->valid(); + } + + public function getInnerIterator() + { + return $this->innerIterator; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Csv.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Csv.php new file mode 100644 index 00000000..31a1d836 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Csv.php @@ -0,0 +1,131 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/ISpec.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/CsvDataSet.php'); + +/** + * Creates CsvDataSets based off of a spec string. + * + * The format of the spec string is as follows: + * + * |table1:filename.csv,table2:filename2.csv + * + * The first portion of the spec including the pipe symbol '|' is optional. + * If the pipe option is included than it may be preceded by up to four + * characters specifying values for the following arguments in order: + * delimiter (defaults to ',',) enclosure (defaults to '"',) escape (defaults to '"',). + * + * Any additional characters in the csv options will be discarded. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_Csv implements PHPUnit_Extensions_Database_DataSet_ISpec +{ + + /** + * Creates CSV Data Set from a data set spec. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet + */ + public function getDataSet($dataSetSpec) + { + $csvDataSetArgs = $this->getCsvOptions($dataSetSpec); + $csvDataSetRfl = new ReflectionClass('PHPUnit_Extensions_Database_DataSet_CsvDataSet'); + $csvDataSet = $csvDataSetRfl->newInstanceArgs($csvDataSetArgs); + + foreach ($this->getTableFileMap($dataSetSpec) as $tableName => $file) { + $csvDataSet->addTable($tableName, $file); + } + return $csvDataSet; + } + + /** + * Returns CSV options. + * + * Returns an array containing the options that will be passed to the + * PHPUnit_Extensions_Database_DataSet_CsvDataSet constructor. The options + * are determined by the given $dataSetSpec. + * + * @param string $dataSetSpec + * @return array + */ + protected function getCsvOptions($dataSetSpec) + { + list($csvOptStr, ) = explode('|', $dataSetSpec, 2); + return str_split($csvOptStr); + } + + /** + * Returns map of tables to files. + * + * Returns an associative array containing a mapping of tables (the key) + * to files (the values.) The tables and files are determined by the given + * $dataSetSpec + * + * @param string $dataSetSpec + * @return array + */ + protected function getTableFileMap($dataSetSpec) + { + $tables = array(); + foreach (explode(',', $dataSetSpec) as $csvfile) { + list($tableName, $file) = explode(':', $csvfile, 2); + $tables[$tableName] = $file; + } + + return $tables; + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/DbQuery.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/DbQuery.php new file mode 100644 index 00000000..1667d96c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/DbQuery.php @@ -0,0 +1,119 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/ISpec.php'); +require_once ('PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php'); +require_once ('PHPUnit/Extensions/Database/IDatabaseListConsumer.php'); + +/** + * Creates DefaultDataSets based off of a spec string. + * + * This spec class requires a list of databases to be set to the object before + * it can return a list of databases. + * + * The format of the spec string is as follows: + * + * ::: + * + * The db label should be equal to one of the keys in the array of databases + * passed to setDatabases(). + * + * The schema should be the primary schema you will be running the sql query + * against. + * + * The table name should be set to what you would like the table name in the + * dataset to be. + * + * The sql is the query you want to use to generate the table columns and data. + * The column names in the table will be identical to the column aliases in the + * query. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_DbQuery implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer +{ + /** + * @var array + */ + protected $databases = array(); + + /** + * Sets the database for the spec + * + * @param array $databases + */ + public function setDatabases(array $databases) + { + $this->databases = $databases; + } + + /** + * Creates a Default Data Set with a query table from a data set spec. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet + */ + public function getDataSet($dataSetSpec) + { + $pdoRflc = new ReflectionClass('PDO'); + list($dbLabel, $schema, $table, $sql) = explode(':', $dataSetSpec, 4); + + $databaseInfo = $this->databases[$dbLabel]; + $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo)); + + $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema); + $table = $dbConnection->createQueryTable($table, $sql); + return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(array($table)); + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/DbTable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/DbTable.php new file mode 100644 index 00000000..56e1ec0b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/DbTable.php @@ -0,0 +1,117 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/ISpec.php'); +require_once ('PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php'); +require_once ('PHPUnit/Extensions/Database/IDatabaseListConsumer.php'); + +/** + * Creates a database dataset based off of a spec string. + * + * This spec class requires a list of databases to be set to the object before + * it can return a list of databases. + * + * The format of the spec string is as follows: + * + * :: + * + * The db label should be equal to one of the keys in the array of databases + * passed to setDatabases(). + * + * The schema should be the primary schema you will be choosing tables from. + * + * The tables should be a comma delimited list of all tables you would like to + * pull data from. + * + * The sql is the query you want to use to generate the table columns and data. + * The column names in the table will be identical to the column aliases in the + * query. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_DbTable implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer +{ + /** + * @var array + */ + protected $databases = array(); + + /** + * Sets the database for the spec + * + * @param array $databases + */ + public function setDatabases(array $databases) + { + $this->databases = $databases; + } + + /** + * Creates a DB Data Set from a data set spec. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + public function getDataSet($dataSetSpec) + { + $pdoRflc = new ReflectionClass('PDO'); + list($dbLabel, $schema, $tables) = explode(':', $dataSetSpec, 3); + + $databaseInfo = $this->databases[$dbLabel]; + $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo)); + + $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema); + return !empty($tables) ? $dbConnection->createDataSet(explode(',', $tables)) : $dbConnection->createDataSet(); + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Factory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Factory.php new file mode 100644 index 00000000..6f7c5f61 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Factory.php @@ -0,0 +1,101 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/Specs/IFactory.php'); + +/** + * Creates the appropriate DataSet Spec based on a given type. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_Factory implements PHPUnit_Extensions_Database_DataSet_Specs_IFactory +{ + /** + * Returns the data set + * + * @param string $type + * @return PHPUnit_Extensions_Database_DataSet_ISpec + */ + public function getDataSetSpecByType($type) + { + switch ($type) { + case 'xml': + require_once ('PHPUnit/Extensions/Database/DataSet/Specs/Xml.php'); + return new PHPUnit_Extensions_Database_DataSet_Specs_Xml(); + + case 'flatxml': + require_once ('PHPUnit/Extensions/Database/DataSet/Specs/FlatXml.php'); + return new PHPUnit_Extensions_Database_DataSet_Specs_FlatXml(); + + case 'csv': + require_once ('PHPUnit/Extensions/Database/DataSet/Specs/Csv.php'); + return new PHPUnit_Extensions_Database_DataSet_Specs_Csv(); + + case 'yaml': + require_once ('PHPUnit/Extensions/Database/DataSet/Specs/Yaml.php'); + return new PHPUnit_Extensions_Database_DataSet_Specs_Yaml(); + + case 'dbtable': + require_once ('PHPUnit/Extensions/Database/DataSet/Specs/DbTable.php'); + return new PHPUnit_Extensions_Database_DataSet_Specs_DbTable(); + + case 'dbquery': + require_once ('PHPUnit/Extensions/Database/DataSet/Specs/DbQuery.php'); + return new PHPUnit_Extensions_Database_DataSet_Specs_DbQuery(); + + default: + throw new Exception("I don't know what you want from me."); + } + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/FlatXml.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/FlatXml.php new file mode 100644 index 00000000..76b3c2e8 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/FlatXml.php @@ -0,0 +1,82 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0CSV + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/ISpec.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php'); + +/** + * Creates a FlatXML dataset based off of a spec string. + * + * The format of the spec string is as follows: + * + * + * + * The filename should be the location of a flat xml file relative to the + * current working directory. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_FlatXml implements PHPUnit_Extensions_Database_DataSet_ISpec +{ + /** + * Creates Flat XML Data Set from a data set spec. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet + */ + public function getDataSet($dataSetSpec) + { + return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($dataSetSpec); + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/IFactory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/IFactory.php new file mode 100644 index 00000000..82f46c84 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/IFactory.php @@ -0,0 +1,69 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * An interface for data set spec factories. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_DataSet_Specs_IFactory +{ + /** + * Returns the data set + * + * @param string $type + * @return PHPUnit_Extensions_Database_DataSet_ISpec + */ + public function getDataSetSpecByType($type); +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Xml.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Xml.php new file mode 100644 index 00000000..97ae020e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Xml.php @@ -0,0 +1,82 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0CSV + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/ISpec.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/XmlDataSet.php'); + +/** + * Creates a XML dataset based off of a spec string. + * + * The format of the spec string is as follows: + * + * + * + * The filename should be the location of a xml file relative to the + * current working directory. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_Xml implements PHPUnit_Extensions_Database_DataSet_ISpec +{ + /** + * Creates XML Data Set from a data set spec. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet + */ + public function getDataSet($dataSetSpec) + { + return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($dataSetSpec); + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Yaml.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Yaml.php new file mode 100644 index 00000000..953276f3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/Specs/Yaml.php @@ -0,0 +1,82 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0CSV + */ + +require_once ('PHPUnit/Extensions/Database/DataSet/ISpec.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/YamlDataSet.php'); + +/** + * Creates a YAML dataset based off of a spec string. + * + * The format of the spec string is as follows: + * + * + * + * The filename should be the location of a yaml file relative to the + * current working directory. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_DataSet_Specs_Yaml implements PHPUnit_Extensions_Database_DataSet_ISpec +{ + /** + * Creates YAML Data Set from a data set spec. + * + * @param string $dataSetSpec + * @return PHPUnit_Extensions_Database_DataSet_YamlDataSet + */ + public function getDataSet($dataSetSpec) + { + return new PHPUnit_Extensions_Database_DataSet_YamlDataSet($dataSetSpec); + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/TableFilter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/TableFilter.php new file mode 100644 index 00000000..0cc85e7f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/TableFilter.php @@ -0,0 +1,147 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTable.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/TableMetaDataFilter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A table decorator that allows filtering out table columns from results. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_TableFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTable +{ + + /** + * The table meta data being decorated. + * @var PHPUnit_Extensions_Database_DataSet_ITable + */ + protected $originalTable; + + /** + * Creates a new table filter using the original table + * + * @param $originalTable PHPUnit_Extensions_Database_DataSet_ITable + * @param $excludeColumns Array @deprecated, use the set* methods instead. + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $originalTable, Array $excludeColumns = array()) + { + $this->originalTable = $originalTable; + $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter($originalTable->getTableMetaData())); + $this->addExcludeColumns($excludeColumns); + } + + /** + * Returns the number of rows in this table. + * + * @return int + */ + public function getRowCount() + { + return $this->originalTable->getRowCount(); + } + + /** + * Returns the value for the given column on the given row. + * + * @param int $row + * @param int $column + */ + public function getValue($row, $column) + { + if (in_array($column, $this->getTableMetaData()->getColumns())) { + return $this->originalTable->getValue($row, $column); + } else { + throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}"); + } + } + + /** + * Sets the columns to include in the table. + * @param Array $includeColumns + */ + public function addIncludeColumns(Array $includeColumns) + { + $this->tableMetaData->addIncludeColumns($includeColumns); + } + + /** + * Clears the included columns. + */ + public function clearIncludeColumns() + { + $this->tableMetaData->clearIncludeColumns(); + } + + /** + * Sets the columns to exclude from the table. + * @param Array $excludeColumns + */ + public function addExcludeColumns(Array $excludeColumns) + { + $this->tableMetaData->addExcludeColumns($excludeColumns); + } + + /** + * Clears the included columns. + */ + public function clearExcludeColumns() + { + $this->tableMetaData->clearExcludeColumns(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/TableMetaDataFilter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/TableMetaDataFilter.php new file mode 100644 index 00000000..eab86d1e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/TableMetaDataFilter.php @@ -0,0 +1,175 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TableMetaData decorator that allows filtering columns from another + * metaData object. + * + * The if a whitelist (include) filter is specified, then only those columns + * will be included. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData +{ + + /** + * The table meta data being decorated. + * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData + */ + protected $originalMetaData; + + /** + * The columns to exclude from the meta data. + * @var Array + */ + protected $excludeColumns = array(); + + /** + * The columns to include from the meta data. + * @var Array + */ + protected $includeColumns = array(); + + /** + * Creates a new filtered table meta data object filtering out + * $excludeColumns. + * + * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData + * @param array $excludeColumns - Deprecated. Use the set* methods instead. + */ + public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData, Array $excludeColumns = array()) + { + $this->originalMetaData = $originalMetaData; + $this->addExcludeColumns($excludeColumns); + } + + /** + * Returns the names of the columns in the table. + * + * @return array + */ + public function getColumns() + { + if (!empty($this->includeColumns)) { + return array_values(array_intersect($this->originalMetaData->getColumns(), $this->includeColumns)); + } + elseif (!empty($this->excludeColumns)) { + return array_values(array_diff($this->originalMetaData->getColumns(), $this->excludeColumns)); + } + else { + return $this->originalMetaData->getColumns(); + } + } + + /** + * Returns the names of the primary key columns in the table. + * + * @return array + */ + public function getPrimaryKeys() + { + return $this->originalMetaData->getPrimaryKeys(); + } + + /** + * Returns the name of the table. + * + * @return string + */ + public function getTableName() + { + return $this->originalMetaData->getTableName(); + } + + /** + * Sets the columns to include in the table. + * @param Array $includeColumns + */ + public function addIncludeColumns(Array $includeColumns) + { + $this->includeColumns = array_unique(array_merge($this->includeColumns, $includeColumns)); + } + + /** + * Clears the included columns. + */ + public function clearIncludeColumns() + { + $this->includeColumns = array(); + } + + /** + * Sets the columns to exclude from the table. + * @param Array $excludeColumns + */ + public function addExcludeColumns(Array $excludeColumns) + { + $this->excludeColumns = array_unique(array_merge($this->excludeColumns, $excludeColumns)); + } + + /** + * Clears the excluded columns. + */ + public function clearExcludeColumns() + { + $this->excludeColumns = array(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/XmlDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/XmlDataSet.php new file mode 100644 index 00000000..812c0bb9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/XmlDataSet.php @@ -0,0 +1,140 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The default implementation of a data set. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DataSet_XmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet +{ + + protected function getTableInfo(Array &$tableColumns, Array &$tableValues) + { + if ($this->xmlFileContents->getName() != 'dataset') { + throw new Exception("The root element of an xml data set file must be called "); + } + + foreach ($this->xmlFileContents->xpath('/dataset/table') as $tableElement) { + if (empty($tableElement['name'])) { + throw new Exception("Table elements must include a name attribute specifying the table name."); + } + + $tableName = (string)$tableElement['name']; + + if (!isset($tableColumns[$tableName])) { + $tableColumns[$tableName] = array(); + } + + if (!isset($tableValues[$tableName])) { + $tableValues[$tableName] = array(); + } + + $tableInstanceColumns = array(); + + foreach ($tableElement->xpath('./column') as $columnElement) { + $columnName = (string)$columnElement; + if (empty($columnName)) { + throw new Exception("column elements cannot be empty"); + } + + if (!in_array($columnName, $tableColumns[$tableName])) { + $tableColumns[$tableName][] = $columnName; + } + + $tableInstanceColumns[] = $columnName; + } + + foreach ($tableElement->xpath('./row') as $rowElement) { + $rowValues = array(); + $index = 0; + foreach ($rowElement->children() as $columnValue) { + switch ($columnValue->getName()) { + case 'value': + $rowValues[$tableInstanceColumns[$index]] = (string)$columnValue; + $index++; + break; + case 'null': + $rowValues[$tableInstanceColumns[$index]] = NULL; + $index++; + break; + default: + throw new Exception("Unknown child in the a row element."); + } + } + + $tableValues[$tableName][] = $rowValues; + } + } + } + + public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) + { + $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml(); + $pers->setFileName($filename); + + try { + $pers->write($dataset); + } catch (RuntimeException $e) { + throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/YamlDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/YamlDataSet.php new file mode 100644 index 00000000..622388ce --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DataSet/YamlDataSet.php @@ -0,0 +1,149 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTable.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php'; +require_once 'SymfonyComponents/YAML/sfYaml.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Creates CsvDataSets. + * + * You can incrementally add CSV files as tables to your datasets + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Database_DataSet_YamlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet +{ + /** + * @var array + */ + protected $tables = array(); + + /** + * Creates a new YAML dataset + * + * @param string $yamlFile + * @param string $enclosure + * @param string $escape + */ + public function __construct($yamlFile) + { + $this->addYamlFile($yamlFile); + } + + /** + * Adds a new yaml file to the dataset. + * @param string $yamlFile + */ + public function addYamlFile($yamlFile) + { + $data = sfYaml::load($yamlFile); + + foreach ($data as $tableName => $rows) + { + if (!is_array($rows)) { + continue; + } + + if (!array_key_exists($tableName, $this->tables)) + { + $columns = count($rows) ? array_keys(current($rows)) : array(); + + $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns); + + $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable($tableMetaData); + } + + foreach ($rows as $row) + { + $this->tables[$tableName]->addRow($row); + } + } + } + + /** + * Creates an iterator over the tables in the data set. If $reverse is + * true a reverse iterator will be returned. + * + * @param bool $reverse + * @return PHPUnit_Extensions_Database_DataSet_ITableIterator + */ + protected function createIterator($reverse = FALSE) + { + return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); + } + + /** + * Saves a given $dataset to $filename in YAML format + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset + * @param string $filename + */ + public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) + { + $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml(); + $pers->setFileName($filename); + + try { + $pers->write($dataset); + } catch (RuntimeException $e) { + throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DefaultTester.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DefaultTester.php new file mode 100644 index 00000000..2d8930dc --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/DefaultTester.php @@ -0,0 +1,94 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/AbstractTester.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This is the default implementation of the database tester. It receives its + * connection object from the constructor. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_DefaultTester extends PHPUnit_Extensions_Database_AbstractTester +{ + + /** + * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected $connection; + + /** + * Creates a new default database tester using the given connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + */ + public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $this->connection = $connection; + } + + /** + * Returns the test database connection. + * + * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + public function getConnection() + { + return $this->connection; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/IDatabaseListConsumer.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/IDatabaseListConsumer.php new file mode 100644 index 00000000..18e77150 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/IDatabaseListConsumer.php @@ -0,0 +1,68 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * An interface for classes that require a list of databases to operate. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_IDatabaseListConsumer +{ + /** + * Sets the database for the spec + * + * @param array $databases + */ + public function setDatabases(array $databases); +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/ITester.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/ITester.php new file mode 100644 index 00000000..13a07ef0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/ITester.php @@ -0,0 +1,127 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This is the interface for DatabaseTester objects. These objects are used to + * add database testing to existing test cases using composition instead of + * extension. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_ITester +{ + + /** + * Closes the specified connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + */ + public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection); + + /** + * Returns the test database connection. + * + * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + public function getConnection(); + + /** + * Returns the test dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + public function getDataSet(); + + /** + * TestCases must call this method inside setUp(). + */ + public function onSetUp(); + + /** + * TestCases must call this method inside teadDown(). + */ + public function onTearDown(); + + /** + * Sets the test dataset to use. + * + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet + */ + public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet); + + /** + * Sets the schema value. + * + * @param string $schema + */ + public function setSchema($schema); + + /** + * Sets the DatabaseOperation to call when starting the test. + * + * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation + */ + public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation); + + /** + * Sets the DatabaseOperation to call when starting the test. + * + * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation + */ + public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Composite.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Composite.php new file mode 100644 index 00000000..218fa00d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Composite.php @@ -0,0 +1,105 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This class facilitates combining database operations. To create a composite + * operation pass an array of classes that implement + * PHPUnit_Extensions_Database_Operation_IDatabaseOperation and they will be + * executed in that order against all data sets. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Composite implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation +{ + + /** + * @var array + */ + protected $operations = array(); + + /** + * Creates a composite operation. + * + * @param array $operations + */ + public function __construct(Array $operations) + { + foreach ($operations as $operation) { + if ($operation instanceof PHPUnit_Extensions_Database_Operation_IDatabaseOperation) { + $this->operations[] = $operation; + } else { + throw new InvalidArgumentException("Only database operation instances can be passed to a composite database operation."); + } + } + } + + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + try { + foreach ($this->operations as $operation) { + /* @var $operation PHPUnit_Extensions_Database_Operation_IDatabaseOperation */ + $operation->execute($connection, $dataSet); + } + } catch (PHPUnit_Extensions_Database_Operation_Exception $e) { + throw new PHPUnit_Extensions_Database_Operation_Exception("COMPOSITE[{$e->getOperation()}]", $e->getQuery(), $e->getArgs(), $e->getTable(), $e->getError()); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Delete.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Delete.php new file mode 100644 index 00000000..ca4e53af --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Delete.php @@ -0,0 +1,97 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/RowBased.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Deletes the rows in a given dataset using primary key columns. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Delete extends PHPUnit_Extensions_Database_Operation_RowBased +{ + + protected $operationName = 'DELETE'; + + protected $iteratorDirection = self::ITERATOR_TYPE_REVERSE; + + protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $keys = $databaseTableMetaData->getPrimaryKeys(); + + $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection)); + + $query = " + DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} + {$whereStatement} + "; + + return $query; + } + + protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) + { + $args = array(); + foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) { + $args[] = $table->getValue($row, $columnName); + } + + return $args; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/DeleteAll.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/DeleteAll.php new file mode 100644 index 00000000..521ef653 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/DeleteAll.php @@ -0,0 +1,86 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Deletes all rows from all tables in a dataset. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_DeleteAll implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation +{ + + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + foreach ($dataSet->getReverseIterator() as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + + $query = " + DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} + "; + + try { + $connection->getConnection()->query($query); + } catch (PDOException $e) { + throw new PHPUnit_Extensions_Database_Operation_Exception('DELETE_ALL', $query, array(), $table, $e->getMessage()); + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Exception.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Exception.php new file mode 100644 index 00000000..e11ce39a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Exception.php @@ -0,0 +1,136 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown for exceptions encountered with database operations. Provides + * information regarding which operations failed and the query (if any) it + * failed on. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Exception extends RuntimeException +{ + + /** + * @var string + */ + protected $operation; + + /** + * @var string + */ + protected $preparedQuery; + + /** + * @var array + */ + protected $preparedArgs; + + /** + * @var PHPUnit_Extensions_Database_DataSet_ITable + */ + protected $table; + + /** + * @var string + */ + protected $error; + + /** + * Creates a new dbunit operation exception + * + * @param string $operation + * @param string $current_query + * @param PHPUnit_Extensions_Database_DataSet_ITable $current_table + * @param string $error + */ + public function __construct($operation, $current_query, $current_args, $current_table, $error) + { + parent::__construct("{$operation} operation failed on query: {$current_query} using args: " . print_r($current_args, TRUE) . " [{$error}]"); + $this->operation = $operation; + $this->preparedQuery = $current_query; + $this->preparedArgs = $current_args; + $this->table = $current_table; + $this->error = $error; + } + + public function getOperation() + { + return $this->operation; + } + + public function getQuery() + { + return $this->preparedQuery; + } + + public function getTable() + { + return $this->table; + } + + public function getArgs() + { + return $this->preparedArgs; + } + + public function getError() + { + return $this->error; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Factory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Factory.php new file mode 100644 index 00000000..9f69cc5e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Factory.php @@ -0,0 +1,156 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +require_once 'PHPUnit/Extensions/Database/Operation/Composite.php'; +require_once 'PHPUnit/Extensions/Database/Operation/DeleteAll.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Delete.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Insert.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Null.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Update.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Truncate.php'; + +/** + * A class factory to easily return database operations. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Factory +{ + + /** + * Returns a null database operation + * + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function NONE() + { + return new PHPUnit_Extensions_Database_Operation_Null(); + } + + /** + * Returns a clean insert database operation. It will remove all contents + * from the table prior to re-inserting rows. + * + * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this. + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function CLEAN_INSERT($cascadeTruncates = FALSE) + { + return new PHPUnit_Extensions_Database_Operation_Composite(array( + self::TRUNCATE($cascadeTruncates), + self::INSERT() + )); + } + + /** + * Returns an insert database operation. + * + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function INSERT() + { + return new PHPUnit_Extensions_Database_Operation_Insert(); + } + + /** + * Returns a truncate database operation. + * + * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this. + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function TRUNCATE($cascadeTruncates = FALSE) + { + $truncate = new PHPUnit_Extensions_Database_Operation_Truncate(); + $truncate->setCascade($cascadeTruncates); + + return $truncate; + } + + /** + * Returns a delete database operation. + * + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function DELETE() + { + return new PHPUnit_Extensions_Database_Operation_Delete(); + } + + /** + * Returns a delete_all database operation. + * + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function DELETE_ALL() + { + return new PHPUnit_Extensions_Database_Operation_DeleteAll(); + } + + /** + * Returns an update database operation. + * + * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation + */ + public static function UPDATE() + { + return new PHPUnit_Extensions_Database_Operation_Update(); + } + +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php new file mode 100644 index 00000000..0460be1c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php @@ -0,0 +1,77 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides a basic interface and functionality for executing database + * operations against a connection using a specific dataSet. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +interface PHPUnit_Extensions_Database_Operation_IDatabaseOperation +{ + + /** + * Executes the database operation against the given $connection for the + * given $dataSet. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet + * @throws PHPUnit_Extensions_Database_Operation_Exception + */ + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Insert.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Insert.php new file mode 100644 index 00000000..3f5a6b67 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Insert.php @@ -0,0 +1,107 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/RowBased.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This class provides functionality for inserting rows from a dataset into a database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Insert extends PHPUnit_Extensions_Database_Operation_RowBased +{ + + protected $operationName = 'INSERT'; + + protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $columnCount = count($table->getTableMetaData()->getColumns()); + + if ($columnCount > 0) { + $placeHolders = implode(', ', array_fill(0, $columnCount, '?')); + + $columns = ''; + foreach ($table->getTableMetaData()->getColumns() as $column) { + $columns .= $connection->quoteSchemaObject($column).', '; + } + + $columns = substr($columns, 0, -2); + + $query = " + INSERT INTO {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} + ({$columns}) + VALUES + ({$placeHolders}) + "; + + return $query; + } else { + return FALSE; + } + } + + protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) + { + $args = array(); + foreach ($table->getTableMetaData()->getColumns() as $columnName) { + $args[] = $table->getValue($row, $columnName); + } + return $args; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Null.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Null.php new file mode 100644 index 00000000..dabdbaf5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Null.php @@ -0,0 +1,73 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This class represents a null database operation. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Null implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation +{ + + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + /* do nothing */ + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Replace.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Replace.php new file mode 100644 index 00000000..e7b83551 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Replace.php @@ -0,0 +1,147 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/RowBased.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Insert.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Update.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Updates the rows in a given dataset using primary key columns. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Replace extends PHPUnit_Extensions_Database_Operation_RowBased +{ + + protected $operationName = 'REPLACE'; + + protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $keys = $databaseTableMetaData->getPrimaryKeys(); + + $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection)); + + $query = " + SELECT COUNT(*) + FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} + {$whereStatement} + "; + + return $query; + } + + protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) + { + $args = array(); + + foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) { + $args[] = $table->getValue($row, $columnName); + } + + return $args; + } + + /** + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet + */ + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + $insertOperation = new PHPUnit_Extensions_Database_Operation_Insert(); + $updateOperation = new PHPUnit_Extensions_Database_Operation_Update(); + + $databaseDataSet = $connection->createDataSet(); + + foreach ($dataSet as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName()); + + $insertQuery = $insertOperation->buildOperationQuery($databaseTableMetaData, $table, $connection); + $updateQuery = $updateOperation->buildOperationQuery($databaseTableMetaData, $table, $connection); + $selectQuery = $this->buildOperationQuery($databaseTableMetaData, $table, $connection); + + $insertStatement = $connection->getConnection()->prepare($insertQuery); + $updateStatement = $connection->getConnection()->prepare($updateQuery); + $selectStatement = $connection->getConnection()->prepare($selectQuery); + + for ($i = 0; $i < $table->getRowCount(); $i++) { + $selectArgs = $this->buildOperationArguments($databaseTableMetaData, $table, $i); + $query = $selectQuery; + $args = $selectArgs; + try { + $selectStatement->execute($selectArgs); + + if ($selectStatement->fetchColumn(0) > 0) { + $updateArgs = $updateOperation->buildOperationArguments($databaseTableMetaData, $table, $i); + $query = $updateQuery; + $args = $updateArgs; + $updateStatement->execute($updateArgs); + } else { + $insertArgs = $insertOperation->buildOperationArguments($databaseTableMetaData, $table, $i); + $query = $insertQuery; + $args = $insertArgs; + $insertStatement->execute($insertArgs); + } + } catch (Exception $e) { + throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, $query, $args, $table, $e->getMessage()); + } + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/RowBased.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/RowBased.php new file mode 100644 index 00000000..59489c36 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/RowBased.php @@ -0,0 +1,124 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Provides basic functionality for row based operations. + * + * To create a row based operation you must create two functions. The first + * one, buildOperationQuery(), must return a query that will be used to create + * a prepared statement. The second one, buildOperationArguments(), should + * return an array containing arguments for each row. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_Operation_RowBased implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation +{ + const ITERATOR_TYPE_FORWARD = 0; + const ITERATOR_TYPE_REVERSE = 1; + + protected $operationName; + + protected $iteratorDirection = self::ITERATOR_TYPE_FORWARD; + + protected abstract function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection); + + protected abstract function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row); + + /** + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet + */ + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + $databaseDataSet = $connection->createDataSet(); + + $dsIterator = $this->iteratorDirection == self::ITERATOR_TYPE_REVERSE ? $dataSet->getReverseIterator() : $dataSet->getIterator(); + + foreach ($dsIterator as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName()); + $query = $this->buildOperationQuery($databaseTableMetaData, $table, $connection); + + if ($query === FALSE && $table->getRowCount() > 0) { + throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, '', array(), $table, "Rows requested for insert, but no columns provided!"); + } + + $statement = $connection->getConnection()->prepare($query); + for ($i = 0; $i < $table->getRowCount(); $i++) { + $args = $this->buildOperationArguments($databaseTableMetaData, $table, $i); + try { + $statement->execute($args); + } catch (Exception $e) { + throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, $query, $args, $table, $e->getMessage()); + } + } + } + } + + protected function buildPreparedColumnArray($columns, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $columnArray = array(); + foreach ($columns as $columnName) { + $columnArray[] = "{$connection->quoteSchemaObject($columnName)} = ?"; + } + return $columnArray; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Truncate.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Truncate.php new file mode 100644 index 00000000..61c4a717 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Truncate.php @@ -0,0 +1,95 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Executes a truncate against all tables in a dataset. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Truncate implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation +{ + protected $useCascade = FALSE; + + public function setCascade($cascade = TRUE) + { + $this->useCascade = $cascade; + } + + public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) + { + foreach ($dataSet->getReverseIterator() as $table) { + /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ + $query = " + {$connection->getTruncateCommand()} {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} + "; + + if ($this->useCascade && $connection->allowsCascading()) { + $query .= " CASCADE"; + } + + try { + $connection->getConnection()->query($query); + } catch (PDOException $e) { + throw new PHPUnit_Extensions_Database_Operation_Exception('TRUNCATE', $query, array(), $table, $e->getMessage()); + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Update.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Update.php new file mode 100644 index 00000000..e30a1894 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/Operation/Update.php @@ -0,0 +1,102 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/Operation/RowBased.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Exception.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Updates the rows in a given dataset using primary key columns. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Extensions_Database_Operation_Update extends PHPUnit_Extensions_Database_Operation_RowBased +{ + + protected $operationName = 'UPDATE'; + + protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $keys = $databaseTableMetaData->getPrimaryKeys(); + $columns = $table->getTableMetaData()->getColumns(); + + $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection)); + $setStatement = 'SET ' . implode(', ', $this->buildPreparedColumnArray($columns, $connection)); + + $query = " + UPDATE {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} + {$setStatement} + {$whereStatement} + "; + + return $query; + } + + protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) + { + $args = array(); + foreach ($table->getTableMetaData()->getColumns() as $columnName) { + $args[] = $table->getValue($row, $columnName); + } + + foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) { + $args[] = $table->getValue($row, $columnName); + } + + return $args; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/TestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/TestCase.php new file mode 100644 index 00000000..0add8b27 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/TestCase.php @@ -0,0 +1,255 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +require_once 'PHPUnit/Extensions/Database/DefaultTester.php'; +require_once 'PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php'; +require_once 'PHPUnit/Extensions/Database/Operation/Factory.php'; +require_once 'PHPUnit/Extensions/Database/Constraint/TableIsEqual.php'; +require_once 'PHPUnit/Extensions/Database/Constraint/DataSetIsEqual.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestCase extension that provides functionality for testing and asserting + * against a real database. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Extensions_Database_TestCase extends PHPUnit_Framework_TestCase +{ + + /** + * @var PHPUnit_Extensions_Database_ITester + */ + protected $databaseTester; + + /** + * Closes the specified connection. + * + * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection + */ + protected function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) + { + $this->getDatabaseTester()->closeConnection($connection); + } + + /** + * Returns the test database connection. + * + * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected abstract function getConnection(); + + /** + * Gets the IDatabaseTester for this testCase. If the IDatabaseTester is + * not set yet, this method calls newDatabaseTester() to obtain a new + * instance. + * + * @return PHPUnit_Extensions_Database_ITester + */ + protected function getDatabaseTester() + { + if (empty($this->databaseTester)) { + $this->databaseTester = $this->newDatabaseTester(); + } + + return $this->databaseTester; + } + + /** + * Returns the test dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected abstract function getDataSet(); + + /** + * Returns the database operation executed in test setup. + * + * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation + */ + protected function getSetUpOperation() + { + return PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT(); + } + + /** + * Returns the database operation executed in test cleanup. + * + * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation + */ + protected function getTearDownOperation() + { + return PHPUnit_Extensions_Database_Operation_Factory::NONE(); + } + + /** + * Creates a IDatabaseTester for this testCase. + * + * @return PHPUnit_Extensions_Database_ITester + */ + protected function newDatabaseTester() + { + return new PHPUnit_Extensions_Database_DefaultTester($this->getConnection()); + } + + /** + * Creates a new DefaultDatabaseConnection using the given PDO connection + * and database schema name. + * + * @param PDO $connection + * @param string $schema + * @return PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection + */ + protected function createDefaultDBConnection(PDO $connection, $schema) + { + return new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($connection, $schema); + } + + /** + * Creates a new FlatXmlDataSet with the given $xmlFile. (absolute path.) + * + * @param string $xmlFile + * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet + */ + protected function createFlatXMLDataSet($xmlFile) + { + require_once 'PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php'; + return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($xmlFile); + } + + /** + * Creates a new XMLDataSet with the given $xmlFile. (absolute path.) + * + * @param string $xmlFile + * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet + */ + protected function createXMLDataSet($xmlFile) + { + require_once 'PHPUnit/Extensions/Database/DataSet/XmlDataSet.php'; + return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($xmlFile); + } + + /** + * Returns an operation factory instance that can be used to instantiate + * new operations. + * + * @return PHPUnit_Extensions_Database_Operation_Factory + */ + protected function getOperations() + { + require_once 'PHPUnit/Extensions/Database/Operation/Factory.php'; + return new PHPUnit_Extensions_Database_Operation_Factory(); + } + + /** + * Performs operation returned by getSetUpOperation(). + */ + protected function setUp() + { + parent::setUp(); + + $this->databaseTester = NULL; + + $this->getDatabaseTester()->setSetUpOperation($this->getSetUpOperation()); + $this->getDatabaseTester()->setDataSet($this->getDataSet()); + $this->getDatabaseTester()->onSetUp(); + } + + /** + * Performs operation returned by getSetUpOperation(). + */ + protected function tearDown() + { + $this->getDatabaseTester()->setTearDownOperation($this->getTearDownOperation()); + $this->getDatabaseTester()->setDataSet($this->getDataSet()); + $this->getDatabaseTester()->onTearDown(); + + /** + * Destroy the tester after the test is run to keep DB connections + * from piling up. + */ + $this->databaseTester = NULL; + } + + /** + * Asserts that two given tables are equal. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $expected + * @param PHPUnit_Extensions_Database_DataSet_ITable $actual + * @param string $message + */ + public static function assertTablesEqual(PHPUnit_Extensions_Database_DataSet_ITable $expected, PHPUnit_Extensions_Database_DataSet_ITable $actual, $message = '') + { + $constraint = new PHPUnit_Extensions_Database_Constraint_TableIsEqual($expected); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two given datasets are equal. + * + * @param PHPUnit_Extensions_Database_DataSet_ITable $expected + * @param PHPUnit_Extensions_Database_DataSet_ITable $actual + * @param string $message + */ + public static function assertDataSetsEqual(PHPUnit_Extensions_Database_DataSet_IDataSet $expected, PHPUnit_Extensions_Database_DataSet_IDataSet $actual, $message = '') + { + $constraint = new PHPUnit_Extensions_Database_Constraint_DataSetIsEqual($expected); + + self::assertThat($actual, $constraint, $message); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Command.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Command.php new file mode 100644 index 00000000..173016e7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Command.php @@ -0,0 +1,92 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Delegates database extension commands to the appropriate mode classes. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_Command +{ + /** + * @var PHPUnit_Extensions_Database_UI_IModeFactory + */ + protected $modeFactory; + + /** + * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory + */ + public function __construct(PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory) + { + $this->modeFactory = $modeFactory; + } + + /** + * Executes the database extension ui. + * + * @param PHPUnit_Extensions_Database_UI_IMedium $medium + * @param PHPUnit_Extensions_Database_UI_Context $context + */ + public function main(PHPUnit_Extensions_Database_UI_IMedium $medium, PHPUnit_Extensions_Database_UI_Context $context) + { + try { + $medium->buildContext($context); + $mode = $this->modeFactory->getMode($context->getMode()); + $mode->execute($context->getModeArguments(), $medium); + + } catch (Exception $e) { + $medium->handleException($e); + } + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Context.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Context.php new file mode 100644 index 00000000..8b49034f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Context.php @@ -0,0 +1,103 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Holds the context of a particular database extension ui call. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_Context +{ + /** + * @var string + */ + protected $mode; + + /** + * @var array + */ + protected $modeArguments; + + /** + * @param string $mode + */ + public function setMode($mode) + { + $this->mode = $mode; + } + + /** + * @return string + */ + public function getMode() + { + return $this->mode; + } + + /** + * @param array $arguments + */ + public function setModeArguments(array $arguments) + { + $this->mode_arguments = $arguments; + } + + /** + * @return array + */ + public function getModeArguments() + { + return $this->mode_arguments; + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMedium.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMedium.php new file mode 100644 index 00000000..ee58b3e2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMedium.php @@ -0,0 +1,77 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/UI/IMediumPrinter.php'); + +/** + * Defines the interface necessary to create new mediums. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_UI_IMedium extends PHPUnit_Extensions_Database_UI_IMediumPrinter +{ + /** + * Builds the context for the application. + * + * @param PHPUnit_Extensions_Database_UI_Context $context + */ + public function buildContext(PHPUnit_Extensions_Database_UI_Context $context); + + /** + * Handles the displaying of exceptions received from the application. + * + * @param Exception $e + */ + public function handleException(Exception $e); +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMediumPrinter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMediumPrinter.php new file mode 100644 index 00000000..4b2eb883 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMediumPrinter.php @@ -0,0 +1,75 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Defines the interface necessary to create new medium printers. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_UI_IMediumPrinter +{ + /** + * Prints standard output messages. + * + * @param string $message + */ + public function output($message); + + /** + * Prints standard error messages. + * + * @param string $message + */ + public function error($message); +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMode.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMode.php new file mode 100644 index 00000000..e389669c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IMode.php @@ -0,0 +1,69 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Defines the interface necessary to create new modes + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_UI_IMode +{ + /** + * Executes the mode using the given arguments and medium. + * + * @param array $modeArguments + * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium + */ + public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium); +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IModeFactory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IModeFactory.php new file mode 100644 index 00000000..e7b07878 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/IModeFactory.php @@ -0,0 +1,76 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Defines the interface necessary to create new mode factories + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +interface PHPUnit_Extensions_Database_UI_IModeFactory +{ + /** + * Generates a new mode based on a given name. + * + * @param string $mode + * @return PHPUnit_Extensions_Database_UI_IMode + */ + public function getMode($mode); + + /** + * Returns the names of valid modes this factory can create. + * + * @return array + */ + public function getModeList(); +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/InvalidModeException.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/InvalidModeException.php new file mode 100644 index 00000000..bb489123 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/InvalidModeException.php @@ -0,0 +1,99 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * An exception thrown when an invalid mode is requested from a mode factory. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_InvalidModeException extends LogicException +{ + /** + * @var string + */ + protected $mode; + + /** + * @var PHPUnit_Extensions_Database_UI_IModeFactory + */ + protected $modeFactory; + + /** + * @param string $mode + * @param string $msg + * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory + */ + public function __construct($mode, $msg, PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory) + { + $this->mode = $mode; + $this->modeFactory = $modeFactory; + parent::__construct($msg); + } + + /** + * @return string + */ + public function getMode() + { + return $this->mode; + } + + /** + * @return array + */ + public function getValidModes() + { + return $this->modeFactory->getModeList(); + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Mediums/Text.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Mediums/Text.php new file mode 100644 index 00000000..558e4878 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Mediums/Text.php @@ -0,0 +1,143 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/UI/IMedium.php'); + +/** + * A text medium for the database extension tool. + * + * This class builds the call context based on command line parameters and + * prints output to stdout and stderr as appropriate. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_Mediums_Text implements PHPUnit_Extensions_Database_UI_IMedium +{ + /** + * @var array + */ + protected $arguments; + + /** + * @var string + */ + protected $command; + + /** + * @param array $arguments + */ + public function __construct(Array $arguments) + { + $this->arguments = $arguments; + } + + /** + * Builds the context for the application. + * + * @param PHPUnit_Extensions_Database_UI_Context $context + */ + public function buildContext(PHPUnit_Extensions_Database_UI_Context $context) + { + $arguments = $this->arguments; + $this->command = array_shift($arguments); + + $context->setMode(array_shift($arguments)); + $context->setModeArguments($arguments); + } + + /** + * Handles the displaying of exceptions received from the application. + * + * @param Exception $e + */ + public function handleException(Exception $e) + { + try { + throw $e; + } catch (PHPUnit_Extensions_Database_UI_InvalidModeException $invalidMode) { + if ($invalidMode->getMode() == '') { + $this->error('Please Specify a Command!' . PHP_EOL); + } else { + $this->error('Command Does Not Exist: ' . $invalidMode->getMode() . PHP_EOL); + } + $this->error('Valid Commands:' . PHP_EOL); + + foreach ($invalidMode->getValidModes() as $mode) { + $this->error(' ' . $mode . PHP_EOL); + } + } catch (Exception $e) { + $this->error('Unknown Error: ' . $e->getMessage() . PHP_EOL); + } + } + + /** + * Prints the message to stdout. + * + * @param string $message + */ + public function output($message) + { + echo $message; + } + + /** + * Prints the message to stderr + * + * @param string $message + */ + public function error($message) + { + fputs(STDERR, $message); + } +} + +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/ModeFactory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/ModeFactory.php new file mode 100644 index 00000000..564a1d32 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/ModeFactory.php @@ -0,0 +1,136 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/UI/IModeFactory.php'); +require_once ('PHPUnit/Extensions/Database/UI/InvalidModeException.php'); + +/** + * The default factory for db extension modes. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de//** + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_ModeFactory implements PHPUnit_Extensions_Database_UI_IModeFactory +{ + /** + * Generates a new mode based on a given name. + * + * @param string $mode + * @return PHPUnit_Extensions_Database_UI_IMode + */ + public function getMode($mode) + { + if ($mode == '') { + throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'A mode was not provided.', $this); + } + + $modeMap = $this->getModeMap(); + if (isset($modeMap[$mode])) { + $modeClass = $this->getModeClass($mode, $modeMap[$mode]); + + return new $modeClass(); + } else { + throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode does not exist. Attempting to load mode ' . $mode, $this); + } + } + + /** + * Returns the names of valid modes this factory can create. + * + * @return array + */ + public function getModeList() + { + return array_keys($this->getModeMap()); + } + + /** + * Returns a map of modes to class name parts + * + * @return array + */ + protected function getModeMap() + { + return array('export-dataset' => 'ExportDataSet'); + } + + /** + * Given a $mode label and a $mode_name class part attempts to return the + * class name necessary to instantiate the mode. + * + * @param string $mode + * @param string $mode_name + * @return string + */ + protected function getModeClass($mode, $mode_name) + { + $modeClass = 'PHPUnit_Extensions_Database_UI_Modes_' . $mode_name; + $modeFile = dirname(__FILE__) . '/Modes/' . $mode_name . '.php'; + + if (class_exists($modeClass)) { + return $modeClass; + } + + if (!is_readable($modeFile)) { + throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode\'s file could not be loaded. Trying file ' . $modeFile, $this); + } + + require_once ($modeFile); + + if (!class_exists($modeClass)) { + throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode class was not found in the file. Expecting class name ' . $modeClass, $this); + } + + return $modeClass; + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet.php new file mode 100644 index 00000000..a9068e03 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet.php @@ -0,0 +1,128 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once ('PHPUnit/Extensions/Database/UI/IMode.php'); +require_once ('PHPUnit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/CompositeDataSet.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/Specs/Factory.php'); +require_once ('PHPUnit/Extensions/Database/DataSet/Persistors/Factory.php'); + +/** + * The class for the export-dataset command. + * + * This command is used to convert existing data sets or data in the database + * into a valid data set format. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet implements PHPUnit_Extensions_Database_UI_IMode +{ + /** + * Executes the export dataset command. + * + * @param array $modeArguments + * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium + */ + public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium) + { + $arguments = new PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments($modeArguments); + + if (FALSE && !$arguments->areValid()) { + throw new InvalidArgumentException("The arguments for this command are incorrect."); + } + + $datasets = array(); + foreach ($arguments->getArgumentArray('dataset') as $argString) { + $datasets[] = $this->getDataSetFromArgument($argString, $arguments->getDatabases()); + } + + $finalDataset = new PHPUnit_Extensions_Database_DataSet_CompositeDataSet($datasets); + + $outputDataset = $this->getPersistorFromArgument($arguments->getSingleArgument('output')); + $outputDataset->write($finalDataset); + } + + /** + * Returns the correct dataset given an argument containing a dataset spec. + * + * @param string $argString + * @param array $databaseList + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected function getDataSetFromArgument($argString, $databaseList) + { + $dataSetSpecFactory = new PHPUnit_Extensions_Database_DataSet_Specs_Factory(); + list($type, $dataSetSpecStr) = explode(':', $argString, 2); + $dataSetSpec = $dataSetSpecFactory->getDataSetSpecByType($type); + + if ($dataSetSpec instanceof PHPUnit_Extensions_Database_IDatabaseListConsumer) { + $dataSetSpec->setDatabases($databaseList); + } + + return $dataSetSpec->getDataSet($dataSetSpecStr); + } + + /** + * Returns the correct persistor given an argument containing a persistor spec. + * + * @param string $argString + * @return PHPUnit_Extensions_Database_DataSet_IPersistable + */ + protected function getPersistorFromArgument($argString) + { + $persistorFactory = new PHPUnit_Extensions_Database_DataSet_Persistors_Factory(); + list($type, $spec) = explode(':', $argString, 2); + return $persistorFactory->getPersistorBySpec($type, $spec); + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php new file mode 100644 index 00000000..76978905 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php @@ -0,0 +1,156 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +/** + * Represents arguments received from a medium. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2010 Mike Lively + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments +{ + /** + * @var array + */ + protected $arguments = array(); + + /** + * @param array $arguments + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + list($argName, $argValue) = explode('=', $argument, 2); + + $argName = trim($argName, '-'); + + if (!isset($this->arguments[$argName])) { + $this->arguments[$argName] = array(); + } + + $this->arguments[$argName][] = $argValue; + } + } + + /** + * Returns an array of arguments matching the given $argName + * + * @param string $argName + * @return array + */ + public function getArgumentArray($argName) + { + if ($this->argumentIsSet($argName)) { + return $this->arguments[$argName]; + } else { + return NULL; + } + } + + /** + * Returns a single argument value. + * + * If $argName points to an array the first argument will be returned. + * + * @param string $argName + * @return mixed + */ + public function getSingleArgument($argName) + { + if ($this->argumentIsSet($argName)) { + return reset($this->arguments[$argName]); + } else { + return NULL; + } + } + + /** + * Returns whether an argument is set. + * + * @param string $argName + * @return bool + */ + public function argumentIsSet($argName) + { + return array_key_exists($argName, $this->arguments); + } + + /** + * Returns an array containing the names of all arguments provided. + * + * @return array + */ + public function getArgumentNames() + { + return array_keys($this->arguments); + } + + /** + * Returns an array of database arguments keyed by name. + * + * @todo this should be moved. + * @return array + */ + public function getDatabases() + { + $databases = $this->getArgumentArray('database'); + + $retDb = array(); + foreach ($databases as $db) { + list($name, $arg) = explode(':', $db, 2); + $retDb[$name] = $arg; + } + + return $retDb; + } +} + +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/GroupTestSuite.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/GroupTestSuite.php new file mode 100644 index 00000000..486438ea --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/GroupTestSuite.php @@ -0,0 +1,106 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * We have a TestSuite object A. + * In TestSuite object A we have Tests tagged with @group. + * We want a TestSuite object B that contains TestSuite objects C, D, ... + * for the Tests tagged with @group C, @group D, ... + * Running the Tests from TestSuite object B results in Tests tagged with both + * @group C and @group D in TestSuite object A to be run twice . + * + * + * $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D')); + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_GroupTestSuite extends PHPUnit_Framework_TestSuite +{ + public function __construct(PHPUnit_Framework_TestSuite $suite, array $groups) + { + $groupSuites = array(); + $name = $suite->getName(); + + foreach ($groups as $group) { + $groupSuites[$group] = new PHPUnit_Framework_TestSuite($name . ' - ' . $group); + $this->addTest($groupSuites[$group]); + } + + $tests = new RecursiveIteratorIterator( + new PHPUnit_Util_TestSuiteIterator($suite), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($tests as $test) { + if ($test instanceof PHPUnit_Framework_TestCase) { + $testGroups = PHPUnit_Util_Test::getGroups( + get_class($test), $test->getName(FALSE) + ); + + foreach ($groups as $group) { + foreach ($testGroups as $testGroup) { + if ($group == $testGroup) { + $groupSuites[$group]->addTest($test); + } + } + } + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/OutputTestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/OutputTestCase.php new file mode 100644 index 00000000..742e6f95 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/OutputTestCase.php @@ -0,0 +1,210 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestCase that expects a specified output. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +abstract class PHPUnit_Extensions_OutputTestCase extends PHPUnit_Framework_TestCase +{ + /** + * @var string + */ + protected $expectedRegex = NULL; + + /** + * @var string + */ + protected $expectedString = NULL; + + /** + * @var string + */ + protected $output = ''; + + /** + * @var boolean + */ + protected $obActive = FALSE; + + /** + * @var mixed + */ + protected $outputCallback = FALSE; + + /** + * @return bool + */ + public function setOutputCallback($callback) + { + if (is_callable($callback)) { + $this->outputCallback = $callback; + $set = TRUE; + } else { + $set = FALSE; + } + + return $set; + } + + /** + * @return string + */ + public function normalizeOutput($buffer) + { + return str_replace("\r", '', $buffer); + } + + /** + * @return string + */ + public function getActualOutput() + { + if (!$this->obActive) { + return $this->output; + } else { + return ob_get_contents(); + } + } + + /** + * @return string + */ + public function expectedRegex() + { + return $this->expectedRegex; + } + + /** + * @param string $expectedRegex + */ + public function expectOutputRegex($expectedRegex) + { + if ($this->expectedString !== NULL) { + throw new PHPUnit_Framework_Exception; + } + + if (is_string($expectedRegex) || is_null($expectedRegex)) { + $this->expectedRegex = $expectedRegex; + } + } + + /** + * @return string + */ + public function expectedString() + { + return $this->expectedOutput; + } + + /** + * @param string $expectedString + */ + public function expectOutputString($expectedString) + { + if ($this->expectedRegex !== NULL) { + throw new PHPUnit_Framework_Exception; + } + + if (is_string($expectedString) || is_null($expectedString)) { + $this->expectedString = $expectedString; + } + } + + /** + * @return mixed + * @throws RuntimeException + */ + protected function runTest() + { + ob_start(); + $this->obActive = TRUE; + + try { + $testResult = parent::runTest(); + } + + catch (Exception $e) { + ob_end_clean(); + $this->obActive = FALSE; + throw $e; + } + + if ($this->outputCallback === FALSE) { + $this->output = ob_get_contents(); + } else { + $this->output = call_user_func_array($this->outputCallback, array(ob_get_contents())); + } + + ob_end_clean(); + $this->obActive = FALSE; + + if ($this->expectedRegex !== NULL) { + $this->assertRegExp($this->expectedRegex, $this->output); + $this->expectedRegex = NULL; + } + + else if ($this->expectedString !== NULL) { + $this->assertEquals($this->expectedString, $this->output); + $this->expectedString = NULL; + } + + return $testResult; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PerformanceTestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PerformanceTestCase.php new file mode 100644 index 00000000..c219a303 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PerformanceTestCase.php @@ -0,0 +1,121 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.1.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Timer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestCase that expects a TestCase to be executed + * meeting a given time limit. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +abstract class PHPUnit_Extensions_PerformanceTestCase extends PHPUnit_Framework_TestCase +{ + /** + * @var integer + */ + protected $maxRunningTime = 0; + + /** + * @return mixed + * @throws RuntimeException + */ + protected function runTest() + { + PHPUnit_Util_Timer::start(); + $testResult = parent::runTest(); + $time = PHPUnit_Util_Timer::stop(); + + if ($this->maxRunningTime != 0 && + $time > $this->maxRunningTime) { + $this->fail( + sprintf( + 'expected running time: <= %s but was: %s', + + $this->maxRunningTime, + $time + ) + ); + } + + return $testResult; + } + + /** + * @param integer $maxRunningTime + * @throws InvalidArgumentException + * @since Method available since Release 2.3.0 + */ + public function setMaxRunningTime($maxRunningTime) + { + if (is_integer($maxRunningTime) && + $maxRunningTime >= 0) { + $this->maxRunningTime = $maxRunningTime; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'positive integer'); + } + } + + /** + * @return integer + * @since Method available since Release 2.3.0 + */ + public function getMaxRunningTime() + { + return $this->maxRunningTime; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestCase.php new file mode 100644 index 00000000..2b2d2098 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestCase.php @@ -0,0 +1,264 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.4 + */ + +if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('PEAR/RunTest.php')) { + $currentErrorReporting = error_reporting(E_ERROR | E_WARNING | E_PARSE); + PHPUnit_Util_Filesystem::collectStart(); + require_once 'PEAR/RunTest.php'; + error_reporting($currentErrorReporting); + + PHPUnit_Util_Filesystem::collectEndAndAddToBlacklist(); +} + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Extensions/PhptTestCase/Logger.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Wrapper to run .phpt test cases. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * The filename of the .phpt file. + * + * @var string + */ + protected $filename; + + /** + * Options for PEAR_RunTest. + * + * @var array + */ + protected $options = array(); + + /** + * Constructs a test case with the given filename. + * + * @param string $filename + * @param array $options + */ + public function __construct($filename, array $options = array()) + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_file($filename)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'File "%s" does not exist.', + $filename + ) + ); + } + + $this->filename = $filename; + $this->options = $options; + } + + /** + * Counts the number of test cases executed by run(TestResult result). + * + * @return integer + */ + public function count() + { + return 1; + } + + /** + * Runs a test and collects its result in a TestResult instance. + * + * @param PHPUnit_Framework_TestResult $result + * @param array $options + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = NULL, array $options = array()) + { + if (!class_exists('PEAR_RunTest', FALSE)) { + throw new PHPUnit_Framework_Exception('Class PEAR_RunTest not found.'); + } + + if (isset($GLOBALS['_PEAR_destructor_object_list']) && + is_array($GLOBALS['_PEAR_destructor_object_list']) && + !empty($GLOBALS['_PEAR_destructor_object_list'])) { + $pearDestructorObjectListCount = count($GLOBALS['_PEAR_destructor_object_list']); + } else { + $pearDestructorObjectListCount = 0; + } + + if ($result === NULL) { + $result = new PHPUnit_Framework_TestResult; + } + + $coverage = $result->getCollectCodeCoverageInformation(); + $options = array_merge($options, $this->options); + + if (!isset($options['include_path'])) { + $options['include_path'] = get_include_path(); + } + + if ($coverage) { + $options['coverage'] = TRUE; + } else { + $options['coverage'] = FALSE; + } + + $currentErrorReporting = error_reporting(E_ERROR | E_WARNING | E_PARSE); + $runner = new PEAR_RunTest(new PHPUnit_Extensions_PhptTestCase_Logger, $options); + + if ($coverage) { + $runner->xdebug_loaded = TRUE; + } else { + $runner->xdebug_loaded = FALSE; + } + + $result->startTest($this); + + PHPUnit_Util_Timer::start(); + $buffer = $runner->run($this->filename, $options); + $time = PHPUnit_Util_Timer::stop(); + error_reporting($currentErrorReporting); + $base = basename($this->filename); + $path = dirname($this->filename); + $coverageFile = $path . DIRECTORY_SEPARATOR . str_replace('.phpt', '.xdebug', $base); + $diffFile = $path . DIRECTORY_SEPARATOR . str_replace('.phpt', '.diff', $base); + $expFile = $path . DIRECTORY_SEPARATOR . str_replace('.phpt', '.exp', $base); + $logFile = $path . DIRECTORY_SEPARATOR . str_replace('.phpt', '.log', $base); + $outFile = $path . DIRECTORY_SEPARATOR . str_replace('.phpt', '.out', $base); + $phpFile = $path . DIRECTORY_SEPARATOR . str_replace('.phpt', '.php', $base); + + if (file_exists($phpFile)) { + PHPUnit_Util_Filter::addFileToFilter($phpFile, 'TESTS'); + } + + if (is_object($buffer) && $buffer instanceof PEAR_Error) { + $result->addError( + $this, + new RuntimeException($buffer->getMessage()), + $time + ); + } + + else if ($buffer == 'SKIPPED') { + $result->addFailure($this, new PHPUnit_Framework_SkippedTestError, 0); + } + + else if ($buffer != 'PASSED') { + $result->addFailure( + $this, + PHPUnit_Framework_ComparisonFailure::diffEqual( + file_get_contents($expFile), + file_get_contents($outFile) + ), + $time + ); + } + + foreach (array($diffFile, $expFile, $logFile, $phpFile, $outFile) as $file) { + if (file_exists($file)) { + unlink($file); + } + } + + if ($coverage && file_exists($coverageFile)) { + eval('$coverageData = ' . file_get_contents($coverageFile) . ';'); + unset($coverageData[$phpFile]); + + $result->appendCodeCoverageInformation($this, $coverageData); + unlink($coverageFile); + } + + $result->endTest($this, $time); + + // Do not invoke PEAR's destructor mechanism for PHP 4 + // as it raises an E_STRICT. + if ($pearDestructorObjectListCount == 0) { + unset($GLOBALS['_PEAR_destructor_object_list']); + } else { + $count = count($GLOBALS['_PEAR_destructor_object_list']) - $pearDestructorObjectListCount; + + for ($i = 0; $i < $count; $i++) { + array_pop($GLOBALS['_PEAR_destructor_object_list']); + } + } + + return $result; + } + + /** + * Returns the name of the test case. + * + * @return string + */ + public function getName() + { + return $this->toString(); + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + return $this->filename; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestCase/Logger.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestCase/Logger.php new file mode 100644 index 00000000..c41e39c2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestCase/Logger.php @@ -0,0 +1,68 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.4 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Dummy logger for PEAR_RunTest. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Extensions_PhptTestCase_Logger +{ + public function log($level, $msg, $append_crlf = TRUE) + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestSuite.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestSuite.php new file mode 100644 index 00000000..70a72f90 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/PhptTestSuite.php @@ -0,0 +1,94 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.4 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/FilterIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Suite for .phpt test cases. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Extensions_PhptTestSuite extends PHPUnit_Framework_TestSuite +{ + /** + * Constructs a new TestSuite for .phpt test cases. + * + * @param string $directory + * @param array $options Array with ini settings for the php instance run, + * key being the name if the setting, value the ini value. + * @throws InvalidArgumentException + */ + public function __construct($directory, array $options = array()) + { + if (is_string($directory) && is_dir($directory)) { + $this->setName($directory); + + $iterator = new PHPUnit_Util_FilterIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($directory) + ), + '.phpt' + ); + + foreach ($iterator as $testFile) { + $this->addTestFile($testFile->getPathname(), TRUE, $options); + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'directory name'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/RepeatedTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/RepeatedTest.php new file mode 100644 index 00000000..a30b2776 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/RepeatedTest.php @@ -0,0 +1,158 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Extensions/TestDecorator.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A Decorator that runs a test repeatedly. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Extensions_RepeatedTest extends PHPUnit_Extensions_TestDecorator +{ + /** + * @var mixed + */ + protected $filter = FALSE; + + /** + * @var array + */ + protected $groups = array(); + + /** + * @var array + */ + protected $excludeGroups = array(); + + /** + * @var integer + */ + protected $timesRepeat = 1; + + /** + * Constructor. + * + * @param PHPUnit_Framework_Test $test + * @param integer $timesRepeat + * @param mixed $filter + * @param array $groups + * @param array $excludeGroups + * @param boolean $processIsolation + * @throws InvalidArgumentException + */ + public function __construct(PHPUnit_Framework_Test $test, $timesRepeat = 1, $filter = FALSE, array $groups = array(), array $excludeGroups = array(), $processIsolation = FALSE) + { + parent::__construct($test); + + if (is_integer($timesRepeat) && + $timesRepeat >= 0) { + $this->timesRepeat = $timesRepeat; + } else { + throw new InvalidArgumentException( + 'Argument 2 must be a positive integer.' + ); + } + + $this->filter = $filter; + $this->groups = $groups; + $this->excludeGroups = $excludeGroups; + $this->processIsolation = $processIsolation; + } + + /** + * Counts the number of test cases that + * will be run by this test. + * + * @return integer + */ + public function count() + { + return $this->timesRepeat * count($this->test); + } + + /** + * Runs the decorated test and collects the + * result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws InvalidArgumentException + */ + public function run(PHPUnit_Framework_TestResult $result = NULL) + { + if ($result === NULL) { + $result = $this->createResult(); + } + + for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) { + if ($this->test instanceof PHPUnit_Framework_TestSuite) { + $this->test->run( + $result, + $this->filter, + $this->groups, + $this->excludeGroups, + $this->processIsolation + ); + } else { + $this->test->run($result); + } + } + + return $result; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase.php new file mode 100644 index 00000000..086fd7ea --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase.php @@ -0,0 +1,1072 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Log/Database.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Test.php'; +require_once 'PHPUnit/Util/XML.php'; +require_once 'PHPUnit/Extensions/SeleniumTestCase/Driver.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * TestCase class that uses Selenium to provide + * the functionality required for web testing. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +abstract class PHPUnit_Extensions_SeleniumTestCase extends PHPUnit_Framework_TestCase +{ + /** + * @var array + */ + public static $browsers = array(); + + /** + * @var boolean + */ + protected $autoStop = TRUE; + + /** + * @var string + */ + protected $browserName; + + /** + * @var boolean + */ + protected $collectCodeCoverageInformation = FALSE; + + /** + * @var string + */ + protected $coverageScriptUrl = ''; + + /** + * @var PHPUnit_Extensions_SeleniumTestCase_Driver[] + */ + protected $drivers = array(); + + /** + * @var boolean + */ + protected $inDefaultAssertions = FALSE; + + /** + * @var string + */ + protected $testId; + + /** + * @var array + * @access protected + */ + protected $verificationErrors = array(); + + /** + * @var boolean + */ + protected $captureScreenshotOnFailure = FALSE; + + /** + * @var string + */ + protected $screenshotPath = ''; + + /** + * @var string + */ + protected $screenshotUrl = ''; + + /** + * @param string $name + * @param array $data + * @param string $dataName + * @param array $browser + * @throws InvalidArgumentException + */ + public function __construct($name = NULL, array $data = array(), $dataName = '', array $browser = array()) + { + parent::__construct($name, $data, $dataName); + $this->testId = md5(uniqid(rand(), TRUE)); + $this->getDriver($browser); + } + + /** + * @param string $className + * @return PHPUnit_Framework_TestSuite + */ + public static function suite($className) + { + $suite = new PHPUnit_Framework_TestSuite; + $suite->setName($className); + + $class = new ReflectionClass($className); + $classGroups = PHPUnit_Util_Test::getGroups($className); + $staticProperties = $class->getStaticProperties(); + + // Create tests from Selenese/HTML files. + if (isset($staticProperties['seleneseDirectory']) && + is_dir($staticProperties['seleneseDirectory'])) { + $files = array_merge( + self::getSeleneseFiles($staticProperties['seleneseDirectory'], '.htm'), + self::getSeleneseFiles($staticProperties['seleneseDirectory'], '.html') + ); + + // Create tests from Selenese/HTML files for multiple browsers. + if (!empty($staticProperties['browsers'])) { + foreach ($staticProperties['browsers'] as $browser) { + $browserSuite = new PHPUnit_Framework_TestSuite; + $browserSuite->setName($className . ': ' . $browser['name']); + + foreach ($files as $file) { + $browserSuite->addTest( + new $className($file, array(), '', $browser), + $classGroups + ); + } + + $suite->addTest($browserSuite); + } + } + + // Create tests from Selenese/HTML files for single browser. + else { + foreach ($files as $file) { + $suite->addTest(new $className($file), $classGroups); + } + } + } + + // Create tests from test methods for multiple browsers. + if (!empty($staticProperties['browsers'])) { + foreach ($staticProperties['browsers'] as $browser) { + $browserSuite = new PHPUnit_Framework_TestSuite; + $browserSuite->setName($className . ': ' . $browser['name']); + + foreach ($class->getMethods() as $method) { + if (PHPUnit_Framework_TestSuite::isPublicTestMethod($method)) { + $name = $method->getName(); + $data = PHPUnit_Util_Test::getProvidedData($className, $name); + $groups = PHPUnit_Util_Test::getGroups($className, $name); + + // Test method with @dataProvider. + if (is_array($data) || $data instanceof Iterator) { + $dataSuite = new PHPUnit_Framework_TestSuite_DataProvider( + $className . '::' . $name + ); + + foreach ($data as $_dataName => $_data) { + $dataSuite->addTest( + new $className($name, $_data, $_dataName, $browser), + $groups + ); + } + + $browserSuite->addTest($dataSuite); + } + + // Test method without @dataProvider. + else { + $browserSuite->addTest( + new $className($name, array(), '', $browser), $groups + ); + } + } + } + + $suite->addTest($browserSuite); + } + } + + // Create tests from test methods for single browser. + else { + foreach ($class->getMethods() as $method) { + if (PHPUnit_Framework_TestSuite::isPublicTestMethod($method)) { + $name = $method->getName(); + $data = PHPUnit_Util_Test::getProvidedData($className, $name); + $groups = PHPUnit_Util_Test::getGroups($className, $name); + + // Test method with @dataProvider. + if (is_array($data) || $data instanceof Iterator) { + $dataSuite = new PHPUnit_Framework_TestSuite_DataProvider( + $className . '::' . $name + ); + + foreach ($data as $_dataName => $_data) { + $dataSuite->addTest( + new $className($name, $_data, $_dataName), + $groups + ); + } + + $suite->addTest($dataSuite); + } + + // Test method without @dataProvider. + else { + $suite->addTest( + new $className($name), $groups + ); + } + } + } + } + + return $suite; + } + + /** + * Runs the test case and collects the results in a TestResult object. + * If no TestResult object is passed a new one will be created. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws InvalidArgumentException + */ + public function run(PHPUnit_Framework_TestResult $result = NULL) + { + if ($result === NULL) { + $result = $this->createResult(); + } + + $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation(); + + foreach ($this->drivers as $driver) { + $driver->setCollectCodeCoverageInformation( + $this->collectCodeCoverageInformation + ); + } + + $result->run($this); + + if ($this->collectCodeCoverageInformation) { + $result->appendCodeCoverageInformation( + $this, $this->getCodeCoverage() + ); + } + + return $result; + } + + /** + * @param array $browser + * @return PHPUnit_Extensions_SeleniumTestCase_Driver + * @since Method available since Release 3.3.0 + */ + protected function getDriver(array $browser) + { + if (isset($browser['name'])) { + if (!is_string($browser['name'])) { + throw new InvalidArgumentException( + 'Array element "name" is no string.' + ); + } + } else { + $browser['name'] = ''; + } + + if (isset($browser['browser'])) { + if (!is_string($browser['browser'])) { + throw new InvalidArgumentException( + 'Array element "browser" is no string.' + ); + } + } else { + $browser['browser'] = ''; + } + + if (isset($browser['host'])) { + if (!is_string($browser['host'])) { + throw new InvalidArgumentException( + 'Array element "host" is no string.' + ); + } + } else { + $browser['host'] = 'localhost'; + } + + if (isset($browser['port'])) { + if (!is_int($browser['port'])) { + throw new InvalidArgumentException( + 'Array element "port" is no integer.' + ); + } + } else { + $browser['port'] = 4444; + } + + if (isset($browser['timeout'])) { + if (!is_int($browser['timeout'])) { + throw new InvalidArgumentException( + 'Array element "timeout" is no integer.' + ); + } + } else { + $browser['timeout'] = 30; + } + + if (isset($browser['httpTimeout'])) { + if (!is_int($browser['httpTimeout'])) { + throw new InvalidArgumentException( + 'Array element "httpTimeout" is no integer.' + ); + } + } else { + $browser['httpTimeout'] = 45; + } + + $driver = new PHPUnit_Extensions_SeleniumTestCase_Driver; + $driver->setName($browser['name']); + $driver->setBrowser($browser['browser']); + $driver->setHost($browser['host']); + $driver->setPort($browser['port']); + $driver->setTimeout($browser['timeout']); + $driver->setHttpTimeout($browser['httpTimeout']); + $driver->setTestCase($this); + $driver->setTestId($this->testId); + + $this->drivers[] = $driver; + + return $driver; + } + + /** + * @throws RuntimeException + */ + protected function runTest() + { + $this->start(); + + if (!is_file($this->name)) { + parent::runTest(); + } else { + $this->runSelenese($this->name); + } + + if (!empty($this->verificationErrors)) { + $this->fail(implode("\n", $this->verificationErrors)); + } + + if ($this->autoStop) { + try { + $this->stop(); + } + + catch (RuntimeException $e) { + } + } + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + $buffer = parent::toString(); + + if (!empty($this->browserName)) { + $buffer .= ' with browser ' . $this->browserName; + } + + return $buffer; + } + + /** + * @param boolean $autoStop + * @throws InvalidArgumentException + */ + public function setAutoStop($autoStop) + { + if (!is_bool($autoStop)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->autoStop = $autoStop; + } + + /** + * Runs a test from a Selenese (HTML) specification. + * + * @param string $filename + */ + public function runSelenese($filename) + { + $document = PHPUnit_Util_XML::loadFile($filename, TRUE); + $xpath = new DOMXPath($document); + $rows = $xpath->query('body/table/tbody/tr'); + + foreach ($rows as $row) { + $action = NULL; + $arguments = array(); + $columns = $xpath->query('td', $row); + + foreach ($columns as $column) { + if ($action === NULL) { + $action = PHPUnit_Util_XML::nodeToText($column); + } else { + $arguments[] = PHPUnit_Util_XML::nodeToText($column); + } + } + + if (method_exists($this, $action)) { + call_user_func_array(array($this, $action), $arguments); + } else { + $this->__call($action, $arguments); + } + } + } + + /** + * Delegate method calls to the driver. + * + * @param string $command + * @param array $arguments + * @return mixed + * @method unknown addLocationStrategy() + * @method unknown addLocationStrategyAndWait() + * @method unknown addScript() + * @method unknown addScriptAndWait() + * @method unknown addSelection() + * @method unknown addSelectionAndWait() + * @method unknown allowNativeXpath() + * @method unknown allowNativeXpathAndWait() + * @method unknown altKeyDown() + * @method unknown altKeyDownAndWait() + * @method unknown altKeyUp() + * @method unknown altKeyUpAndWait() + * @method unknown answerOnNextPrompt() + * @method unknown assignId() + * @method unknown assignIdAndWait() + * @method unknown attachFile() + * @method unknown break() + * @method unknown captureEntirePageScreenshot() + * @method unknown captureEntirePageScreenshotAndWait() + * @method unknown captureEntirePageScreenshotToStringAndWait() + * @method unknown captureScreenshotAndWait() + * @method unknown captureScreenshotToStringAndWait() + * @method unknown check() + * @method unknown checkAndWait() + * @method unknown chooseCancelOnNextConfirmation() + * @method unknown chooseCancelOnNextConfirmationAndWait() + * @method unknown chooseOkOnNextConfirmation() + * @method unknown chooseOkOnNextConfirmationAndWait() + * @method unknown click() + * @method unknown clickAndWait() + * @method unknown clickAt() + * @method unknown clickAtAndWait() + * @method unknown close() + * @method unknown contextMenu() + * @method unknown contextMenuAndWait() + * @method unknown contextMenuAt() + * @method unknown contextMenuAtAndWait() + * @method unknown controlKeyDown() + * @method unknown controlKeyDownAndWait() + * @method unknown controlKeyUp() + * @method unknown controlKeyUpAndWait() + * @method unknown createCookie() + * @method unknown createCookieAndWait() + * @method unknown deleteAllVisibleCookies() + * @method unknown deleteAllVisibleCookiesAndWait() + * @method unknown deleteCookie() + * @method unknown deleteCookieAndWait() + * @method unknown deselectPopUp() + * @method unknown deselectPopUpAndWait() + * @method unknown doubleClick() + * @method unknown doubleClickAndWait() + * @method unknown doubleClickAt() + * @method unknown doubleClickAtAndWait() + * @method unknown dragAndDrop() + * @method unknown dragAndDropAndWait() + * @method unknown dragAndDropToObject() + * @method unknown dragAndDropToObjectAndWait() + * @method unknown dragDrop() + * @method unknown dragDropAndWait() + * @method unknown echo() + * @method unknown fireEvent() + * @method unknown fireEventAndWait() + * @method unknown focus() + * @method unknown focusAndWait() + * @method string getAlert() + * @method array getAllButtons() + * @method array getAllFields() + * @method array getAllLinks() + * @method array getAllWindowIds() + * @method array getAllWindowNames() + * @method array getAllWindowTitles() + * @method string getAttribute() + * @method array getAttributeFromAllWindows() + * @method string getBodyText() + * @method string getConfirmation() + * @method string getCookie() + * @method string getCookieByName() + * @method integer getCursorPosition() + * @method integer getElementHeight() + * @method integer getElementIndex() + * @method integer getElementPositionLeft() + * @method integer getElementPositionTop() + * @method integer getElementWidth() + * @method string getEval() + * @method string getExpression() + * @method string getHtmlSource() + * @method string getLocation() + * @method string getLogMessages() + * @method integer getMouseSpeed() + * @method string getPrompt() + * @method array getSelectOptions() + * @method string getSelectedId() + * @method array getSelectedIds() + * @method string getSelectedIndex() + * @method array getSelectedIndexes() + * @method string getSelectedLabel() + * @method array getSelectedLabels() + * @method string getSelectedValue() + * @method array getSelectedValues() + * @method unknown getSpeed() + * @method unknown getSpeedAndWait() + * @method string getTable() + * @method string getText() + * @method string getTitle() + * @method string getValue() + * @method boolean getWhetherThisFrameMatchFrameExpression() + * @method boolean getWhetherThisWindowMatchWindowExpression() + * @method integer getXpathCount() + * @method unknown goBack() + * @method unknown goBackAndWait() + * @method unknown highlight() + * @method unknown highlightAndWait() + * @method unknown ignoreAttributesWithoutValue() + * @method unknown ignoreAttributesWithoutValueAndWait() + * @method boolean isAlertPresent() + * @method boolean isChecked() + * @method boolean isConfirmationPresent() + * @method boolean isCookiePresent() + * @method boolean isEditable() + * @method boolean isElementPresent() + * @method boolean isOrdered() + * @method boolean isPromptPresent() + * @method boolean isSomethingSelected() + * @method boolean isTextPresent() + * @method boolean isVisible() + * @method unknown keyDown() + * @method unknown keyDownAndWait() + * @method unknown keyDownNative() + * @method unknown keyDownNativeAndWait() + * @method unknown keyPress() + * @method unknown keyPressAndWait() + * @method unknown keyPressNative() + * @method unknown keyPressNativeAndWait() + * @method unknown keyUp() + * @method unknown keyUpAndWait() + * @method unknown keyUpNative() + * @method unknown keyUpNativeAndWait() + * @method unknown metaKeyDown() + * @method unknown metaKeyDownAndWait() + * @method unknown metaKeyUp() + * @method unknown metaKeyUpAndWait() + * @method unknown mouseDown() + * @method unknown mouseDownAndWait() + * @method unknown mouseDownAt() + * @method unknown mouseDownAtAndWait() + * @method unknown mouseMove() + * @method unknown mouseMoveAndWait() + * @method unknown mouseMoveAt() + * @method unknown mouseMoveAtAndWait() + * @method unknown mouseOut() + * @method unknown mouseOutAndWait() + * @method unknown mouseOver() + * @method unknown mouseOverAndWait() + * @method unknown mouseUp() + * @method unknown mouseUpAndWait() + * @method unknown mouseUpAt() + * @method unknown mouseUpAtAndWait() + * @method unknown mouseUpRight() + * @method unknown mouseUpRightAndWait() + * @method unknown mouseUpRightAt() + * @method unknown mouseUpRightAtAndWait() + * @method unknown open() + * @method unknown openWindow() + * @method unknown openWindowAndWait() + * @method unknown pause() + * @method unknown refresh() + * @method unknown refreshAndWait() + * @method unknown removeAllSelections() + * @method unknown removeAllSelectionsAndWait() + * @method unknown removeScript() + * @method unknown removeScriptAndWait() + * @method unknown removeSelection() + * @method unknown removeSelectionAndWait() + * @method unknown retrieveLastRemoteControlLogs() + * @method unknown rollup() + * @method unknown rollupAndWait() + * @method unknown runScript() + * @method unknown runScriptAndWait() + * @method unknown select() + * @method unknown selectAndWait() + * @method unknown selectFrame() + * @method unknown selectPopUp() + * @method unknown selectPopUpAndWait() + * @method unknown selectWindow() + * @method unknown setBrowserLogLevel() + * @method unknown setBrowserLogLevelAndWait() + * @method unknown setContext() + * @method unknown setCursorPosition() + * @method unknown setCursorPositionAndWait() + * @method unknown setMouseSpeed() + * @method unknown setMouseSpeedAndWait() + * @method unknown setSpeed() + * @method unknown setSpeedAndWait() + * @method unknown shiftKeyDown() + * @method unknown shiftKeyDownAndWait() + * @method unknown shiftKeyUp() + * @method unknown shiftKeyUpAndWait() + * @method unknown shutDownSeleniumServer() + * @method unknown store() + * @method unknown submit() + * @method unknown submitAndWait() + * @method unknown type() + * @method unknown typeAndWait() + * @method unknown typeKeys() + * @method unknown typeKeysAndWait() + * @method unknown uncheck() + * @method unknown uncheckAndWait() + * @method unknown useXpathLibrary() + * @method unknown useXpathLibraryAndWait() + * @method unknown waitForCondition() + * @method unknown waitForPageToLoad() + * @method unknown waitForPopUp() + * @method unknown windowFocus() + * @method unknown windowMaximize() + */ + public function __call($command, $arguments) + { + $result = call_user_func_array( + array($this->drivers[0], $command), $arguments + ); + + $this->verificationErrors = array_merge( + $this->verificationErrors, $this->drivers[0]->getVerificationErrors() + ); + + $this->drivers[0]->clearVerificationErrors(); + + return $result; + } + + /** + * Asserts that an element's value is equal to a given string. + * + * @param string $locator + * @param string $text + * @param string $message + */ + public function assertElementValueEquals($locator, $text, $message = '') + { + $this->assertEquals($text, $this->getValue($locator), $message); + } + + /** + * Asserts that an element's value is not equal to a given string. + * + * @param string $locator + * @param string $text + * @param string $message + */ + public function assertElementValueNotEquals($locator, $text, $message = '') + { + $this->assertNotEquals($text, $this->getValue($locator), $message); + } + + /** + * Asserts that an element's value contains a given string. + * + * @param string $locator + * @param string $text + * @param string $message + */ + public function assertElementValueContains($locator, $text, $message = '') + { + $this->assertContains($text, $this->getValue($locator), $message); + } + + /** + * Asserts that an element's value does not contain a given string. + * + * @param string $locator + * @param string $text + * @param string $message + */ + public function assertElementValueNotContains($locator, $text, $message = '') + { + $this->assertNotContains($text, $this->getValue($locator), $message); + } + + /** + * Asserts that an element contains a given string. + * + * @param string $locator + * @param string $text + * @param string $message + */ + public function assertElementContainsText($locator, $text, $message = '') + { + $this->assertContains($text, $this->getText($locator), $message); + } + + /** + * Asserts that an element does not contain a given string. + * + * @param string $locator + * @param string $text + * @param string $message + */ + public function assertElementNotContainsText($locator, $text, $message = '') + { + $this->assertNotContains($text, $this->getText($locator), $message); + } + + /** + * Asserts that a select element has a specific option. + * + * @param string $selectLocator + * @param string $option + * @param string $message + * @since Method available since Release 3.2.0 + */ + public function assertSelectHasOption($selectLocator, $option, $message = '') + { + $this->assertContains($option, $this->getSelectOptions($selectLocator), $message); + } + + /** + * Asserts that a select element does not have a specific option. + * + * @param string $selectLocator + * @param string $option + * @param string $message + * @since Method available since Release 3.2.0 + */ + public function assertSelectNotHasOption($selectLocator, $option, $message = '') + { + $this->assertNotContains($option, $this->getSelectOptions($selectLocator), $message); + } + + /** + * Asserts that a specific label is selected. + * + * @param string $selectLocator + * @param string $value + * @param string $message + * @since Method available since Release 3.2.0 + */ + public function assertSelected($selectLocator, $option, $message = '') + { + if ($message == '') { + $message = sprintf( + 'Label "%s" not selected in "%s".', + $option, + $selectLocator + ); + } + + $this->assertEquals( + $option, + $this->getSelectedLabel($selectLocator), + $message + ); + } + + /** + * Asserts that a specific label is not selected. + * + * @param string $selectLocator + * @param string $value + * @param string $message + * @since Method available since Release 3.2.0 + */ + public function assertNotSelected($selectLocator, $option, $message = '') + { + if ($message == '') { + $message = sprintf( + 'Label "%s" selected in "%s".', + $option, + $selectLocator + ); + } + + $this->assertNotEquals( + $option, + $this->getSelectedLabel($selectLocator), + $message + ); + } + + /** + * Asserts that a specific value is selected. + * + * @param string $selectLocator + * @param string $value + * @param string $message + */ + public function assertIsSelected($selectLocator, $value, $message = '') + { + if ($message == '') { + $message = sprintf( + 'Value "%s" not selected in "%s".', + $value, + $selectLocator + ); + } + + $this->assertEquals( + $value, $this->getSelectedValue($selectLocator), + $message + ); + } + + /** + * Asserts that a specific value is not selected. + * + * @param string $selectLocator + * @param string $value + * @param string $message + */ + public function assertIsNotSelected($selectLocator, $value, $message = '') + { + if ($message == '') { + $message = sprintf( + 'Value "%s" selected in "%s".', + $value, + $selectLocator + ); + } + + $this->assertNotEquals( + $value, + $this->getSelectedValue($selectLocator), + $message + ); + } + + /** + * Template Method that is called after Selenium actions. + * + * @param string $action + * @since Method available since Release 3.1.0 + */ + protected function defaultAssertions($action) + { + } + + /** + * @return array + * @since Method available since Release 3.2.0 + */ + protected function getCodeCoverage() + { + if (!empty($this->coverageScriptUrl)) { + $url = sprintf( + '%s?PHPUNIT_SELENIUM_TEST_ID=%s', + $this->coverageScriptUrl, + $this->testId + ); + + $buffer = @file_get_contents($url); + + if ($buffer !== FALSE) { + return $this->matchLocalAndRemotePaths(unserialize($buffer)); + } + } + + return array(); + } + + /** + * @param array $coverage + * @return array + * @author Mattis Stordalen Flister + * @since Method available since Release 3.2.9 + */ + protected function matchLocalAndRemotePaths(array $coverage) + { + $coverageWithLocalPaths = array(); + + foreach ($coverage as $originalRemotePath => $data) { + $remotePath = $originalRemotePath; + $separator = $this->findDirectorySeparator($remotePath); + + while (!($localpath = PHPUnit_Util_Filesystem::fileExistsInIncludePath($remotePath)) && + strpos($remotePath, $separator) !== FALSE) { + $remotePath = substr($remotePath, strpos($remotePath, $separator) + 1); + } + + if ($localpath && md5_file($localpath) == $data['md5']) { + $coverageWithLocalPaths[$localpath] = $data['coverage']; + } + } + + return $coverageWithLocalPaths; + } + + /** + * @param string $path + * @return string + * @author Mattis Stordalen Flister + * @since Method available since Release 3.2.9 + */ + protected function findDirectorySeparator($path) + { + if (strpos($path, '/') !== FALSE) { + return '/'; + } + + return '\\'; + } + + /** + * @param string $path + * @return array + * @author Mattis Stordalen Flister + * @since Method available since Release 3.2.9 + */ + protected function explodeDirectories($path) + { + return explode($this->findDirectorySeparator($path), dirname($path)); + } + + /** + * @param string $directory + * @param string $suffix + * @return array + * @since Method available since Release 3.3.0 + */ + protected static function getSeleneseFiles($directory, $suffix) + { + $files = array(); + + $iterator = new PHPUnit_Util_FilterIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($directory) + ), + $suffix + ); + + foreach ($iterator as $file) { + $files[] = (string)$file; + } + + return $files; + } + + /** + * @param string $action + * @since Method available since Release 3.2.0 + */ + public function runDefaultAssertions($action) + { + if (!$this->inDefaultAssertions) { + $this->inDefaultAssertions = TRUE; + $this->defaultAssertions($action); + $this->inDefaultAssertions = FALSE; + } + } + + /** + * This method is called when a test method did not execute successfully. + * + * @param Exception $e + * @since Method available since Release 3.4.0 + */ + protected function onNotSuccessfulTest(Exception $e) + { + if ($e instanceof PHPUnit_Framework_ExpectationFailedException) { + $buffer = 'Current URL: ' . $this->drivers[0]->getLocation() . + "\n"; + $message = $e->getCustomMessage(); + + if ($this->captureScreenshotOnFailure && + !empty($this->screenshotPath) && + !empty($this->screenshotUrl)) { + $this->drivers[0]->captureEntirePageScreenshot( + $this->screenshotPath . DIRECTORY_SEPARATOR . $this->testId . + '.png' + ); + + $buffer .= 'Screenshot: ' . $this->screenshotUrl . '/' . + $this->testId . ".png\n"; + } + } + + if ($this->autoStop) { + try { + $this->stop(); + } + + catch (RuntimeException $e) { + } + } + + if ($e instanceof PHPUnit_Framework_ExpectationFailedException) { + if (!empty($message)) { + $buffer .= "\n" . $message; + } + + $e->setCustomMessage($buffer); + } + + throw $e; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/Driver.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/Driver.php new file mode 100644 index 00000000..34680100 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/Driver.php @@ -0,0 +1,1219 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Implementation of the Selenium RC client/server protocol. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_SeleniumTestCase_Driver +{ + /** + * @var PHPUnit_Extensions_SeleniumTestCase + */ + protected $testCase; + + /** + * @var string + */ + protected $testId; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $browser; + + /** + * @var string + */ + protected $browserUrl; + + /** + * @var boolean + */ + protected $collectCodeCoverageInformation = FALSE; + + /** + * @var string + */ + protected $host = 'localhost'; + + /** + * @var integer + */ + protected $port = 4444; + + /** + * @var integer + */ + protected $httpTimeout = 45; + + /** + * @var integer + */ + protected $seleniumTimeout = 30; + + /** + * @var array + */ + protected $sessionId; + + /** + * @var integer + */ + protected $sleep = 0; + + /** + * @var boolean + */ + protected $useWaitForPageToLoad = TRUE; + + /** + * @var boolean + */ + protected $wait = 5; + + /** + * @var array + */ + protected static $autoGeneratedCommands = array(); + + /** + * @var array + */ + protected $commands = array(); + + /** + * @var array + */ + protected $verificationErrors = array(); + + public function __construct() + { + if (empty(self::$autoGeneratedCommands)) { + self::autoGenerateCommands(); + } + } + + /** + * @return string + */ + public function start() + { + if ($this->browserUrl == NULL) { + throw new PHPUnit_Framework_Exception( + 'setBrowserUrl() needs to be called before start().' + ); + } + + if (!isset($this->sessionId)) { + $this->sessionId = $this->getString( + 'getNewBrowserSession', + array($this->browser, $this->browserUrl) + ); + + $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000)); + } + + return $this->sessionId; + } + + /** + */ + public function stop() + { + if (!isset($this->sessionId)) { + return; + } + + $this->doCommand('testComplete'); + + $this->sessionId = NULL; + } + + /** + * @param boolean $flag + * @throws InvalidArgumentException + */ + public function setCollectCodeCoverageInformation($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->collectCodeCoverageInformation = $flag; + } + + /** + * @param PHPUnit_Extensions_SeleniumTestCase $testCase + */ + public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase) + { + $this->testCase = $testCase; + } + + /** + * @param integer $testId + */ + public function setTestId($testId) + { + $this->testId = $testId; + } + + /** + * @param string $name + * @throws InvalidArgumentException + */ + public function setName($name) + { + if (!is_string($name)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->name = $name; + } + + /** + * @param string $browser + * @throws InvalidArgumentException + */ + public function setBrowser($browser) + { + if (!is_string($browser)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->browser = $browser; + } + + /** + * @param string $browserUrl + * @throws InvalidArgumentException + */ + public function setBrowserUrl($browserUrl) + { + if (!is_string($browserUrl)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->browserUrl = $browserUrl; + } + + /** + * @param string $host + * @throws InvalidArgumentException + */ + public function setHost($host) + { + if (!is_string($host)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->host = $host; + } + + /** + * @param integer $port + * @throws InvalidArgumentException + */ + public function setPort($port) + { + if (!is_int($port)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->port = $port; + } + + /** + * @param integer $timeout for Selenium RC in seconds + * @throws InvalidArgumentException + */ + public function setTimeout($timeout) + { + if (!is_int($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->seleniumTimeout = $timeout; + } + + /** + * @param integer $timeout for HTTP connection to Selenium RC in seconds + * @throws InvalidArgumentException + */ + public function setHttpTimeout($timeout) + { + if (!is_int($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->httpTimeout = $timeout; + } + + /** + * @param integer $seconds + * @throws InvalidArgumentException + */ + public function setSleep($seconds) + { + if (!is_int($seconds)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->sleep = $seconds; + } + + /** + * Sets the number of seconds to sleep() after *AndWait commands + * when setWaitForPageToLoad(FALSE) is used. + * + * @param integer $seconds + * @throws InvalidArgumentException + */ + public function setWait($seconds) + { + if (!is_int($seconds)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->wait = $seconds; + } + + /** + * Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE) + * is used after *AndWait commands. + * + * @param boolean $flag + * @throws InvalidArgumentException + */ + public function setWaitForPageToLoad($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->useWaitForPageToLoad = $flag; + } + + /** + * This method implements the Selenium RC protocol. + * + * @param string $command + * @param array $arguments + * @return mixed + * @method unknown addLocationStrategy() + * @method unknown addLocationStrategyAndWait() + * @method unknown addScript() + * @method unknown addScriptAndWait() + * @method unknown addSelection() + * @method unknown addSelectionAndWait() + * @method unknown allowNativeXpath() + * @method unknown allowNativeXpathAndWait() + * @method unknown altKeyDown() + * @method unknown altKeyDownAndWait() + * @method unknown altKeyUp() + * @method unknown altKeyUpAndWait() + * @method unknown answerOnNextPrompt() + * @method unknown assignId() + * @method unknown assignIdAndWait() + * @method unknown attachFile() + * @method unknown break() + * @method unknown captureEntirePageScreenshot() + * @method unknown captureEntirePageScreenshotAndWait() + * @method unknown captureEntirePageScreenshotToStringAndWait() + * @method unknown captureScreenshotAndWait() + * @method unknown captureScreenshotToStringAndWait() + * @method unknown check() + * @method unknown checkAndWait() + * @method unknown chooseCancelOnNextConfirmation() + * @method unknown chooseCancelOnNextConfirmationAndWait() + * @method unknown chooseOkOnNextConfirmation() + * @method unknown chooseOkOnNextConfirmationAndWait() + * @method unknown click() + * @method unknown clickAndWait() + * @method unknown clickAt() + * @method unknown clickAtAndWait() + * @method unknown close() + * @method unknown contextMenu() + * @method unknown contextMenuAndWait() + * @method unknown contextMenuAt() + * @method unknown contextMenuAtAndWait() + * @method unknown controlKeyDown() + * @method unknown controlKeyDownAndWait() + * @method unknown controlKeyUp() + * @method unknown controlKeyUpAndWait() + * @method unknown createCookie() + * @method unknown createCookieAndWait() + * @method unknown deleteAllVisibleCookies() + * @method unknown deleteAllVisibleCookiesAndWait() + * @method unknown deleteCookie() + * @method unknown deleteCookieAndWait() + * @method unknown deselectPopUp() + * @method unknown deselectPopUpAndWait() + * @method unknown doubleClick() + * @method unknown doubleClickAndWait() + * @method unknown doubleClickAt() + * @method unknown doubleClickAtAndWait() + * @method unknown dragAndDrop() + * @method unknown dragAndDropAndWait() + * @method unknown dragAndDropToObject() + * @method unknown dragAndDropToObjectAndWait() + * @method unknown dragDrop() + * @method unknown dragDropAndWait() + * @method unknown echo() + * @method unknown fireEvent() + * @method unknown fireEventAndWait() + * @method unknown focus() + * @method unknown focusAndWait() + * @method string getAlert() + * @method array getAllButtons() + * @method array getAllFields() + * @method array getAllLinks() + * @method array getAllWindowIds() + * @method array getAllWindowNames() + * @method array getAllWindowTitles() + * @method string getAttribute() + * @method array getAttributeFromAllWindows() + * @method string getBodyText() + * @method string getConfirmation() + * @method string getCookie() + * @method string getCookieByName() + * @method integer getCursorPosition() + * @method integer getElementHeight() + * @method integer getElementIndex() + * @method integer getElementPositionLeft() + * @method integer getElementPositionTop() + * @method integer getElementWidth() + * @method string getEval() + * @method string getExpression() + * @method string getHtmlSource() + * @method string getLocation() + * @method string getLogMessages() + * @method integer getMouseSpeed() + * @method string getPrompt() + * @method array getSelectOptions() + * @method string getSelectedId() + * @method array getSelectedIds() + * @method string getSelectedIndex() + * @method array getSelectedIndexes() + * @method string getSelectedLabel() + * @method array getSelectedLabels() + * @method string getSelectedValue() + * @method array getSelectedValues() + * @method unknown getSpeed() + * @method unknown getSpeedAndWait() + * @method string getTable() + * @method string getText() + * @method string getTitle() + * @method string getValue() + * @method boolean getWhetherThisFrameMatchFrameExpression() + * @method boolean getWhetherThisWindowMatchWindowExpression() + * @method integer getXpathCount() + * @method unknown goBack() + * @method unknown goBackAndWait() + * @method unknown highlight() + * @method unknown highlightAndWait() + * @method unknown ignoreAttributesWithoutValue() + * @method unknown ignoreAttributesWithoutValueAndWait() + * @method boolean isAlertPresent() + * @method boolean isChecked() + * @method boolean isConfirmationPresent() + * @method boolean isCookiePresent() + * @method boolean isEditable() + * @method boolean isElementPresent() + * @method boolean isOrdered() + * @method boolean isPromptPresent() + * @method boolean isSomethingSelected() + * @method boolean isTextPresent() + * @method boolean isVisible() + * @method unknown keyDown() + * @method unknown keyDownAndWait() + * @method unknown keyDownNative() + * @method unknown keyDownNativeAndWait() + * @method unknown keyPress() + * @method unknown keyPressAndWait() + * @method unknown keyPressNative() + * @method unknown keyPressNativeAndWait() + * @method unknown keyUp() + * @method unknown keyUpAndWait() + * @method unknown keyUpNative() + * @method unknown keyUpNativeAndWait() + * @method unknown metaKeyDown() + * @method unknown metaKeyDownAndWait() + * @method unknown metaKeyUp() + * @method unknown metaKeyUpAndWait() + * @method unknown mouseDown() + * @method unknown mouseDownAndWait() + * @method unknown mouseDownAt() + * @method unknown mouseDownAtAndWait() + * @method unknown mouseMove() + * @method unknown mouseMoveAndWait() + * @method unknown mouseMoveAt() + * @method unknown mouseMoveAtAndWait() + * @method unknown mouseOut() + * @method unknown mouseOutAndWait() + * @method unknown mouseOver() + * @method unknown mouseOverAndWait() + * @method unknown mouseUp() + * @method unknown mouseUpAndWait() + * @method unknown mouseUpAt() + * @method unknown mouseUpAtAndWait() + * @method unknown mouseUpRight() + * @method unknown mouseUpRightAndWait() + * @method unknown mouseUpRightAt() + * @method unknown mouseUpRightAtAndWait() + * @method unknown open() + * @method unknown openWindow() + * @method unknown openWindowAndWait() + * @method unknown pause() + * @method unknown refresh() + * @method unknown refreshAndWait() + * @method unknown removeAllSelections() + * @method unknown removeAllSelectionsAndWait() + * @method unknown removeScript() + * @method unknown removeScriptAndWait() + * @method unknown removeSelection() + * @method unknown removeSelectionAndWait() + * @method unknown retrieveLastRemoteControlLogs() + * @method unknown rollup() + * @method unknown rollupAndWait() + * @method unknown runScript() + * @method unknown runScriptAndWait() + * @method unknown select() + * @method unknown selectAndWait() + * @method unknown selectFrame() + * @method unknown selectPopUp() + * @method unknown selectPopUpAndWait() + * @method unknown selectWindow() + * @method unknown setBrowserLogLevel() + * @method unknown setBrowserLogLevelAndWait() + * @method unknown setContext() + * @method unknown setCursorPosition() + * @method unknown setCursorPositionAndWait() + * @method unknown setMouseSpeed() + * @method unknown setMouseSpeedAndWait() + * @method unknown setSpeed() + * @method unknown setSpeedAndWait() + * @method unknown shiftKeyDown() + * @method unknown shiftKeyDownAndWait() + * @method unknown shiftKeyUp() + * @method unknown shiftKeyUpAndWait() + * @method unknown shutDownSeleniumServer() + * @method unknown store() + * @method unknown submit() + * @method unknown submitAndWait() + * @method unknown type() + * @method unknown typeAndWait() + * @method unknown typeKeys() + * @method unknown typeKeysAndWait() + * @method unknown uncheck() + * @method unknown uncheckAndWait() + * @method unknown useXpathLibrary() + * @method unknown useXpathLibraryAndWait() + * @method unknown waitForCondition() + * @method unknown waitForPageToLoad() + * @method unknown waitForPopUp() + * @method unknown windowFocus() + * @method unknown windowMaximize() + */ + public function __call($command, $arguments) + { + $wait = FALSE; + + if (substr($command, -7, 7) == 'AndWait') { + $command = substr($command, 0, -7); + $wait = TRUE; + } + + switch ($command) { + case 'addLocationStrategy': + case 'addScript': + case 'addSelection': + case 'allowNativeXpath': + case 'altKeyDown': + case 'altKeyUp': + case 'answerOnNextPrompt': + case 'assignId': + case 'attachFile': + case 'break': + case 'captureEntirePageScreenshot': + case 'captureEntirePageScreenshotToString': + case 'captureScreenshot': + case 'captureScreenshotToString': + case 'check': + case 'chooseCancelOnNextConfirmation': + case 'chooseOkOnNextConfirmation': + case 'click': + case 'clickAt': + case 'close': + case 'contextMenu': + case 'contextMenuAt': + case 'controlKeyDown': + case 'controlKeyUp': + case 'createCookie': + case 'deleteAllVisibleCookies': + case 'deleteCookie': + case 'deselectPopUp': + case 'doubleClick': + case 'doubleClickAt': + case 'dragAndDrop': + case 'dragAndDropToObject': + case 'dragDrop': + case 'echo': + case 'fireEvent': + case 'focus': + case 'goBack': + case 'highlight': + case 'ignoreAttributesWithoutValue': + case 'keyDown': + case 'keyDownNative': + case 'keyPress': + case 'keyPressNative': + case 'keyUp': + case 'keyUpNative': + case 'metaKeyDown': + case 'metaKeyUp': + case 'mouseDown': + case 'mouseDownAt': + case 'mouseMove': + case 'mouseMoveAt': + case 'mouseOut': + case 'mouseOver': + case 'mouseUp': + case 'mouseUpAt': + case 'mouseUpRight': + case 'mouseUpRightAt': + case 'open': + case 'openWindow': + case 'pause': + case 'refresh': + case 'removeAllSelections': + case 'removeScript': + case 'removeSelection': + case 'retrieveLastRemoteControlLogs': + case 'rollup': + case 'runScript': + case 'select': + case 'selectFrame': + case 'selectPopUp': + case 'selectWindow': + case 'setBrowserLogLevel': + case 'setContext': + case 'setCursorPosition': + case 'setMouseSpeed': + case 'setSpeed': + case 'shiftKeyDown': + case 'shiftKeyUp': + case 'shutDownSeleniumServer': + case 'store': + case 'submit': + case 'type': + case 'typeKeys': + case 'uncheck': + case 'useXpathLibrary': + case 'windowFocus': + case 'windowMaximize': + case isset(self::$autoGeneratedCommands[$command]): { + // Pre-Command Actions + switch ($command) { + case 'open': + case 'openWindow': { + if ($this->collectCodeCoverageInformation) { + $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/'); + + $this->createCookie( + 'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId, + 'path=/' + ); + } + } + break; + case 'store': + // store is a synonym of storeExpression + // and RC only understands storeExpression + $command = 'storeExpression'; + break; + } + + if (isset(self::$autoGeneratedCommands[$command]) && self::$autoGeneratedCommands[$command]['functionHelper']) { + $helperArguments = array($command, $arguments, self::$autoGeneratedCommands[$command]); + call_user_func_array(array($this, self::$autoGeneratedCommands[$command]['functionHelper']), $helperArguments); + } else { + $this->doCommand($command, $arguments); + } + + // Post-Command Actions + switch ($command) { + case 'addLocationStrategy': + case 'allowNativeXpath': + case 'assignId': + case 'captureEntirePageScreenshot': + case 'captureScreenshot': + case 'captureScreenshotToString': { + // intentionally empty + } + break; + + default: { + if ($wait) { + if ($this->useWaitForPageToLoad) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } else { + sleep($this->wait); + } + } + + if ($this->sleep > 0) { + sleep($this->sleep); + } + + $this->testCase->runDefaultAssertions($command); + } + } + } + break; + + case 'getWhetherThisFrameMatchFrameExpression': + case 'getWhetherThisWindowMatchWindowExpression': + case 'isAlertPresent': + case 'isChecked': + case 'isConfirmationPresent': + case 'isCookiePresent': + case 'isEditable': + case 'isElementPresent': + case 'isOrdered': + case 'isPromptPresent': + case 'isSomethingSelected': + case 'isTextPresent': + case 'isVisible': { + return $this->getBoolean($command, $arguments); + } + break; + + case 'getCursorPosition': + case 'getElementHeight': + case 'getElementIndex': + case 'getElementPositionLeft': + case 'getElementPositionTop': + case 'getElementWidth': + case 'getMouseSpeed': + case 'getSpeed': + case 'getXpathCount': { + $result = $this->getNumber($command, $arguments); + + if ($wait) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } + + return $result; + } + break; + + case 'getAlert': + case 'getAttribute': + case 'getBodyText': + case 'getConfirmation': + case 'getCookie': + case 'getCookieByName': + case 'getEval': + case 'getExpression': + case 'getHtmlSource': + case 'getLocation': + case 'getLogMessages': + case 'getPrompt': + case 'getSelectedId': + case 'getSelectedIndex': + case 'getSelectedLabel': + case 'getSelectedValue': + case 'getTable': + case 'getText': + case 'getTitle': + case 'getValue': { + $result = $this->getString($command, $arguments); + + if ($wait) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } + + return $result; + } + break; + + case 'getAllButtons': + case 'getAllFields': + case 'getAllLinks': + case 'getAllWindowIds': + case 'getAllWindowNames': + case 'getAllWindowTitles': + case 'getAttributeFromAllWindows': + case 'getSelectedIds': + case 'getSelectedIndexes': + case 'getSelectedLabels': + case 'getSelectedValues': + case 'getSelectOptions': { + $result = $this->getStringArray($command, $arguments); + + if ($wait) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } + + return $result; + } + break; + + case 'waitForCondition': + case 'waitForFrameToLoad': + case 'waitForPopUp': { + if (count($arguments) == 1) { + $arguments[] = $this->seleniumTimeout * 1000; + } + + $this->doCommand($command, $arguments); + $this->testCase->runDefaultAssertions($command); + } + break; + + case 'waitForPageToLoad': { + if (empty($arguments)) { + $arguments[] = $this->seleniumTimeout * 1000; + } + + $this->doCommand($command, $arguments); + $this->testCase->runDefaultAssertions($command); + } + break; + + default: { + $this->stop(); + + throw new BadMethodCallException( + "Method $command not defined." + ); + } + } + } + + /** + * Send a command to the Selenium RC server. + * + * @param string $command + * @param array $arguments + * @return string + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function doCommand($command, array $arguments = array()) + { + if (!ini_get('allow_url_fopen')) { + throw new PHPUnit_Framework_Exception( + 'Could not connect to the Selenium RC server because allow_url_fopen is disabled.' + ); + } + + $url = sprintf( + 'http://%s:%s/selenium-server/driver/?cmd=%s', + $this->host, + $this->port, + urlencode($command) + ); + + $numArguments = count($arguments); + + for ($i = 0; $i < $numArguments; $i++) { + $argNum = strval($i + 1); + $url .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i]))); + } + + if (isset($this->sessionId)) { + $url .= sprintf('&%s=%s', 'sessionId', $this->sessionId); + } + + $this->commands[] = sprintf('%s(%s)', $command, join(', ', $arguments)); + + $context = stream_context_create( + array( + 'http' => array( + 'timeout' => $this->httpTimeout + ) + ) + ); + + $handle = @fopen($url, 'r', FALSE, $context); + + if (!$handle) { + throw new PHPUnit_Framework_Exception( + 'Could not connect to the Selenium RC server.' + ); + } + + stream_set_blocking($handle, 1); + stream_set_timeout($handle, 0, $this->httpTimeout * 1000); + + $info = stream_get_meta_data($handle); + $response = ''; + + while (!$info['eof'] && !$info['timed_out']) { + $response .= fgets($handle, 4096); + $info = stream_get_meta_data($handle); + } + + fclose($handle); + + if (!preg_match('/^OK/', $response)) { + $this->stop(); + + throw new PHPUnit_Framework_Exception( + sprintf( + "Response from Selenium RC server for %s.\n%s.\n", + $this->commands[count($this->commands)-1], + $response + ) + ); + } + + return $response; + } + + /** + * Send a command to the Selenium RC server and treat the result + * as a boolean. + * + * @param string $command + * @param array $arguments + * @return boolean + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getBoolean($command, array $arguments) + { + $result = $this->getString($command, $arguments); + + switch ($result) { + case 'true': return TRUE; + + case 'false': return FALSE; + + default: { + $this->stop(); + + throw new PHPUnit_Framework_Exception( + 'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::toString($result, TRUE) + ); + } + } + } + + /** + * Send a command to the Selenium RC server and treat the result + * as a number. + * + * @param string $command + * @param array $arguments + * @return numeric + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getNumber($command, array $arguments) + { + $result = $this->getString($command, $arguments); + + if (!is_numeric($result)) { + $this->stop(); + + throw new PHPUnit_Framework_Exception( + 'Result is not numeric: ' . PHPUnit_Util_Type::toString($result, TRUE) + ); + } + + return $result; + } + + /** + * Send a command to the Selenium RC server and treat the result + * as a string. + * + * @param string $command + * @param array $arguments + * @return string + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getString($command, array $arguments) + { + try { + $result = $this->doCommand($command, $arguments); + } + + catch (RuntimeException $e) { + $this->stop(); + + throw $e; + } + + return (strlen($result) > 3) ? substr($result, 3) : ''; + } + + /** + * Send a command to the Selenium RC server and treat the result + * as an array of strings. + * + * @param string $command + * @param array $arguments + * @return array + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getStringArray($command, array $arguments) + { + $csv = $this->getString($command, $arguments); + $token = ''; + $tokens = array(); + $letters = preg_split('//', $csv, -1, PREG_SPLIT_NO_EMPTY); + $count = count($letters); + + for ($i = 0; $i < $count; $i++) { + $letter = $letters[$i]; + + switch($letter) { + case '\\': { + $letter = $letters[++$i]; + $token .= $letter; + } + break; + + case ',': { + $tokens[] = $token; + $token = ''; + } + break; + + default: { + $token .= $letter; + } + } + } + + $tokens[] = $token; + + return $tokens; + } + + public function getVerificationErrors() + { + return $this->verificationErrors; + } + + public function clearVerificationErrors() + { + $this->verificationErrors = array(); + } + + protected function assertCommand($command, $arguments, $info) + { + $method = $info['originalMethod']; + $result = $this->__call($method, $arguments); + + if ($info['isBoolean']) { + if (!isset($info['negative']) || !$info['negative']) { + PHPUnit_Framework_Assert::assertTrue($result); + } else { + PHPUnit_Framework_Assert::assertFalse($result); + } + } else { + $expected = array_pop($arguments); + + if (strpos($expected, 'exact:') === 0) { + $expected = substr($expected, strlen('exact:')); + + if (!isset($info['negative']) || !$info['negative']) { + PHPUnit_Framework_Assert::assertEquals($expected, $result); + } else { + PHPUnit_Framework_Assert::assertNotEquals($expected, $result); + } + } else { + if (strpos($expected, 'regexp:') === 0) { + $expected = substr($expected, strlen('regexp:')); + } else { + if (strpos($expected, 'glob:') === 0) { + $expected = substr($expected, strlen('glob:')); + } + + $expected = str_replace( + array('*', '?'), array('.*', '.?'), $expected + ); + } + + $expected = str_replace('/', '\/', $expected); + + if (!isset($info['negative']) || !$info['negative']) { + PHPUnit_Framework_Assert::assertRegExp( + '/' . $expected . '/', $result + ); + } else { + PHPUnit_Framework_Assert::assertNotRegExp( + '/' . $expected . '/', $result + ); + } + } + } + } + + protected function verifyCommand($command, $arguments, $info) + { + try { + $this->assertCommand($command, $arguments, $info); + } + + catch (PHPUnit_Framework_AssertionFailedError $e) { + array_push($this->verificationErrors, $e->toString()); + } + } + + protected function waitForCommand($command, $arguments, $info) + { + for ($second = 0; ; $second++) { + if ($second > $this->httpTimeout) { + PHPUnit_Framework_Assert::fail('timeout'); + } + + try { + $this->assertCommand($command, $arguments, $info); + return; + } + + catch (Exception $e) { + } + + sleep(1); + } + } + + /** + * Parses the docblock of PHPUnit_Extensions_SeleniumTestCase_Driver::__call + * for get*(), is*(), assert*(), verify*(), assertNot*(), verifyNot*(), + * store*(), waitFor*(), and waitForNot*() methods. + */ + protected static function autoGenerateCommands() + { + $method = new ReflectionMethod(__CLASS__, '__call'); + $docComment = $method->getDocComment(); + + if (preg_match_all('(@method\s+(\w+)\s+([\w]+)\(\))', $docComment, $matches)) { + foreach ($matches[2] as $method) { + if (preg_match('/^(get|is)([A-Z].+)$/', $method, $matches)) { + $baseName = $matches[2]; + $isBoolean = $matches[1] == 'is'; + + if (preg_match('/^(.*)Present$/', $baseName, $matches)) { + $notBaseName = $matches[1].'NotPresent'; + } else { + $notBaseName = 'Not'.$baseName; + } + + self::$autoGeneratedCommands['store' . $baseName] = array( + 'functionHelper' => FALSE + ); + + self::$autoGeneratedCommands['assert' . $baseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'functionHelper' => 'assertCommand' + ); + + self::$autoGeneratedCommands['assert' . $notBaseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'negative' => TRUE, + 'functionHelper' => 'assertCommand' + ); + + self::$autoGeneratedCommands['verify' . $baseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'functionHelper' => 'verifyCommand' + ); + + self::$autoGeneratedCommands['verify' . $notBaseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'negative' => TRUE, + 'functionHelper' => 'verifyCommand' + ); + + self::$autoGeneratedCommands['waitFor' . $baseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'functionHelper' => 'waitForCommand' + ); + + self::$autoGeneratedCommands['waitFor' . $notBaseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'negative' => TRUE, + 'functionHelper' => 'waitForCommand' + ); + } + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/append.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/append.php new file mode 100644 index 00000000..d55b023a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/append.php @@ -0,0 +1,71 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.10 + */ + +if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && + !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) && + extension_loaded('xdebug')) { + $GLOBALS['PHPUNIT_FILTERED_FILES'][] = __FILE__; + + $data = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + foreach ($GLOBALS['PHPUNIT_FILTERED_FILES'] as $file) { + unset($data[$file]); + } + + if (is_string($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) && + is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) { + $file = $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] . + DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']); + } else { + $file = $_SERVER['SCRIPT_FILENAME']; + } + + file_put_contents( + $file . '.' . md5(uniqid(rand(), TRUE)) . '.' . $_COOKIE['PHPUNIT_SELENIUM_TEST_ID'], + serialize($data) + ); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/phpunit_coverage.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/phpunit_coverage.php new file mode 100644 index 00000000..cd94453d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/phpunit_coverage.php @@ -0,0 +1,91 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.10 + */ + +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/FilterIterator.php'; + +// Set this to the directory that contains the code coverage files. +// It defaults to getcwd(). If you have configured a different directory +// in prepend.php, you need to configure the same directory here. +$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = getcwd(); + +if (isset($_GET['PHPUNIT_SELENIUM_TEST_ID'])) { + $files = new PHPUnit_Util_FilterIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( + $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] + ) + ) + ); + + $coverage = array(); + + foreach ($files as $file) { + $filename = $file->getPathName(); + $data = unserialize(file_get_contents($filename)); + @unlink($filename); + unset($filename); + + foreach ($data as $filename => $lines) { + if (PHPUnit_Util_CodeCoverage::isFile($filename)) { + if (!isset($coverage[$filename])) { + $coverage[$filename] = array( + 'md5' => md5_file($filename), 'coverage' => $lines + ); + } else { + foreach ($lines as $line => $flag) { + if (!isset($coverage[$filename]['coverage'][$line]) || + $flag > $coverage[$filename]['coverage'][$line]) { + $coverage[$filename]['coverage'][$line] = $flag; + } + } + } + } + } + } + + print serialize($coverage); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/prepend.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/prepend.php new file mode 100644 index 00000000..7da899a5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/SeleniumTestCase/prepend.php @@ -0,0 +1,61 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.10 + */ + +// By default the code coverage files are written to the same directory +// that contains the covered sourcecode files. Use this setting to change +// the default behaviour and set a specific directory to write the files to. +// If you change the default setting, please make sure to also configure +// the same directory in phpunit_coverage.php. Also note that the webserver +// needs write access to the directory. +$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = FALSE; + +if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && + !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) && + extension_loaded('xdebug')) { + $GLOBALS['PHPUNIT_FILTERED_FILES'] = array(__FILE__); + + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Given.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Given.php new file mode 100644 index 00000000..31e1f01f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Given.php @@ -0,0 +1,78 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/Step.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A "Given" step. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +class PHPUnit_Extensions_Story_Given extends PHPUnit_Extensions_Story_Step +{ + /** + * Returns this step's name. + * + * @return string + */ + public function getName() + { + return 'Given'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter.php new file mode 100644 index 00000000..281b8bba --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter.php @@ -0,0 +1,109 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Template.php'; +require_once 'PHPUnit/Util/TestDox/ResultPrinter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Base for Story result printers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Story_ResultPrinter extends PHPUnit_Util_TestDox_ResultPrinter +{ + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($test instanceof PHPUnit_Extensions_Story_TestCase || + $test instanceof PHPUnit_Extensions_Story_SeleniumTestCase) { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $this->successful++; + $success = TRUE; + } else { + $success = FALSE; + } + + $this->onTest( + $this->currentTestMethodPrettified, + $success, + $test->getScenario()->getSteps() + ); + } + } + + /** + */ + protected function doEndClass() + { + $this->endClass($this->testClass); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + * @param array $steps + */ + protected function onTest($name, $success = TRUE, array $steps = array()) + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/HTML.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/HTML.php new file mode 100644 index 00000000..565bfa0a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/HTML.php @@ -0,0 +1,208 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Template.php'; +require_once 'PHPUnit/Extensions/Story/ResultPrinter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Prints stories in HTML format. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Story_ResultPrinter_HTML extends PHPUnit_Extensions_Story_ResultPrinter +{ + /** + * @var boolean + */ + protected $printsHTML = TRUE; + + protected $id = 0; + protected $scenarios = ''; + protected $templatePath; + + /** + * Constructor. + * + * @param mixed $out + * @throws InvalidArgumentException + */ + public function __construct($out = NULL) + { + parent::__construct($out); + + $this->templatePath = sprintf( + '%s%sTemplate%s', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ); + } + + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + $scenarioHeaderTemplate = new PHPUnit_Util_Template( + $this->templatePath . 'scenario_header.html' + ); + + $scenarioHeaderTemplate->setVar( + array( + 'name' => $this->currentTestClassPrettified + ) + ); + + $this->scenarios .= $scenarioHeaderTemplate->render(); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + * @param array $steps + */ + protected function onTest($name, $success = TRUE, array $steps = array()) + { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) { + $scenarioStatus = 'scenarioFailed'; + } + + else if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED) { + $scenarioStatus = 'scenarioSkipped'; + } + + else if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) { + $scenarioStatus = 'scenarioIncomplete'; + } + + else { + $scenarioStatus = 'scenarioSuccess'; + } + + $lastStepName = ''; + $stepsBuffer = ''; + + foreach ($steps as $step) { + $currentStepName = $step->getName(); + + if ($lastStepName == $currentStepName) { + $stepText = 'and'; + } else { + $stepText = $currentStepName; + } + + $lastStepName = $currentStepName; + + $stepTemplate = new PHPUnit_Util_Template( + $this->templatePath . 'step.html' + ); + + $stepTemplate->setVar( + array( + 'text' => $stepText, + 'action' => $step->getAction() . ' ' . $step->getArguments(TRUE), + ) + ); + + $stepsBuffer .= $stepTemplate->render(); + } + + $scenarioTemplate = new PHPUnit_Util_Template( + $this->templatePath . 'scenario.html' + ); + + $scenarioTemplate->setVar( + array( + 'id' => ++$this->id, + 'name' => $name, + 'scenarioStatus' => $scenarioStatus, + 'steps' => $stepsBuffer, + ) + ); + + $this->scenarios .= $scenarioTemplate->render(); + } + + /** + * Handler for 'end run' event. + * + */ + protected function endRun() + { + $scenariosTemplate = new PHPUnit_Util_Template( + $this->templatePath . 'scenarios.html' + ); + + $scenariosTemplate->setVar( + array( + 'scenarios' => $this->scenarios, + 'successfulScenarios' => $this->successful, + 'failedScenarios' => $this->failed, + 'skippedScenarios' => $this->skipped, + 'incompleteScenarios' => $this->incomplete + ) + ); + + $this->write($scenariosTemplate->render()); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenario.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenario.html.dist new file mode 100644 index 00000000..caa149aa --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenario.html.dist @@ -0,0 +1,13 @@ + + + + + + + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenario_header.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenario_header.html.dist new file mode 100644 index 00000000..7b205d1c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenario_header.html.dist @@ -0,0 +1,6 @@ + + + + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenarios.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenarios.html.dist new file mode 100644 index 00000000..21bf38e8 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/scenarios.html.dist @@ -0,0 +1,60 @@ + + + + + + +
+

[+] {name}

+
+ +{steps} +
+
+

{name}

+
+{scenarios} + + + +
+

[+] Summary:

+ +
+ + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/step.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/step.html.dist new file mode 100644 index 00000000..bcdce3f4 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Template/step.html.dist @@ -0,0 +1,6 @@ + + {text} + {action} +   + + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Text.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Text.php new file mode 100644 index 00000000..9f33fd03 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/ResultPrinter/Text.php @@ -0,0 +1,157 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Template.php'; +require_once 'PHPUnit/Extensions/Story/ResultPrinter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Prints stories in HTML format. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_Story_ResultPrinter_Text extends PHPUnit_Extensions_Story_ResultPrinter +{ + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + $this->write($this->currentTestClassPrettified . "\n"); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + * @param array $steps + */ + protected function onTest($name, $success = TRUE, array $steps = array()) + { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) { + $scenarioStatus = 'failed'; + } + + else if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED) { + $scenarioStatus = 'skipped'; + } + + else if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) { + $scenarioStatus = 'incomplete'; + } + + else { + $scenarioStatus = 'successful'; + } + + $this->write( + sprintf( + " [%s] %s\n\n", + $scenarioStatus == 'successful' ? 'x' : ' ', + $name + ) + ); + + $lastStepName = ''; + $stepsBuffer = ''; + + foreach ($steps as $step) { + $currentStepName = $step->getName(); + + if ($lastStepName == $currentStepName) { + $stepText = 'and'; + } else { + $stepText = $currentStepName; + } + + $lastStepName = $currentStepName; + + $this->write( + sprintf( + " %5s %s %s\n", + $stepText, + $step->getAction(), + $step->getArguments(TRUE) + ) + ); + } + + $this->write("\n"); + } + + /** + * Handler for 'end run' event. + * + */ + protected function endRun() + { + $this->write( + sprintf( + "Scenarios: %d, Failed: %d, Skipped: %d, Incomplete: %d.\n", + + $this->successful + $this->failed + + $this->skipped + $this->incomplete, + $this->failed, + $this->skipped, + $this->incomplete + ) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Scenario.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Scenario.php new file mode 100644 index 00000000..619f005a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Scenario.php @@ -0,0 +1,199 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/Step.php'; +require_once 'PHPUnit/Extensions/Story/Given.php'; +require_once 'PHPUnit/Extensions/Story/When.php'; +require_once 'PHPUnit/Extensions/Story/Then.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A scenario. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +class PHPUnit_Extensions_Story_Scenario +{ + /** + * @var PHPUnit_Extensions_Story_TestCase + */ + protected $test; + + /** + * @var array + */ + protected $steps = array(); + + /** + * @var string + */ + protected $lastCalledMethod; + + /** + * Constructor. + * + * @param PHPUnit_Extensions_Story_TestCase $caller + */ + public function __construct($test) + { + if ($test instanceof PHPUnit_Extensions_Story_TestCase || + $test instanceof PHPUnit_Extensions_Story_SeleniumTestCase) { + $this->test = $test; + } else { + throw new Exception('$test must either be PHPUnit_Extensions_Story_TestCase or PHPUnit_Extensions_Story_SeleniumTestCase'); + } + } + + /** + * Adds a "Given" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + public function given($arguments) + { + return $this->addStep(new PHPUnit_Extensions_Story_Given($arguments)); + } + + /** + * Adds a "When" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + public function when($arguments) + { + return $this->addStep(new PHPUnit_Extensions_Story_When($arguments)); + } + + /** + * Adds a "Then" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + public function then($arguments) + { + return $this->addStep(new PHPUnit_Extensions_Story_Then($arguments)); + } + + /** + * Add another step of the same type as the step that was added before. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + public function _and($arguments) + { + $lastCalledStepClass = get_class($this->steps[count($this->steps)-1]); + + return $this->addStep(new $lastCalledStepClass($arguments)); + } + + /** + * Runs this scenario. + * + * @param array $world + */ + public function run(array &$world) + { + foreach ($this->steps as $step) + { + if ($step instanceof PHPUnit_Extensions_Story_Given) { + $this->test->runGiven( + $world, $step->getAction(), $step->getArguments() + ); + } + + else if ($step instanceof PHPUnit_Extensions_Story_When) { + $this->test->runWhen( + $world, $step->getAction(), $step->getArguments() + ); + } + + else { + $this->test->runThen( + $world, $step->getAction(), $step->getArguments() + ); + } + } + } + + /** + * Adds a step to the scenario. + * + * @param PHPUnit_Extensions_Story_Step $step + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function addStep(PHPUnit_Extensions_Story_Step $step) + { + $this->steps[] = $step; + + return $this->test; + } + + /** + * Returns the steps of this scenario. + * + * @return array + */ + public function getSteps() + { + return $this->steps; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/SeleniumTestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/SeleniumTestCase.php new file mode 100644 index 00000000..14f56050 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/SeleniumTestCase.php @@ -0,0 +1,211 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/Scenario.php'; +require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; +require_once 'PHPUnit/Extensions/Story/TestCase.php'; + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +abstract class PHPUnit_Extensions_Story_SeleniumTestCase extends PHPUnit_Extensions_SeleniumTestCase +{ + protected $scenario; + protected $world = array(); + + public function __construct($name = NULL, array $data = array(), $dataName = '', array $browser = array()) + { + parent::__construct($name, $data, $dataName, $browser); + $this->scenario = new PHPUnit_Extensions_Story_Scenario($this); + } + + /** + * @method PHPUnit_Extensions_Story_Step and($contextOrOutcome) + */ + public function __call($command, $arguments) + { + switch($command) { + case 'and': { + return $this->scenario->_and($arguments); + } + break; + + default: { + return parent::__call($command, $arguments); + } + } + } + + /** + * Returns this test's scenario. + * + * @return PHPUnit_Extensions_Story_Scenario + */ + public function getScenario() + { + return $this->scenario; + } + + /** + * This method is used by __call + * + */ + protected function notImplemented($action) + { + if (strstr($action, ' ')) { + $this->markTestIncomplete("step: $action not implemented."); + } + + throw new BadMethodCallException("Method $action not defined."); + } + + /** + * Adds a "Given" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function given($context) + { + return $this->scenario->given(func_get_args()); + } + + /** + * Adds a "When" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function when($event) + { + return $this->scenario->when(func_get_args()); + } + + /** + * Adds a "Then" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function then($outcome) + { + return $this->scenario->then(func_get_args()); + } + + /** + * Add another step of the same type as the step that was added before. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function _and($contextOrOutcome) + { + return $this->scenario->_and(func_get_args()); + } + + /** + * Run this test's scenario. + * + * @return mixed + * @throws RuntimeException + */ + protected function runTest() + { + $autostop = $this->autoStop; + $this->autoStop = FALSE; + + try { + $testResult = parent::runTest(); + $this->scenario->run($this->world); + $this->autoStop = $autostop; + } + + catch (Exception $e) { + $this->autoStop = $autostop; + throw $e; + } + + return $testResult; + } + + /** + * Implementation for "Given" steps. + * + * @param array $world + * @param string $action + * @param array $arguments + */ + abstract protected function runGiven(&$world, $action, $arguments); + + /** + * Implementation for "When" steps. + * + * @param array $world + * @param string $action + * @param array $arguments + */ + abstract protected function runWhen(&$world, $action, $arguments); + + /** + * Implementation for "Then" steps. + * + * @param array $world + * @param string $action + * @param array $arguments + */ + abstract protected function runThen(&$world, $action, $arguments); +} diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Step.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Step.php new file mode 100644 index 00000000..647624ef --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Step.php @@ -0,0 +1,134 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A step of a scenario. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +abstract class PHPUnit_Extensions_Story_Step +{ + /** + * @var string + */ + protected $action; + + /** + * @var array + */ + protected $arguments; + + /** + * Constructor. + * + * @param array $arguments + */ + public function __construct(array $arguments) + { + $this->action = array_shift($arguments); + $this->arguments = $arguments; + } + + /** + * Returns this step's action. + * + * @return string + */ + public function getAction() + { + return $this->action; + } + + /** + * Returns this step's arguments. + * + * @param boolean $asString + * @return array|string + */ + public function getArguments($asString = FALSE) + { + if (!$asString) { + return $this->arguments; + } else { + switch (count($this->arguments)) { + case 0: { + return ''; + } + break; + + case 1: { + return $this->arguments[0]; + } + break; + + default: { + return var_export($this->arguments, TRUE); + } + } + } + } + + /** + * Returns this step's name. + * + * @return string + */ + abstract public function getName(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/TestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/TestCase.php new file mode 100644 index 00000000..200adcec --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/TestCase.php @@ -0,0 +1,218 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/Scenario.php'; +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A story test case. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +abstract class PHPUnit_Extensions_Story_TestCase extends PHPUnit_Framework_TestCase +{ + /** + * @var PHPUnit_Extensions_Story_Scenario + */ + protected $scenario; + + /** + * @var array + */ + protected $world = array(); + + /** + * Constructs a test case with the given name. + * + * @param string $name + * @param array $data + * @param string $dataName + */ + public function __construct($name = NULL, array $data = array(), $dataName = '') + { + parent::__construct($name, $data, $dataName); + $this->scenario = new PHPUnit_Extensions_Story_Scenario($this); + } + + /** + * @method PHPUnit_Extensions_Story_Step and($contextOrOutcome) + */ + public function __call($command, $arguments) + { + switch ($command) { + case 'and': { + return $this->scenario->_and($arguments); + } + break; + + default: { + throw new BadMethodCallException( + "Method $command not defined." + ); + } + } + } + + /** + * Returns this test's scenario. + * + * @return PHPUnit_Extensions_Story_Scenario + */ + public function getScenario() + { + return $this->scenario; + } + + /** + * + * + */ + protected function notImplemented($action) + { + if (strstr($action, ' ')) { + $this->markTestIncomplete("step: $action not implemented."); + } + + throw new BadMethodCallException("Method $action not defined."); + } + + /** + * Adds a "Given" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function given($context) + { + return $this->scenario->given(func_get_args()); + } + + /** + * Adds a "When" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function when($event) + { + return $this->scenario->when(func_get_args()); + } + + /** + * Adds a "Then" step to the scenario. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function then($outcome) + { + return $this->scenario->then(func_get_args()); + } + + /** + * Add another step of the same type as the step that was added before. + * + * @param array $arguments + * @return PHPUnit_Extensions_Story_TestCase + */ + protected function _and($contextOrOutcome) + { + return $this->scenario->_and(func_get_args()); + } + + /** + * Run this test's scenario. + * + * @return mixed + * @throws RuntimeException + */ + protected function runTest() + { + $testResult = parent::runTest(); + $this->scenario->run($this->world); + return $testResult; + } + + /** + * Implementation for "Given" steps. + * + * @param array $world + * @param string $action + * @param array $arguments + */ + abstract protected function runGiven(&$world, $action, $arguments); + + /** + * Implementation for "When" steps. + * + * @param array $world + * @param string $action + * @param array $arguments + */ + abstract protected function runWhen(&$world, $action, $arguments); + + /** + * Implementation for "Then" steps. + * + * @param array $world + * @param string $action + * @param array $arguments + */ + abstract protected function runThen(&$world, $action, $arguments); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Then.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Then.php new file mode 100644 index 00000000..248e0a7f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/Then.php @@ -0,0 +1,78 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/Step.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A "Then" step. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +class PHPUnit_Extensions_Story_Then extends PHPUnit_Extensions_Story_Step +{ + /** + * Returns this step's name. + * + * @return string + */ + public function getName() + { + return 'Then'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/When.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/When.php new file mode 100644 index 00000000..d63c2e45 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/Story/When.php @@ -0,0 +1,78 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/Step.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A "When" step. + * + * @category Testing + * @package PHPUnit + * @author Mattis Stordalen Flister + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + * @abstract + */ +class PHPUnit_Extensions_Story_When extends PHPUnit_Extensions_Story_Step +{ + /** + * Returns this step's name. + * + * @return string + */ + public function getName() + { + return 'When'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TestDecorator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TestDecorator.php new file mode 100644 index 00000000..c56aaef3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TestDecorator.php @@ -0,0 +1,157 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A Decorator for Tests. + * + * Use TestDecorator as the base class for defining new + * test decorators. Test decorator subclasses can be introduced + * to add behaviour before or after a test is run. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Extensions_TestDecorator extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * The Test to be decorated. + * + * @var object + */ + protected $test = NULL; + + /** + * Constructor. + * + * @param PHPUnit_Framework_Test $test + */ + public function __construct(PHPUnit_Framework_Test $test) + { + $this->test = $test; + } + + /** + * Returns a string representation of the test. + * + * @return string + */ + public function toString() + { + return $this->test->toString(); + } + + /** + * Runs the test and collects the + * result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + */ + public function basicRun(PHPUnit_Framework_TestResult $result) + { + $this->test->run($result); + } + + /** + * Counts the number of test cases that + * will be run by this test. + * + * @return integer + */ + public function count() + { + return count($this->test); + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * Returns the test to be run. + * + * @return PHPUnit_Framework_Test + */ + public function getTest() + { + return $this->test; + } + + /** + * Runs the decorated test and collects the + * result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws InvalidArgumentException + */ + public function run(PHPUnit_Framework_TestResult $result = NULL) + { + if ($result === NULL) { + $result = $this->createResult(); + } + + $this->basicRun($result); + + return $result; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TicketListener.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TicketListener.php new file mode 100644 index 00000000..7d39aa82 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TicketListener.php @@ -0,0 +1,220 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sean Coates + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Test.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Base class for test listeners that interact with an issue tracker. + * + * @category Testing + * @package PHPUnit + * @author Sean Coates + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +abstract class PHPUnit_Extensions_TicketListener implements PHPUnit_Framework_TestListener +{ + protected $ticketCounts = array(); + protected $ran = FALSE; + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($this->ran) { + return; + } + + $name = $test->getName(); + $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name); + + foreach ($tickets as $ticket) { + $this->ticketCounts[$ticket][$name] = 1; + } + + $this->ran = TRUE; + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $ifStatus = array('assigned', 'new', 'reopened'); + $newStatus = 'closed'; + $message = 'Automatically closed by PHPUnit (test passed).'; + $resolution = 'fixed'; + $cumulative = TRUE; + } + + else if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) { + $ifStatus = array('closed'); + $newStatus = 'reopened'; + $message = 'Automatically reopened by PHPUnit (test failed).'; + $resolution = ''; + $cumulative = FALSE; + } + + else { + return; + } + + $name = $test->getName(); + $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name); + + foreach ($tickets as $ticket) { + // Remove this test from the totals (if it passed). + if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + unset($this->ticketCounts[$ticket][$name]); + } + + // Only close tickets if ALL referenced cases pass + // but reopen tickets if a single test fails. + if ($cumulative) { + // Determine number of to-pass tests: + if (count($this->ticketCounts[$ticket]) > 0) { + // There exist remaining test cases with this reference. + $adjustTicket = FALSE; + } else { + // No remaining tickets, go ahead and adjust. + $adjustTicket = TRUE; + } + } else { + $adjustTicket = TRUE; + } + + if ($adjustTicket && in_array($ticketInfo[3]['status'], $ifStatus)) { + $this->updateTicket($ticket, $newStatus, $message, $resolution); + } + } + } + } + + abstract protected function updateTicket($ticketId, $newStatus, $message, $resolution); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TicketListener/Trac.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TicketListener/Trac.php new file mode 100644 index 00000000..d13dc1ed --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Extensions/TicketListener/Trac.php @@ -0,0 +1,147 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sean Coates + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Extensions/TicketListener.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A test listener that interact with Trac. + * + * @category Testing + * @package PHPUnit + * @author Sean Coates + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Extensions_TicketListener_Trac extends PHPUnit_Extensions_TicketListener +{ + protected $username; + protected $password; + protected $hostpath; + protected $scheme; + + /** + * Constructor + * + * @param string $user Trac-XMLRPC username + * @param string $pass Trac-XMLRPC password + * @param string $hostpath Trac-XMLRPC Host+Path (e.g. example.com/trac/login/xmlrpc) + * @param string $scheme Trac scheme (http or https) + */ + public function __construct($username, $password, $hostpath, $scheme = 'http') + { + $this->username = $username; + $this->password = $password; + $this->hostpath = $hostpath; + $this->scheme = $scheme; + } + + protected function updateTicket($ticketId, $newStatus, $message, $resolution) + { + if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('XML/RPC2/Client.php')) { + PHPUnit_Util_Filesystem::collectStart(); + require_once 'XML/RPC2/Client.php'; + + $ticket = XML_RPC2_Client::create( + $this->scheme . '://' . + $this->username . ':' . $this->password . '@' . + $this->hostpath, + array('prefix' => 'ticket.') + ); + + try { + $ticketInfo = $ticket->get($ticketId); + } + + catch (XML_RPC2_FaultException $e) { + throw new PHPUnit_Framework_Exception( + sprintf( + "Trac fetch failure: %d: %s\n", + $e->getFaultCode(), + $e->getFaultString() + ) + ); + } + + try { + printf( + "Updating Trac ticket #%d, status: %s\n", + $ticketId, + $newStatus + ); + + $ticket->update( + $ticketId, + $message, + array( + 'status' => $newStatus, + 'resolution' => $resolution + ) + ); + } + + catch (XML_RPC2_FaultException $e) { + throw new PHPUnit_Framework_Exception( + sprintf( + "Trac update failure: %d: %s\n", + $e->getFaultCode(), + $e->getFaultString() + ) + ); + } + + PHPUnit_Util_Filesystem::collectEndAndAddToBlacklist(); + } else { + throw new PHPUnit_Framework_Exception('XML_RPC2 is not available.'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework.php new file mode 100644 index 00000000..bfdb224a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework.php @@ -0,0 +1,73 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +require 'PHPUnit/Framework/Exception.php'; +require 'PHPUnit/Framework/SelfDescribing.php'; +require 'PHPUnit/Framework/AssertionFailedError.php'; +require 'PHPUnit/Framework/Assert.php'; +require 'PHPUnit/Framework/Error.php'; +require 'PHPUnit/Framework/Error/Notice.php'; +require 'PHPUnit/Framework/Error/Warning.php'; +require 'PHPUnit/Framework/IncompleteTest.php'; +require 'PHPUnit/Framework/SkippedTest.php'; +require 'PHPUnit/Framework/Test.php'; +require 'PHPUnit/Framework/TestFailure.php'; +require 'PHPUnit/Framework/TestListener.php'; +require 'PHPUnit/Framework/TestResult.php'; +require 'PHPUnit/Framework/ExpectationFailedException.php'; +require 'PHPUnit/Framework/IncompleteTestError.php'; +require 'PHPUnit/Framework/SkippedTestError.php'; +require 'PHPUnit/Framework/SkippedTestSuiteError.php'; +require 'PHPUnit/Framework/TestCase.php'; +require 'PHPUnit/Framework/TestSuite.php'; +require 'PHPUnit/Framework/TestSuite/DataProvider.php'; +require 'PHPUnit/Framework/Warning.php'; +require 'PHPUnit/Framework/Constraint.php'; +require 'PHPUnit/Framework/ComparisonFailure.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Assert.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Assert.php new file mode 100644 index 00000000..91b20e0a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Assert.php @@ -0,0 +1,2231 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; +require_once 'PHPUnit/Util/Type.php'; +require_once 'PHPUnit/Util/XML.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A set of assert methods. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + * @abstract + */ +abstract class PHPUnit_Framework_Assert +{ + /** + * @var integer + */ + private static $count = 0; + + /** + * Asserts that an array has a specified key. + * + * @param mixed $key + * @param array $array + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertArrayHasKey($key, array $array, $message = '') + { + if (!(is_integer($key) || is_string($key))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'integer or string' + ); + } + + $constraint = new PHPUnit_Framework_Constraint_ArrayHasKey($key); + + self::assertThat($array, $constraint, $message); + } + + /** + * Asserts that an array does not have a specified key. + * + * @param mixed $key + * @param array $array + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertArrayNotHasKey($key, array $array, $message = '') + { + if (!(is_integer($key) || is_string($key))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'integer or string' + ); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ArrayHasKey($key) + ); + + self::assertThat($array, $constraint, $message); + } + + /** + * Asserts that a haystack contains a needle. + * + * @param mixed $needle + * @param mixed $haystack + * @param string $message + * @param boolean $ignoreCase + * @since Method available since Release 2.1.0 + */ + public static function assertContains($needle, $haystack, $message = '', $ignoreCase = FALSE) + { + if (is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable) { + $constraint = new PHPUnit_Framework_Constraint_TraversableContains( + $needle + ); + } + + else if (is_string($haystack)) { + $constraint = new PHPUnit_Framework_Constraint_StringContains( + $needle, $ignoreCase + ); + } + + else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'array, iterator or string' + ); + } + + self::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains a needle. + * + * @param mixed $needle + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @param boolean $ignoreCase + * @since Method available since Release 3.0.0 + */ + public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = FALSE) + { + self::assertContains( + $needle, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message, + $ignoreCase + ); + } + + /** + * Asserts that a haystack does not contain a needle. + * + * @param mixed $needle + * @param mixed $haystack + * @param string $message + * @param boolean $ignoreCase + * @since Method available since Release 2.1.0 + */ + public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = FALSE) + { + if (is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable) { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_TraversableContains($needle) + ); + } + + else if (is_string($haystack)) { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringContains( + $needle, $ignoreCase + ) + ); + } + + else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'array, iterator or string' + ); + } + + self::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain a needle. + * + * @param mixed $needle + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @param boolean $ignoreCase + * @since Method available since Release 3.0.0 + */ + public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = FALSE) + { + self::assertNotContains( + $needle, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message, + $ignoreCase + ); + } + + /** + * Asserts that a haystack contains only values of a given type. + * + * @param string $type + * @param mixed $haystack + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertContainsOnly($type, $haystack, $isNativeType = NULL, $message = '') + { + if (!(is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'array or iterator' + ); + } + + if ($isNativeType == NULL) { + $isNativeType = PHPUnit_Util_Type::isType($type); + } + + self::assertThat( + $haystack, + new PHPUnit_Framework_Constraint_TraversableContainsOnly( + $type, $isNativeType + ), + $message + ); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains only values of a given type. + * + * @param string $type + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = NULL, $message = '') + { + self::assertContainsOnly( + $type, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $isNativeType, + $message + ); + } + + /** + * Asserts that a haystack does not contain only values of a given type. + * + * @param string $type + * @param mixed $haystack + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertNotContainsOnly($type, $haystack, $isNativeType = NULL, $message = '') + { + if (!(is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'array or iterator' + ); + } + + if ($isNativeType == NULL) { + $isNativeType = PHPUnit_Util_Type::isType($type); + } + + self::assertThat( + $haystack, + new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_TraversableContainsOnly( + $type, $isNativeType + ) + ), + $message + ); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain only values of a given + * type. + * + * @param string $type + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = NULL, $message = '') + { + self::assertNotContainsOnly( + $type, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $isNativeType, + $message + ); + } + + /** + * Asserts that two variables are equal. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + */ + public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $expected, $delta, $maxDepth, $canonicalizeEol, $ignoreCase + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a variable is equal to an attribute of an object. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + */ + public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + self::assertEquals( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message, + $delta, + $maxDepth, + $canonicalizeEol, + $ignoreCase + ); + } + + /** + * Asserts that two variables are not equal. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @since Method available since Release 2.3.0 + */ + public static function assertNotEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsEqual( + $expected, $delta, $maxDepth, $canonicalizeEol, $ignoreCase + ) + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a variable is not equal to an attribute of an object. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + */ + public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + self::assertNotEquals( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message, + $delta, + $maxDepth, + $canonicalizeEol, + $ignoreCase + ); + } + + /** + * Asserts that a value is greater than another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertGreaterThan($expected, $actual, $message = '') + { + self::assertThat($actual, self::greaterThan($expected), $message); + } + + /** + * Asserts that an attribute is greater than another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertGreaterThan( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is greater than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertGreaterThanOrEqual($expected, $actual, $message = '') + { + self::assertThat( + $actual, self::greaterThanOrEqual($expected), $message + ); + } + + /** + * Asserts that an attribute is greater than or equal to another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertGreaterThanOrEqual( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is smaller than another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertLessThan($expected, $actual, $message = '') + { + self::assertThat($actual, self::lessThan($expected), $message); + } + + /** + * Asserts that an attribute is smaller than another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertLessThan( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is smaller than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertLessThanOrEqual($expected, $actual, $message = '') + { + self::assertThat($actual, self::lessThanOrEqual($expected), $message); + } + + /** + * Asserts that an attribute is smaller than or equal to another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertLessThanOrEqual( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that the contents of one file is equal to the contents of another + * file. + * + * @param string $expected + * @param string $actual + * @param string $message + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @since Method available since Release 3.2.14 + */ + public static function assertFileEquals($expected, $actual, $message = '', $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + self::assertFileExists($expected, $message); + self::assertFileExists($actual, $message); + + self::assertEquals( + file_get_contents($expected), + file_get_contents($actual), + $message, + 0, + 10, + $canonicalizeEol, + $ignoreCase + ); + } + + /** + * Asserts that the contents of one file is not equal to the contents of + * another file. + * + * @param string $expected + * @param string $actual + * @param string $message + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @since Method available since Release 3.2.14 + */ + public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + self::assertFileExists($expected, $message); + self::assertFileExists($actual, $message); + + self::assertNotEquals( + file_get_contents($expected), + file_get_contents($actual), + $message, + 0, + 10, + $canonicalizeEol, + $ignoreCase + ); + } + + /** + * Asserts that the contents of a string is equal + * to the contents of a file. + * + * @param string $expectedFile + * @param string $actualString + * @param string $message + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @since Method available since Release 3.3.0 + */ + public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + self::assertFileExists($expectedFile, $message); + + self::assertEquals( + file_get_contents($expectedFile), + $actualString, + $message, + 0, + 10, + $canonicalizeEol, + $ignoreCase + ); + } + + /** + * Asserts that the contents of a string is not equal + * to the contents of a file. + * + * @param string $expectedFile + * @param string $actualString + * @param string $message + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @since Method available since Release 3.3.0 + */ + public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + self::assertFileExists($expectedFile, $message); + + self::assertNotEquals( + file_get_contents($expectedFile), + $actualString, + $message, + 0, + 10, + $canonicalizeEol, + $ignoreCase + ); + } + + /** + * Asserts that a file exists. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertFileExists($filename, $message = '') + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_FileExists; + + self::assertThat($filename, $constraint, $message); + } + + /** + * Asserts that a file does not exist. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertFileNotExists($filename, $message = '') + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_FileExists + ); + + self::assertThat($filename, $constraint, $message); + } + + /** + * Asserts that a condition is true. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertTrue($condition, $message = '') + { + self::assertThat($condition, self::isTrue(), $message); + } + + /** + * Asserts that a condition is false. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertFalse($condition, $message = '') + { + self::assertThat($condition, self::isFalse(), $message); + } + + /** + * Asserts that a variable is not NULL. + * + * @param mixed $actual + * @param string $message + */ + public static function assertNotNull($actual, $message = '') + { + self::assertThat($actual, self::logicalNot(self::isNull()), $message); + } + + /** + * Asserts that a variable is NULL. + * + * @param mixed $actual + * @param string $message + */ + public static function assertNull($actual, $message = '') + { + self::assertThat($actual, self::isNull(), $message); + } + + /** + * Asserts that a class has a specified attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassHasAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($className) || !class_exists($className, FALSE)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_ClassHasAttribute( + $attributeName + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that a class does not have a specified attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassNotHasAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($className) || !class_exists($className, FALSE)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ClassHasAttribute($attributeName) + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that a class has a specified static attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassHasStaticAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($className) || !class_exists($className, FALSE)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( + $attributeName + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that a class does not have a specified static attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassNotHasStaticAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($className) || !class_exists($className, FALSE)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( + $attributeName + ) + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that an object has a specified attribute. + * + * @param string $attributeName + * @param object $object + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertObjectHasAttribute($attributeName, $object, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object'); + } + + $constraint = new PHPUnit_Framework_Constraint_ObjectHasAttribute( + $attributeName + ); + + self::assertThat($object, $constraint, $message); + } + + /** + * Asserts that an object does not have a specified attribute. + * + * @param string $attributeName + * @param object $object + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertObjectNotHasAttribute($attributeName, $object, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ObjectHasAttribute($attributeName) + ); + + self::assertThat($object, $constraint, $message); + } + + /** + * Asserts that two variables have the same type and value. + * Used on objects, it asserts that two variables reference + * the same object. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ + public static function assertSame($expected, $actual, $message = '') + { + if (is_bool($expected) && is_bool($actual)) { + self::assertEquals($expected, $actual, $message); + } else { + $constraint = new PHPUnit_Framework_Constraint_IsIdentical( + $expected + ); + + self::assertThat($actual, $constraint, $message); + } + } + + /** + * Asserts that a variable and an attribute of an object have the same type + * and value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param object $actualClassOrObject + * @param string $message + */ + public static function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertSame( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that two variables do not have the same type and value. + * Used on objects, it asserts that two variables do not reference + * the same object. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ + public static function assertNotSame($expected, $actual, $message = '') + { + if (is_bool($expected) && is_bool($actual)) { + self::assertNotEquals($expected, $actual, $message); + } else { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsIdentical($expected) + ); + + self::assertThat($actual, $constraint, $message); + } + } + + /** + * Asserts that a variable and an attribute of an object do not have the + * same type and value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param object $actualClassOrObject + * @param string $message + */ + public static function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertNotSame( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a variable is of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + */ + public static function assertType($expected, $actual, $message = '') + { + if (is_string($expected)) { + if (PHPUnit_Util_Type::isType($expected)) { + $constraint = new PHPUnit_Framework_Constraint_IsType( + $expected + ); + } + + else if (class_exists($expected) || interface_exists($expected)) { + $constraint = new PHPUnit_Framework_Constraint_IsInstanceOf( + $expected + ); + } + + else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'class or interface name' + ); + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertAttributeType($expected, $attributeName, $classOrObject, $message = '') + { + self::assertType( + $expected, + self::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is not of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 2.2.0 + */ + public static function assertNotType($expected, $actual, $message = '') + { + if (is_string($expected)) { + if (PHPUnit_Util_Type::isType($expected)) { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsType($expected) + ); + } + + else if (class_exists($expected) || interface_exists($expected)) { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsInstanceOf($expected) + ); + } + + else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'class or interface name' + ); + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertAttributeNotType($expected, $attributeName, $classOrObject, $message = '') + { + self::assertNotType( + $expected, + self::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a string matches a given regular expression. + * + * @param string $pattern + * @param string $string + * @param string $message + */ + public static function assertRegExp($pattern, $string, $message = '') + { + if (!is_string($pattern)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_PCREMatch($pattern); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string does not match a given regular expression. + * + * @param string $pattern + * @param string $string + * @param string $message + * @since Method available since Release 2.1.0 + */ + public static function assertNotRegExp($pattern, $string, $message = '') + { + if (!is_string($pattern)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_PCREMatch($pattern) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string starts with a given prefix. + * + * @param string $prefix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringStartsWith($prefix, $string, $message = '') + { + if (!is_string($prefix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_StringStartsWith( + $prefix + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string starts not with a given prefix. + * + * @param string $prefix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringStartsNotWith($prefix, $string, $message = '') + { + if (!is_string($prefix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringStartsWith($prefix) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string ends with a given prefix. + * + * @param string $suffix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringEndsWith($suffix, $string, $message = '') + { + if (!is_string($suffix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_StringEndsWith($suffix); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string ends not with a given prefix. + * + * @param string $suffix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringEndsNotWith($suffix, $string, $message = '') + { + if (!is_string($suffix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringEndsWith($suffix) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that two XML files are equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '') + { + self::assertFileExists($expectedFile); + self::assertFileExists($actualFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = FALSE; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = FALSE; + $actual->load($actualFile); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML files are not equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '') + { + self::assertFileExists($expectedFile); + self::assertFileExists($actualFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = FALSE; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = FALSE; + $actual->load($actualFile); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are equal. + * + * @param string $expectedFile + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.3.0 + */ + public static function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '') + { + self::assertFileExists($expectedFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = FALSE; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = FALSE; + $actual->loadXML($actualXml); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param string $expectedFile + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.3.0 + */ + public static function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '') + { + self::assertFileExists($expectedFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = FALSE; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = FALSE; + $actual->loadXML($actualXml); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are equal. + * + * @param string $expectedXml + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '') + { + $expected = new DOMDocument; + $expected->preserveWhiteSpace = FALSE; + $expected->loadXML($expectedXml); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = FALSE; + $actual->loadXML($actualXml); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param string $expectedXml + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '') + { + $expected = new DOMDocument; + $expected->preserveWhiteSpace = FALSE; + $expected->loadXML($expectedXml); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = FALSE; + $actual->loadXML($actualXml); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that a hierarchy of DOMNodes matches. + * + * @param DOMNode $expectedNode + * @param DOMNode $actualNode + * @param boolean $checkAttributes + * @param string $message + * @author Mattis Stordalen Flister + * @since Method available since Release 3.3.0 + */ + public static function assertEqualXMLStructure(DOMNode $expectedNode, DOMNode $actualNode, $checkAttributes = FALSE, $message = '') + { + self::assertEquals( + $expectedNode->tagName, + $actualNode->tagName, + $message + ); + + if ($checkAttributes) { + self::assertEquals( + $expectedNode->attributes->length, + $actualNode->attributes->length, + sprintf( + '%s%sNumber of attributes on node "%s" does not match', + $message, + !empty($message) ? "\n" : '', + $expectedNode->tagName + ) + ); + + for ($i = 0 ; $i < $expectedNode->attributes->length; $i++) { + $expectedAttribute = $expectedNode->attributes->item($i); + $actualAttribute = $actualNode->attributes->getNamedItem( + $expectedAttribute->name + ); + + if (!$actualAttribute) { + self::fail( + sprintf( + '%s%sCould not find attribute "%s" on node "%s"', + $message, + !empty($message) ? "\n" : '', + $expectedAttribute->name, + $expectedNode->tagName + ) + ); + } + } + } + + PHPUnit_Util_XML::removeCharacterDataNodes($expectedNode); + PHPUnit_Util_XML::removeCharacterDataNodes($actualNode); + + self::assertEquals( + $expectedNode->childNodes->length, + $actualNode->childNodes->length, + sprintf( + '%s%sNumber of child nodes of "%s" differs', + $message, + !empty($message) ? "\n" : '', + $expectedNode->tagName + ) + ); + + for ($i = 0; $i < $expectedNode->childNodes->length; $i++) { + self::assertEqualXMLStructure( + $expectedNode->childNodes->item($i), + $actualNode->childNodes->item($i), + $checkAttributes, + $message + ); + } + } + + /** + * Assert the presence, absence, or count of elements in a document matching + * the CSS $selector, regardless of the contents of those elements. + * + * The first argument, $selector, is the CSS selector used to match + * the elements in the $actual document. + * + * The second argument, $count, can be either boolean or numeric. + * When boolean, it asserts for presence of elements matching the selector + * (TRUE) or absence of elements (FALSE). + * When numeric, it asserts the count of elements. + * + * assertSelectCount("#binder", true, $xml); // any? + * assertSelectCount(".binder", 3, $xml); // exactly 3? + * + * @param array $selector + * @param integer $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = TRUE) + { + self::assertSelectEquals( + $selector, TRUE, $count, $actual, $message, $isHtml + ); + } + + /** + * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any? + * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml); // 3? + * + * @param array $selector + * @param string $pattern + * @param integer $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = TRUE) + { + self::assertSelectEquals( + $selector, "regexp:$pattern", $count, $actual, $message, $isHtml + ); + } + + /** + * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any? + * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none? + * + * @param array $selector + * @param string $content + * @param integer $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = TRUE) + { + $tags = PHPUnit_Util_XML::cssSelect( + $selector, $content, $actual, $isHtml + ); + + // assert specific number of elements + if (is_numeric($count)) { + $counted = $tags ? count($tags) : 0; + self::assertEquals($count, $counted); + } + + // assert any elements exist if true, assert no elements exist if false + else if (is_bool($count)) { + $any = count($tags) > 0 && $tags[0] instanceof DOMNode; + + if ($count) { + self::assertTrue($any, $message); + } else { + self::assertFalse($any, $message); + } + } + + // check for range number of elements + else if (is_array($count) && + (isset($count['>']) || isset($count['<']) || + isset($count['>=']) || isset($count['<=']))) { + $counted = $tags ? count($tags) : 0; + + if (isset($count['>'])) { + self::assertTrue($counted > $count['>'], $message); + } + + if (isset($count['>='])) { + self::assertTrue($counted >= $count['>='], $message); + } + + if (isset($count['<'])) { + self::assertTrue($counted < $count['<'], $message); + } + + if (isset($count['<='])) { + self::assertTrue($counted <= $count['<='], $message); + } + } else { + throw new InvalidArgumentException(); + } + } + + /** + * Evaluate an HTML or XML string and assert its structure and/or contents. + * + * The first argument ($matcher) is an associative array that specifies the + * match criteria for the assertion: + * + * - `id` : the node with the given id attribute must match the + * corresponsing value. + * - `tag` : the node type must match the corresponding value. + * - `attributes` : a hash. The node's attributres must match the + * corresponsing values in the hash. + * - `content` : The text content must match the given value. + * - `parent` : a hash. The node's parent must match the + * corresponsing hash. + * - `child` : a hash. At least one of the node's immediate children + * must meet the criteria described by the hash. + * - `ancestor` : a hash. At least one of the node's ancestors must + * meet the criteria described by the hash. + * - `descendant` : a hash. At least one of the node's descendants must + * meet the criteria described by the hash. + * - `children` : a hash, for counting children of a node. + * Accepts the keys: + * - `count` : a number which must equal the number of children + * that match + * - `less_than` : the number of matching children must be greater + * than this number + * - `greater_than` : the number of matching children must be less than + * this number + * - `only` : another hash consisting of the keys to use to match + * on the children, and only matching children will be + * counted + * + * + * // Matcher that asserts that there is an element with an id="my_id". + * $matcher = array('id' => 'my_id'); + * + * // Matcher that asserts that there is a "span" tag. + * $matcher = array('tag' => 'span'); + * + * // Matcher that asserts that there is a "span" tag with the content + * // "Hello World". + * $matcher = array('tag' => 'span', 'content' => 'Hello World'); + * + * // Matcher that asserts that there is a "span" tag with content matching + * // the regular expression pattern. + * $matcher = array('tag' => 'span', 'content' => '/Try P(HP|ython)/'); + * + * // Matcher that asserts that there is a "span" with an "list" class + * // attribute. + * $matcher = array( + * 'tag' => 'span', + * 'attributes' => array('class' => 'list') + * ); + * + * // Matcher that asserts that there is a "span" inside of a "div". + * $matcher = array( + * 'tag' => 'span', + * 'parent' => array('tag' => 'div') + * ); + * + * // Matcher that asserts that there is a "span" somewhere inside a + * // "table". + * $matcher = array( + * 'tag' => 'span', + * 'ancestor' => array('tag' => 'table') + * ); + * + * // Matcher that asserts that there is a "span" with at least one "em" + * // child. + * $matcher = array( + * 'tag' => 'span', + * 'child' => array('tag' => 'em') + * ); + * + * // Matcher that asserts that there is a "span" containing a (possibly + * // nested) "strong" tag. + * $matcher = array( + * 'tag' => 'span', + * 'descendant' => array('tag' => 'strong') + * ); + * + * // Matcher that asserts that there is a "span" containing 5-10 "em" tags + * // as immediate children. + * $matcher = array( + * 'tag' => 'span', + * 'children' => array( + * 'less_than' => 11, + * 'greater_than' => 4, + * 'only' => array('tag' => 'em') + * ) + * ); + * + * // Matcher that asserts that there is a "div", with an "ul" ancestor and + * // a "li" parent (with class="enum"), and containing a "span" descendant + * // that contains an element with id="my_test" and the text "Hello World". + * $matcher = array( + * 'tag' => 'div', + * 'ancestor' => array('tag' => 'ul'), + * 'parent' => array( + * 'tag' => 'li', + * 'attributes' => array('class' => 'enum') + * ), + * 'descendant' => array( + * 'tag' => 'span', + * 'child' => array( + * 'id' => 'my_test', + * 'content' => 'Hello World' + * ) + * ) + * ); + * + * // Use assertTag() to apply a $matcher to a piece of $html. + * $this->assertTag($matcher, $html); + * + * // Use assertTag() to apply a $matcher to a piece of $xml. + * $this->assertTag($matcher, $xml, '', FALSE); + * + * + * The second argument ($actual) is a string containing either HTML or + * XML text to be tested. + * + * The third argument ($message) is an optional message that will be + * used if the assertion fails. + * + * The fourth argument ($html) is an optional flag specifying whether + * to load the $actual string into a DOMDocument using the HTML or + * XML load strategy. It is TRUE by default, which assumes the HTML + * load strategy. In many cases, this will be acceptable for XML as well. + * + * @param array $matcher + * @param string $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertTag($matcher, $actual, $message = '', $isHtml = TRUE) + { + $dom = PHPUnit_Util_XML::load($actual, $isHtml); + $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml); + $matched = count($tags) > 0 && $tags[0] instanceof DOMNode; + + self::assertTrue($matched, $message); + } + + /** + * This assertion is the exact opposite of assertTag(). + * + * Rather than asserting that $matcher results in a match, it asserts that + * $matcher does not match. + * + * @param array $matcher + * @param string $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertNotTag($matcher, $actual, $message = '', $isHtml = TRUE) + { + $dom = PHPUnit_Util_XML::load($actual, $isHtml); + $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml); + $matched = count($tags) > 0 && $tags[0] instanceof DOMNode; + + self::assertFalse($matched, $message); + } + + /** + * Evaluates a PHPUnit_Framework_Constraint matcher object. + * + * @param mixed $value + * @param PHPUnit_Framework_Constraint $constraint + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '') + { + self::$count += count($constraint); + + if (!$constraint->evaluate($value)) { + $constraint->fail($value, $message); + } + } + + /** + * Returns a PHPUnit_Framework_Constraint_And matcher object. + * + * @return PHPUnit_Framework_Constraint_And + * @since Method available since Release 3.0.0 + */ + public static function logicalAnd() + { + $constraints = func_get_args(); + + $constraint = new PHPUnit_Framework_Constraint_And; + $constraint->setConstraints($constraints); + + return $constraint; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Or matcher object. + * + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.0.0 + */ + public static function logicalOr() + { + $constraints = func_get_args(); + + $constraint = new PHPUnit_Framework_Constraint_Or; + $constraint->setConstraints($constraints); + + return $constraint; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Not matcher object. + * + * @param PHPUnit_Framework_Constraint $constraint + * @return PHPUnit_Framework_Constraint_Not + * @since Method available since Release 3.0.0 + */ + public static function logicalNot(PHPUnit_Framework_Constraint $constraint) + { + return new PHPUnit_Framework_Constraint_Not($constraint); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Xor matcher object. + * + * @return PHPUnit_Framework_Constraint_Xor + * @since Method available since Release 3.0.0 + */ + public static function logicalXor() + { + $constraints = func_get_args(); + + $constraint = new PHPUnit_Framework_Constraint_Xor; + $constraint->setConstraints($constraints); + + return $constraint; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object. + * + * @return PHPUnit_Framework_Constraint_IsAnything + * @since Method available since Release 3.0.0 + */ + public static function anything() + { + return new PHPUnit_Framework_Constraint_IsAnything; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object. + * + * @return PHPUnit_Framework_Constraint_IsTrue + * @since Method available since Release 3.3.0 + */ + public static function isTrue() + { + return new PHPUnit_Framework_Constraint_IsTrue; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object. + * + * @return PHPUnit_Framework_Constraint_IsFalse + * @since Method available since Release 3.3.0 + */ + public static function isFalse() + { + return new PHPUnit_Framework_Constraint_IsFalse; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsNull matcher object. + * + * @return PHPUnit_Framework_Constraint_IsNull + * @since Method available since Release 3.3.0 + */ + public static function isNull() + { + return new PHPUnit_Framework_Constraint_IsNull; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Attribute matcher object. + * + * @param PHPUnit_Framework_Constraint $constraint + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_Attribute + * @since Method available since Release 3.1.0 + */ + public static function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName) + { + return new PHPUnit_Framework_Constraint_Attribute( + $constraint, $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher + * object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_TraversableContains + * @since Method available since Release 3.0.0 + */ + public static function contains($value) + { + return new PHPUnit_Framework_Constraint_TraversableContains($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher + * object. + * + * @param string $type + * @return PHPUnit_Framework_Constraint_TraversableContainsOnly + * @since Method available since Release 3.1.4 + */ + public static function containsOnly($type) + { + return new PHPUnit_Framework_Constraint_TraversableContainsOnly($type); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object. + * + * @param mixed $key + * @return PHPUnit_Framework_Constraint_ArrayHasKey + * @since Method available since Release 3.0.0 + */ + public static function arrayHasKey($key) + { + return new PHPUnit_Framework_Constraint_ArrayHasKey($key); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object. + * + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @return PHPUnit_Framework_Constraint_IsEqual + * @since Method available since Release 3.0.0 + */ + public static function equalTo($value, $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + return new PHPUnit_Framework_Constraint_IsEqual( + $value, $delta, $maxDepth, $canonicalizeEol, $ignoreCase + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object + * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher + * object. + * + * @param string $attributeName + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + * @return PHPUnit_Framework_Constraint_Attribute + * @since Method available since Release 3.1.0 + */ + public static function attributeEqualTo($attributeName, $value, $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + return self::attribute( + self::equalTo( + $value, $delta, $maxDepth, $canonicalizeEol, $ignoreCase + ), + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_FileExists matcher object. + * + * @return PHPUnit_Framework_Constraint_FileExists + * @since Method available since Release 3.0.0 + */ + public static function fileExists() + { + return new PHPUnit_Framework_Constraint_FileExists; + } + + /** + * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_GreaterThan + * @since Method available since Release 3.0.0 + */ + public static function greaterThan($value) + { + return new PHPUnit_Framework_Constraint_GreaterThan($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps + * a PHPUnit_Framework_Constraint_IsEqual and a + * PHPUnit_Framework_Constraint_GreaterThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.1.0 + */ + public static function greaterThanOrEqual($value) + { + return self::logicalOr( + new PHPUnit_Framework_Constraint_IsEqual($value), + new PHPUnit_Framework_Constraint_GreaterThan($value) + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ClassHasAttribute + * @since Method available since Release 3.1.0 + */ + public static function classHasAttribute($attributeName) + { + return new PHPUnit_Framework_Constraint_ClassHasAttribute( + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher + * object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @since Method available since Release 3.1.0 + */ + public static function classHasStaticAttribute($attributeName) + { + return new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ObjectHasAttribute + * @since Method available since Release 3.0.0 + */ + public static function objectHasAttribute($attributeName) + { + return new PHPUnit_Framework_Constraint_ObjectHasAttribute( + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_IsIdentical + * @since Method available since Release 3.0.0 + */ + public static function identicalTo($value) + { + return new PHPUnit_Framework_Constraint_IsIdentical($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object. + * + * @param string $className + * @return PHPUnit_Framework_Constraint_IsInstanceOf + * @since Method available since Release 3.0.0 + */ + public static function isInstanceOf($className) + { + return new PHPUnit_Framework_Constraint_IsInstanceOf($className); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsType matcher object. + * + * @param string $type + * @return PHPUnit_Framework_Constraint_IsType + * @since Method available since Release 3.0.0 + */ + public static function isType($type) + { + return new PHPUnit_Framework_Constraint_IsType($type); + } + + /** + * Returns a PHPUnit_Framework_Constraint_LessThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_LessThan + * @since Method available since Release 3.0.0 + */ + public static function lessThan($value) + { + return new PHPUnit_Framework_Constraint_LessThan($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps + * a PHPUnit_Framework_Constraint_IsEqual and a + * PHPUnit_Framework_Constraint_LessThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.1.0 + */ + public static function lessThanOrEqual($value) + { + return self::logicalOr( + new PHPUnit_Framework_Constraint_IsEqual($value), + new PHPUnit_Framework_Constraint_LessThan($value) + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object. + * + * @param string $pattern + * @return PHPUnit_Framework_Constraint_PCREMatch + * @since Method available since Release 3.0.0 + */ + public static function matchesRegularExpression($pattern) + { + return new PHPUnit_Framework_Constraint_PCREMatch($pattern); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object. + * + * @param mixed $prefix + * @return PHPUnit_Framework_Constraint_StringStartsWith + * @since Method available since Release 3.4.0 + */ + public static function stringStartsWith($prefix) + { + return new PHPUnit_Framework_Constraint_StringStartsWith($prefix); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringContains matcher object. + * + * @param string $string + * @param boolean $case + * @return PHPUnit_Framework_Constraint_StringContains + * @since Method available since Release 3.0.0 + */ + public static function stringContains($string, $case = TRUE) + { + return new PHPUnit_Framework_Constraint_StringContains($string, $case); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object. + * + * @param mixed $suffix + * @return PHPUnit_Framework_Constraint_StringEndsWith + * @since Method available since Release 3.4.0 + */ + public static function stringEndsWith($suffix) + { + return new PHPUnit_Framework_Constraint_StringEndsWith($suffix); + } + + /** + * Fails a test with the given message. + * + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function fail($message = '') + { + throw new PHPUnit_Framework_AssertionFailedError($message); + } + + /** + * Returns the value of an attribute of a class or an object. + * This also works for attributes that are declared protected or private. + * + * @param mixed $classOrObject + * @param string $attributeName + * @return mixed + * @throws InvalidArgumentException + */ + public static function readAttribute($classOrObject, $attributeName) + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + if (is_string($classOrObject)) { + if (!class_exists($classOrObject)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'class name' + ); + } + + return PHPUnit_Util_Class::getStaticAttribute( + $classOrObject, + $attributeName + ); + } + + else if (is_object($classOrObject)) { + return PHPUnit_Util_Class::getObjectAttribute( + $classOrObject, + $attributeName + ); + } + + else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'class name or object' + ); + } + } + + /** + * Mark the test as incomplete. + * + * @param string $message + * @throws PHPUnit_Framework_IncompleteTestError + * @since Method available since Release 3.0.0 + */ + public static function markTestIncomplete($message = '') + { + throw new PHPUnit_Framework_IncompleteTestError($message); + } + + /** + * Mark the test as skipped. + * + * @param string $message + * @throws PHPUnit_Framework_SkippedTestError + * @since Method available since Release 3.0.0 + */ + public static function markTestSkipped($message = '') + { + throw new PHPUnit_Framework_SkippedTestError($message); + } + + /** + * Return the current assertion count. + * + * @return integer + * @since Method available since Release 3.3.3 + */ + public static function getCount() + { + return self::$count; + } + + /** + * Reset the assertion counter. + * + * @since Method available since Release 3.3.3 + */ + public static function resetCount() + { + self::$count = 0; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/AssertionFailedError.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/AssertionFailedError.php new file mode 100644 index 00000000..264a9995 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/AssertionFailedError.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_AssertionFailedError extends Exception implements PHPUnit_Framework_SelfDescribing +{ + /** + * Wrapper for getMessage() which is declared as final. + * + * @return string + */ + public function toString() + { + return $this->getMessage(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure.php new file mode 100644 index 00000000..737f3aba --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure.php @@ -0,0 +1,220 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion for string equality failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +abstract class PHPUnit_Framework_ComparisonFailure extends PHPUnit_Framework_AssertionFailedError +{ + /** + * Expected value of the retrieval which does not match $actual. + * @var mixed + */ + protected $expected; + + /** + * Actually retrieved value which does not match $expected. + * @var mixed + */ + protected $actual; + + /** + * @var boolean + */ + protected $identical; + + /** + * Optional message which is placed in front of the first line + * returned by toString(). + * @var string + */ + protected $message; + + /** + * Initialises with the expected value and the actual value. + * + * @param mixed $expected Expected value retrieved. + * @param mixed $actual Actual value retrieved. + * @param boolean $identical + * @param string $message A string which is prefixed on all returned lines + * in the difference output. + */ + public function __construct($expected, $actual, $identical = FALSE, $message = '') + { + $this->expected = $expected; + $this->actual = $actual; + $this->identical = $identical; + $this->message = $message; + } + + /** + * @return mixed + */ + public function getActual() + { + return $this->actual; + } + + /** + * @return mixed + */ + public function getExpected() + { + return $this->expected; + } + + /** + * @return boolean + */ + public function identical() + { + return $this->identical; + } + + /** + * Figures out which diff class to use for the input types then + * instantiates that class and returns the object. + * @note The diff is type sensitive, if the type differs only the types + * are shown. + * + * @param mixed $expected Expected value retrieved. + * @param mixed $actual Actual value retrieved. + * @param string $message A string which is prefixed on all returned lines + * in the difference output. + * @return PHPUnit_Framework_ComparisonFailure + */ + public static function diffIdentical($expected, $actual, $message = '') + { + if (gettype($expected) !== gettype($actual)) { + return new PHPUnit_Framework_ComparisonFailure_Type( + $expected, $actual, TRUE, $message + ); + } + + else if (is_array($expected) && is_array($actual)) { + return new PHPUnit_Framework_ComparisonFailure_Array( + $expected, $actual, TRUE, $message + ); + } + + else if (is_object($expected) && is_object($actual)) { + return new PHPUnit_Framework_ComparisonFailure_Object( + $expected, $actual, TRUE, $message + ); + } + + else if (is_string($expected) && !is_object($actual)) { + return new PHPUnit_Framework_ComparisonFailure_String( + $expected, $actual, TRUE, $message + ); + } + + else if (is_null($expected) || is_scalar($expected)) { + return new PHPUnit_Framework_ComparisonFailure_Scalar( + $expected, $actual, TRUE, $message + ); + } + } + + /** + * Figures out which diff class to use for the input types then + * instantiates that class and returns the object. + * @note The diff is not type sensitive, if the type differs the $actual + * value will be converted to the same type as the $expected. + * + * @param mixed $expected Expected value retrieved. + * @param mixed $actual Actual value retrieved. + * @param string $message A string which is prefixed on all returned lines + * in the difference output. + * @return PHPUnit_Framework_ComparisonFailure + */ + public static function diffEqual($expected, $actual, $message = '') + { + if (is_array($expected) && is_array($actual)) { + return new PHPUnit_Framework_ComparisonFailure_Array( + $expected, $actual, FALSE, $message + ); + } + + else if (is_object($expected) && is_object($actual)) { + return new PHPUnit_Framework_ComparisonFailure_Object( + $expected, $actual, FALSE, $message + ); + } + + else if (is_string($expected) && !is_object($actual)) { + return new PHPUnit_Framework_ComparisonFailure_String( + $expected, $actual, FALSE, $message + ); + } + + else if (is_null($expected) || is_scalar($expected)) { + return new PHPUnit_Framework_ComparisonFailure_Scalar( + $expected, $actual, FALSE, $message + ); + } + } +} + +require_once 'PHPUnit/Framework/ComparisonFailure/Array.php'; +require_once 'PHPUnit/Framework/ComparisonFailure/Object.php'; +require_once 'PHPUnit/Framework/ComparisonFailure/Scalar.php'; +require_once 'PHPUnit/Framework/ComparisonFailure/String.php'; +require_once 'PHPUnit/Framework/ComparisonFailure/Type.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Array.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Array.php new file mode 100644 index 00000000..2ba344a3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Array.php @@ -0,0 +1,142 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Diff.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion for array equality failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ComparisonFailure_Array extends PHPUnit_Framework_ComparisonFailure +{ + /** + * Returns a string describing the difference between the expected and the + * actual array. + * + * @return string + */ + public function toString() + { + $diff = PHPUnit_Util_Diff::diff( + print_r($this->expected, TRUE), + print_r($this->actual, TRUE) + ); + + if ($diff !== FALSE) { + return trim($diff); + } + + // Fallback: Either diff is not available or the print_r() output for + // the expected and the actual array are equal (but the arrays are not). + + $expectedOnly = array(); + $actualOnly = array(); + $diff = ''; + + foreach ($this->expected as $expectedKey => $expectedValue) { + if (!array_key_exists($expectedKey, $this->actual)) { + $expectedOnly[] = $expectedKey; + continue; + } + + if ($expectedValue === $this->actual[$expectedKey]) { + continue; + } + + $diffObject = PHPUnit_Framework_ComparisonFailure::diffIdentical( + $expectedValue, + $this->actual[$expectedKey], + sprintf( + '%sarray key %s: ', + + $this->message, + PHPUnit_Util_Type::toString($expectedKey) + ) + ); + + $diff .= $diffObject->toString() . "\n"; + } + + foreach ($this->actual as $actualKey => $actualValue) { + if (!array_key_exists($actualKey, $this->expected)) { + $actualOnly[] = $actualKey; + continue; + } + } + + foreach ($expectedOnly as $expectedKey) { + $diff .= sprintf( + "array key %s: only in expected %s\n", + + PHPUnit_Util_Type::toString($expectedKey), + PHPUnit_Util_Type::toString($this->expected[$expectedKey]) + ); + } + + foreach ($actualOnly as $actualKey) { + $diff .= sprintf( + "array key %s: only in actual %s\n", + + PHPUnit_Util_Type::toString($actualKey), + PHPUnit_Util_Type::toString($this->actual[$actualKey]) + ); + } + + return $diff; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Object.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Object.php new file mode 100644 index 00000000..3828ff60 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Object.php @@ -0,0 +1,177 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Diff.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion for object equality failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ComparisonFailure_Object extends PHPUnit_Framework_ComparisonFailure +{ + /** + * Returns a string describing the difference between the expected and the + * actual object. + * + * @return string + */ + public function toString() + { + $diff = PHPUnit_Util_Diff::diff( + print_r($this->expected, TRUE), + print_r($this->actual, TRUE) + ); + + if ($diff !== FALSE) { + return trim($diff); + } + + // Fallback: Either diff is not available or the print_r() output for + // the expected and the actual object are equal (but the objects are + // not). + + $expectedClass = get_class($this->expected); + $actualClass = get_class($this->actual); + + if ($expectedClass !== $actualClass) { + return sprintf( + "%s%sexpected class <%s>\n" . + '%sgot class <%s>', + + $this->message, + ($this->message != '') ? ' ' : '', + $expectedClass, + ($this->message != '') ? str_repeat(' ', strlen($this->message) + 1) : '', + $actualClass + ); + } else { + $expectedReflection = new ReflectionClass($expectedClass); + $actualReflection = new ReflectionClass($actualClass); + + $diff = "in object of class <{$expectedClass}>:\n"; + $i = 0; + + foreach($expectedReflection->getProperties() as $expectedAttribute) { + if ($expectedAttribute->isPrivate() || + $expectedAttribute->isProtected()) { + continue; + } + + $actualAttribute = $actualReflection->getProperty( + $expectedAttribute->getName() + ); + $expectedValue = $expectedAttribute->getValue( + $this->expected + ); + $actualValue = $actualAttribute->getValue($this->actual); + + if ($expectedValue !== $actualValue) { + if ($i > 0) { + $diff .= "\n"; + } + + ++$i; + + $expectedType = gettype($expectedValue); + $actualType = gettype($actualValue); + + if ($expectedType !== $actualType) { + $diffObject = new PHPUnit_Framework_ComparisonFailure_Type( + $expectedValue, + $actualValue, + $this->message . 'attribute <' . + $expectedAttribute->getName() . '>: ' + ); + + $diff .= $diffObject->toString(); + } + + elseif (is_object($expectedValue)) { + if (get_class($expectedValue) !== get_class($actualValue)) { + $diffObject = new PHPUnit_Framework_ComparisonFailure_Type( + $expectedValue, + $actualValue, + $this->message . 'attribute <' . + $expectedAttribute->getName() . '>: ' + ); + + $diff .= $diffObject->toString(); + } else { + $diff .= 'attribute <' . + $expectedAttribute->getName() . + '> contains object <' . + get_class($expectedValue) . + '> with different attributes'; + } + } else { + $diffObject = PHPUnit_Framework_ComparisonFailure::diffIdentical( + $expectedValue, + $actualValue, + $this->message . 'attribute <' . + $expectedAttribute->getName() . '>: ' + ); + + $diff .= $diffObject->toString(); + } + } + } + + return $diff; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Scalar.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Scalar.php new file mode 100644 index 00000000..70d7e2a6 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Scalar.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion for scalar equality failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ComparisonFailure_Scalar extends PHPUnit_Framework_ComparisonFailure +{ + /** + * Returns a string describing the difference between the expected and the + * actual scalar value. + */ + public function toString() + { + return ''; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/String.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/String.php new file mode 100644 index 00000000..5ca8f03f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/String.php @@ -0,0 +1,89 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Diff.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion for string equality failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ComparisonFailure_String extends PHPUnit_Framework_ComparisonFailure +{ + /** + * Returns a string describing the difference between + * the expected and the actual string value. + */ + public function toString() + { + $expected = (string)$this->expected; + $actual = (string)$this->actual; + $diff = PHPUnit_Util_Diff::diff($expected, $actual); + + if ($diff === FALSE) { + $diff = ''; + } + + if (!empty($this->message)) { + $buffer = $this->message . "\n"; + } else { + $buffer = ''; + } + + return trim($buffer . $diff); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Type.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Type.php new file mode 100644 index 00000000..243622ef --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ComparisonFailure/Type.php @@ -0,0 +1,79 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Thrown when an assertion for type equality failed. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ComparisonFailure_Type extends PHPUnit_Framework_ComparisonFailure +{ + /** + * Returns a string describing the type difference between the expected + * and the actual value. + */ + public function toString() + { + return sprintf( + '%s does not match expected type "%s".', + + PHPUnit_Util_Type::toString($this->actual), + gettype($this->expected) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint.php new file mode 100644 index 00000000..bdd0625b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint.php @@ -0,0 +1,200 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for constraints. which are placed upon any value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +abstract class PHPUnit_Framework_Constraint implements Countable, PHPUnit_Framework_SelfDescribing +{ + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + return 1; + } + + /** + * Creates the appropriate exception for the constraint which can be caught + * by the unit test system. This can be called if a call to evaluate() + * fails. + * + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + throw new PHPUnit_Framework_ExpectationFailedException( + $this->failureDescription($other, $description, $not), + NULL + ); + } + + /** + * @param mixed $other + * @param string $description + * @param boolean $not + */ + protected function failureDescription($other, $description, $not) + { + $failureDescription = $this->customFailureDescription( + $other, $description, $not + ); + + if ($failureDescription === NULL) { + $failureDescription = sprintf( + 'Failed asserting that %s %s.', + + PHPUnit_Util_Type::toString($other), + $this->toString() + ); + } + + if ($not) { + $failureDescription = self::negate($failureDescription); + } + + if (!empty($description)) { + $failureDescription = $description . "\n" . $failureDescription; + } + + return $failureDescription; + } + + /** + * @param mixed $other + * @param string $description + * @param boolean $not + */ + protected function customFailureDescription($other, $description, $not) + { + } + + /** + * @param string $string + * @return string + */ + public static function negate($string) + { + return str_replace( + array( + 'contains ', + 'exists', + 'has ', + 'is ', + 'matches ', + 'starts with ', + 'ends with ' + ), + array( + 'does not contain ', + 'does not exist', + 'does not have ', + 'is not ', + 'does not match ', + 'starts not with ', + 'ends not with ' + ), + $string + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + abstract public function evaluate($other); +} + +require_once 'PHPUnit/Framework/Constraint/And.php'; +require_once 'PHPUnit/Framework/Constraint/ArrayHasKey.php'; +require_once 'PHPUnit/Framework/Constraint/Attribute.php'; +require_once 'PHPUnit/Framework/Constraint/ClassHasAttribute.php'; +require_once 'PHPUnit/Framework/Constraint/ClassHasStaticAttribute.php'; +require_once 'PHPUnit/Framework/Constraint/IsFalse.php'; +require_once 'PHPUnit/Framework/Constraint/FileExists.php'; +require_once 'PHPUnit/Framework/Constraint/GreaterThan.php'; +require_once 'PHPUnit/Framework/Constraint/IsAnything.php'; +require_once 'PHPUnit/Framework/Constraint/IsEqual.php'; +require_once 'PHPUnit/Framework/Constraint/IsIdentical.php'; +require_once 'PHPUnit/Framework/Constraint/IsInstanceOf.php'; +require_once 'PHPUnit/Framework/Constraint/IsType.php'; +require_once 'PHPUnit/Framework/Constraint/LessThan.php'; +require_once 'PHPUnit/Framework/Constraint/Not.php'; +require_once 'PHPUnit/Framework/Constraint/IsNull.php'; +require_once 'PHPUnit/Framework/Constraint/ObjectHasAttribute.php'; +require_once 'PHPUnit/Framework/Constraint/Or.php'; +require_once 'PHPUnit/Framework/Constraint/PCREMatch.php'; +require_once 'PHPUnit/Framework/Constraint/StringContains.php'; +require_once 'PHPUnit/Framework/Constraint/StringStartsWith.php'; +require_once 'PHPUnit/Framework/Constraint/StringEndsWith.php'; +require_once 'PHPUnit/Framework/Constraint/TraversableContains.php'; +require_once 'PHPUnit/Framework/Constraint/TraversableContainsOnly.php'; +require_once 'PHPUnit/Framework/Constraint/IsTrue.php'; +require_once 'PHPUnit/Framework/Constraint/Xor.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/And.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/And.php new file mode 100644 index 00000000..9703ff61 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/And.php @@ -0,0 +1,167 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Logical AND. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_And extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint[] + */ + protected $constraints = array(); + + /** + * @var PHPUnit_Framework_Constraint + */ + protected $lastConstraint = NULL; + + /** + * @param PHPUnit_Framework_Constraint[] $constraints + */ + public function setConstraints(array $constraints) + { + $this->constraints = array(); + + foreach($constraints as $key => $constraint) { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + throw new InvalidArgumentException( + 'All parameters to ' . __CLASS__ . + ' must be a constraint object.' + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + $this->lastConstraint = NULL; + + foreach($this->constraints as $constraint) { + $this->lastConstraint = $constraint; + + if (!$constraint->evaluate($other)) { + return FALSE; + } + } + + return TRUE; + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + $this->lastConstraint->fail($other, $description, $not); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $text = ''; + + foreach($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' and '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + $count = 1; + + foreach ($this->constraints as $constraint) { + $count += count($constraint); + } + + return $count; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ArrayHasKey.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ArrayHasKey.php new file mode 100644 index 00000000..47a1255d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ArrayHasKey.php @@ -0,0 +1,120 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the array it is evaluated for has a given key. + * + * Uses array_key_exists() to check if the key is found in the input array, if + * not found the evaluaton fails. + * + * The array key is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_ArrayHasKey extends PHPUnit_Framework_Constraint +{ + /** + * @var integer|string + */ + protected $key; + + /** + * @param integer|string $key + */ + public function __construct($key) + { + $this->key = $key; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return array_key_exists($this->key, $other); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'has the key ' . PHPUnit_Util_Type::toString($this->key); + } + + /** + * @param mixed $other + * @param string $description + * @param boolean $not + */ + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that an array %s.', + + $this->toString() + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Attribute.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Attribute.php new file mode 100644 index 00000000..8d93b955 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Attribute.php @@ -0,0 +1,155 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ + +class PHPUnit_Framework_Constraint_Attribute extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $attributeName; + + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @param PHPUnit_Framework_Constraint $constraint + * @param string $attributeName + */ + public function __construct(PHPUnit_Framework_Constraint $constraint, $attributeName) + { + $this->attributeName = $attributeName; + $this->constraint = $constraint; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $this->constraint->evaluate( + PHPUnit_Framework_Assert::readAttribute( + $other, $this->attributeName + ) + ); + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + parent::fail( + PHPUnit_Framework_Assert::readAttribute( + $other, $this->attributeName + ), + $description, + $not + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'attribute "' . $this->attributeName . '" ' . + $this->constraint->toString(); + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + return count($this->constraint) + 1; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that %s.', + + $this->toString() + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ClassHasAttribute.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ClassHasAttribute.php new file mode 100644 index 00000000..b14e8e73 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ClassHasAttribute.php @@ -0,0 +1,117 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the class it is evaluated for has a given + * attribute. + * + * The attribute name is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_Constraint_ClassHasAttribute extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $attributeName; + + /** + * @param string $attributeName + */ + public function __construct($attributeName) + { + $this->attributeName = $attributeName; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + $class = new ReflectionClass($other); + + return $class->hasProperty($this->attributeName); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'has attribute "%s"', + + $this->attributeName + ); + } + + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that class "%s" %s.', $other, $this->toString() + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ClassHasStaticAttribute.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ClassHasStaticAttribute.php new file mode 100644 index 00000000..d058a94c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ClassHasStaticAttribute.php @@ -0,0 +1,104 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the class it is evaluated for has a given + * static attribute. + * + * The attribute name is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_Constraint_ClassHasStaticAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + $class = new ReflectionClass($other); + + if ($class->hasProperty($this->attributeName)) { + $attribute = $class->getProperty($this->attributeName); + + return $attribute->isStatic(); + } else { + return FALSE; + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + * @since Method available since Release 3.3.0 + */ + public function toString() + { + return sprintf( + 'has static attribute "%s"', + + $this->attributeName + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/FileExists.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/FileExists.php new file mode 100644 index 00000000..f6d9324e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/FileExists.php @@ -0,0 +1,118 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that checks if the file(name) that it is evaluated for exists. + * + * The file path to check is passed as $other in evaluate(). + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_FileExists extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return file_exists($other); + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + $failureDescription = sprintf( + 'Failed asserting that file "%s" exists.', + + $other + ); + + if ($not) { + $failureDescription = self::negate($failureDescription); + } + + if (!empty($description)) { + $failureDescription = $description . "\n" . $failureDescription; + } + + throw new PHPUnit_Framework_ExpectationFailedException( + $failureDescription + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'file exists'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/GreaterThan.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/GreaterThan.php new file mode 100644 index 00000000..b427e3a7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/GreaterThan.php @@ -0,0 +1,102 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the value it is evaluated for is greater + * than a given value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_GreaterThan extends PHPUnit_Framework_Constraint +{ + /** + * @var numeric + */ + protected $value; + + /** + * @param numeric $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $this->value < $other; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is greater than ' . PHPUnit_Util_Type::toString($this->value); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsAnything.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsAnything.php new file mode 100644 index 00000000..355ce78b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsAnything.php @@ -0,0 +1,98 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that accepts any input value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsAnything extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return TRUE; + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + */ + public function fail($other, $description, $not = FALSE) + { + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is anything'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsEqual.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsEqual.php new file mode 100644 index 00000000..7fb7a9e9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsEqual.php @@ -0,0 +1,390 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Kore Nordmann + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that checks if one value is equal to another. + * + * Equality is checked with PHP's == operator, the operator is explained in + * detail at {@url http://www.php.net/manual/en/types.comparisons.php}. + * Two values are equal if they have the same value disregarding type. + * + * The expected value is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Kore Nordmann + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsEqual extends PHPUnit_Framework_Constraint +{ + /** + * @var mixed + */ + protected $value; + + /** + * @var float + */ + protected $delta = 0; + + /** + * @var integer + */ + protected $maxDepth = 10; + + /** + * @var boolean + */ + protected $canonicalizeEol = FALSE; + + /** + * @var boolean + */ + protected $ignoreCase = FALSE; + + /** + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalizeEol + * @param boolean $ignoreCase + */ + public function __construct($value, $delta = 0, $maxDepth = 10, $canonicalizeEol = FALSE, $ignoreCase = FALSE) + { + if (!is_numeric($delta)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'numeric'); + } + + if (!is_int($maxDepth)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'integer'); + } + + if (!is_bool($canonicalizeEol)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean'); + } + + if (!is_bool($ignoreCase)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'boolean'); + } + + $this->value = $value; + $this->delta = $delta; + $this->maxDepth = $maxDepth; + $this->canonicalizeEol = $canonicalizeEol; + $this->ignoreCase = $ignoreCase; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $this->recursiveComparison($this->value, $other); + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + $failureDescription = $this->failureDescription( + $other, + $description, + $not + ); + + if (!$not) { + if ($this->value instanceof DOMDocument) { + $value = $this->domToText($this->value); + } else { + $value = $this->value; + } + + if ($other instanceof DOMDocument) { + $other = $this->domToText($other); + } + + throw new PHPUnit_Framework_ExpectationFailedException( + $failureDescription, + PHPUnit_Framework_ComparisonFailure::diffEqual($value, $other), + $description + ); + } else { + throw new PHPUnit_Framework_ExpectationFailedException( + $failureDescription, + NULL + ); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $delta = ''; + + if (is_string($this->value)) { + if (strpos($this->value, "\n") !== FALSE) { + return 'is equal to '; + } else { + return sprintf( + 'is equal to ', + + $this->value + ); + } + } else { + if ($this->delta != 0) { + $delta = sprintf( + ' with delta <%F>', + + $this->delta + ); + } + + return sprintf( + 'is equal to %s%s', + + PHPUnit_Util_Type::toString($this->value), + $delta + ); + } + } + + /** + * Perform the actual recursive comparision of two values + * + * @param mixed $a First value + * @param mixed $b Second value + * @param int $depth Depth + * @return bool + */ + protected function recursiveComparison($a, $b, $depth = 0) + { + if ($a === $b) { + return TRUE; + } + + if ($depth >= $this->maxDepth) { + return TRUE; + } + + if (is_numeric($a) XOR is_numeric($b)) { + return FALSE; + } + + if (is_array($a) XOR is_array($b)) { + return FALSE; + } + + if (is_object($a) XOR is_object($b)) { + return FALSE; + } + + if ($a instanceof SplObjectStorage XOR $b instanceof SplObjectStorage) { + return FALSE; + } + + if ($a instanceof SplObjectStorage) { + foreach ($a as $object) { + if (!$b->contains($object)) { + return FALSE; + } + } + + foreach ($b as $object) { + if (!$a->contains($object)) { + return FALSE; + } + } + + return TRUE; + } + + if ($a instanceof DOMDocument || $b instanceof DOMDocument) { + if (!$a instanceof DOMDocument) { + $_a = new DOMDocument; + $_a->preserveWhiteSpace = FALSE; + $_a->loadXML($a); + $a = $_a; + unset($_a); + } + + if (!$b instanceof DOMDocument) { + $_b = new DOMDocument; + $_b->preserveWhiteSpace = FALSE; + $_b->loadXML($b); + $b = $_b; + unset($_b); + } + + if (version_compare(PHP_VERSION, '5.2.0RC1', '>=')) { + return ($a->C14N() == $b->C14N()); + } else { + return ($a->saveXML() == $b->saveXML()); + } + } + + if (is_object($a) && is_object($b) && + (get_class($a) !== get_class($b))) { + return FALSE; + } + + // Normal comparision for scalar values. + if ((!is_array($a) && !is_object($a)) || + (!is_array($b) && !is_object($b))) { + if (is_numeric($a) && is_numeric($b)) { + // Optionally apply delta on numeric values. + return $this->numericComparison($a, $b); + } + + if (is_string($a) && is_string($b)) { + if ($this->canonicalizeEol && PHP_EOL != "\n") { + $a = str_replace(PHP_EOL, "\n", $a); + $b = str_replace(PHP_EOL, "\n", $b); + } + + if ($this->ignoreCase) { + $a = strtolower($a); + $b = strtolower($b); + } + } + + return ($a == $b); + } + + if (is_object($a)) { + $isMock = $a instanceof PHPUnit_Framework_MockObject_MockObject; + $a = (array)$a; + $b = (array)$b; + + if ($isMock) { + unset($a["\0*\0invocationMocker"]); + + if (isset($b["\0*\0invocationMocker"])) { + unset($b["\0*\0invocationMocker"]); + } + } + } + + foreach ($a as $key => $v) { + if (!array_key_exists($key, $b)) { + // Abort on missing key in $b. + return FALSE; + } + + if (!$this->recursiveComparison($a[$key], $b[$key], $depth + 1)) { + // FALSE, if child comparision fails. + return FALSE; + } + + // Unset key to check whether all keys of b are compared. + unset($b[$key]); + } + + if (count($b)) { + // There is something in $b, that is missing in $a. + return FALSE; + } + + return TRUE; + } + + /** + * Compares two numeric values - use delta if applicable. + * + * @param mixed $a + * @param mixed $b + * @return bool + */ + protected function numericComparison($a, $b) + { + if ($this->delta === FALSE) { + return ($a == $b); + } else { + return (abs($a - $b) <= $this->delta); + } + } + + /** + * Returns the normalized, whitespace-cleaned, and indented textual + * representation of a DOMDocument. + * + * @param DOMDocument $document + * @return string + */ + protected function domToText(DOMDocument $document) + { + $document->formatOutput = TRUE; + $document->normalizeDocument(); + + return $document->saveXML(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsFalse.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsFalse.php new file mode 100644 index 00000000..23b3d5e8 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsFalse.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that accepts FALSE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Constraint_IsFalse extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $other === FALSE; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is false'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsIdentical.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsIdentical.php new file mode 100644 index 00000000..3388459d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsIdentical.php @@ -0,0 +1,147 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that one value is identical to another. + * + * Identical check is performed with PHP's === operator, the operator is + * explained in detail at + * {@url http://www.php.net/manual/en/types.comparisons.php}. + * Two values are identical if they have the same value and are of the same + * type. + * + * The expected value is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsIdentical extends PHPUnit_Framework_Constraint +{ + /** + * @var mixed + */ + protected $value; + + /** + * @param mixed $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $this->value === $other; + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + $failureDescription = $this->failureDescription( + $other, + $description, + $not + ); + + if (!$not) { + throw new PHPUnit_Framework_ExpectationFailedException( + $failureDescription, + PHPUnit_Framework_ComparisonFailure::diffIdentical( + $this->value, $other + ), + $description + ); + } else { + throw new PHPUnit_Framework_ExpectationFailedException( + $failureDescription, + NULL + ); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + if (is_object($this->value)) { + return 'is identical to an object of class "' . + get_class($this->value) . '"'; + } else { + return 'is identical to ' . + PHPUnit_Util_Type::toString($this->value); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsInstanceOf.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsInstanceOf.php new file mode 100644 index 00000000..2c4bcd19 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsInstanceOf.php @@ -0,0 +1,135 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the object it is evaluated for is an instance + * of a given class. + * + * The expected class name is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsInstanceOf extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $className; + + /** + * @param string $className + */ + public function __construct($className) + { + $this->className = $className; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return ($other instanceof $this->className); + } + + /** + * Creates the appropriate exception for the constraint which can be caught + * by the unit test system. This can be called if a call to evaluate() + * fails. + * + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + '%sFailed asserting that %s is %san instance of class "%s".', + + !empty($description) ? $description . "\n" : '', + PHPUnit_Util_Type::toString($other, TRUE), + $not ? 'not ' : '', + $this->className + ), + NULL + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'is instance of class "%s"', + + $this->className + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsNull.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsNull.php new file mode 100644 index 00000000..f9b0f77f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsNull.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that accepts NULL. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Constraint_IsNull extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $other === NULL; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is null'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsTrue.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsTrue.php new file mode 100644 index 00000000..9056f0d2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsTrue.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that accepts TRUE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Constraint_IsTrue extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $other === TRUE; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is true'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsType.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsType.php new file mode 100644 index 00000000..c0db34ca --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/IsType.php @@ -0,0 +1,189 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the value it is evaluated for is of a + * specified type. + * + * The expected value is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsType extends PHPUnit_Framework_Constraint +{ + const TYPE_ARRAY = 'array'; + const TYPE_BOOL = 'bool'; + const TYPE_FLOAT = 'float'; + const TYPE_INT = 'int'; + const TYPE_NULL = 'null'; + const TYPE_NUMERIC = 'numeric'; + const TYPE_OBJECT = 'object'; + const TYPE_RESOURCE = 'resource'; + const TYPE_STRING = 'string'; + const TYPE_SCALAR = 'scalar'; + + /** + * @var array + */ + protected $types = array( + 'array' => TRUE, + 'boolean' => TRUE, + 'bool' => TRUE, + 'float' => TRUE, + 'integer' => TRUE, + 'int' => TRUE, + 'null' => TRUE, + 'numeric' => TRUE, + 'object' => TRUE, + 'resource' => TRUE, + 'string' => TRUE, + 'scalar' => TRUE + ); + + /** + * @var string + */ + protected $type; + + /** + * @param string $type + * @throws InvalidArgumentException + */ + public function __construct($type) + { + if (!isset($this->types[$type])) { + throw new InvalidArgumentException( + sprintf( + 'Type specified for PHPUnit_Framework_Constraint_IsType <%s> ' . + 'is not a valid type.', + $type + ) + ); + } + + $this->type = $type; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + switch ($this->type) { + case 'numeric': { + return is_numeric($other); + } + + case 'integer': + case 'int': { + return is_integer($other); + } + + case 'float': { + return is_float($other); + } + + case 'string': { + return is_string($other); + } + + case 'boolean': + case 'bool': { + return is_bool($other); + } + + case 'null': { + return is_null($other); + } + + case 'array': { + return is_array($other); + } + + case 'object': { + return is_object($other); + } + + case 'resource': { + return is_resource($other); + } + + case 'scalar': { + return is_scalar($other); + } + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'is of type "%s"', + + $this->type + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/LessThan.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/LessThan.php new file mode 100644 index 00000000..646f9186 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/LessThan.php @@ -0,0 +1,102 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the value it is evaluated for is less than + * a given value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_LessThan extends PHPUnit_Framework_Constraint +{ + /** + * @var numeric + */ + protected $value; + + /** + * @param numeric $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return $this->value > $other; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is less than ' . PHPUnit_Util_Type::toString($this->value); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Not.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Not.php new file mode 100644 index 00000000..622e19a4 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Not.php @@ -0,0 +1,147 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Logical NOT. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ + +class PHPUnit_Framework_Constraint_Not extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @param PHPUnit_Framework_Constraint $constraint + */ + public function __construct($constraint) + { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + $constraint = new PHPUnit_Framework_Constraint_IsEqual($constraint); + } + + $this->constraint = $constraint; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return !$this->constraint->evaluate($other); + } + + /** + * @param mixed $other The value passed to evaluate() which failed the + * constraint check. + * @param string $description A string with extra description of what was + * going on while the evaluation failed. + * @param boolean $not Flag to indicate negation. + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function fail($other, $description, $not = FALSE) + { + if (count($this->constraint) == 1 || + $this->constraint instanceof PHPUnit_Framework_Constraint_Attribute) { + $this->constraint->fail($other, $description, TRUE); + } else { + parent::fail($other, $description, !$not); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + switch (get_class($this->constraint)) { + case 'PHPUnit_Framework_Constraint_And': + case 'PHPUnit_Framework_Constraint_Not': + case 'PHPUnit_Framework_Constraint_Or': { + return 'not( ' . $this->constraint->toString() . ' )'; + } + break; + + default: { + return PHPUnit_Framework_Constraint::negate( + $this->constraint->toString() + ); + } + } + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + return count($this->constraint) + 1; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ObjectHasAttribute.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ObjectHasAttribute.php new file mode 100644 index 00000000..5795a2a0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/ObjectHasAttribute.php @@ -0,0 +1,91 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the object it is evaluated for has a given + * attribute. + * + * The attribute name is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_ObjectHasAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute +{ + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + $object = new ReflectionObject($other); + + return $object->hasProperty($this->attributeName); + } + + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that object of class "%s" %s.', + get_class($other), $this->toString() + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Or.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Or.php new file mode 100644 index 00000000..3c4de795 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Or.php @@ -0,0 +1,144 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Logical OR. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_Or extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint[] + */ + protected $constraints = array(); + + /** + * @param PHPUnit_Framework_Constraint[] $constraints + */ + public function setConstraints(array $constraints) + { + $this->constraints = array(); + + foreach($constraints as $key => $constraint) { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $constraint + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + foreach($this->constraints as $constraint) { + if ($constraint->evaluate($other)) { + return TRUE; + } + } + + return FALSE; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $text = ''; + + foreach($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' or '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + $count = 1; + + foreach ($this->constraints as $constraint) { + $count += count($constraint); + } + + return $count; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/PCREMatch.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/PCREMatch.php new file mode 100644 index 00000000..3e69fc8f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/PCREMatch.php @@ -0,0 +1,111 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the string it is evaluated for matches + * a regular expression. + * + * Checks a given value using the Perl Compatible Regular Expression extension + * in PHP. The pattern is matched by executing preg_match(). + * + * The pattern string passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_PCREMatch extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $pattern; + + /** + * @param string $pattern + */ + public function __construct($pattern) + { + $this->pattern = $pattern; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return preg_match($this->pattern, $other) > 0; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'matches PCRE pattern "%s"', + + $this->pattern + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringContains.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringContains.php new file mode 100644 index 00000000..01398957 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringContains.php @@ -0,0 +1,127 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the string it is evaluated for contains + * a given string. + * + * Uses strpos() to find the position of the string in the input, if not found + * the evaluaton fails. + * + * The sub-string is passed in the constructor. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_StringContains extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $string; + + /** + * @var boolean + */ + protected $ignoreCase; + + /** + * @param string $string + * @param boolean $ignoreCase + */ + public function __construct($string, $ignoreCase = FALSE) + { + $this->string = $string; + $this->ignoreCase = $ignoreCase; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + if ($this->ignoreCase) { + return stripos($other, $this->string) !== FALSE; + } else { + return strpos($other, $this->string) !== FALSE; + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + if ($this->ignoreCase) { + $string = strtolower($this->string); + } else { + $string = $this->string; + } + + return sprintf( + 'contains "%s"', + + $string + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringEndsWith.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringEndsWith.php new file mode 100644 index 00000000..e197dbe0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringEndsWith.php @@ -0,0 +1,101 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the string it is evaluated for ends with a given + * suffix. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_Constraint_StringEndsWith extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $suffix; + + /** + * @param string $suffix + */ + public function __construct($suffix) + { + $this->suffix = $suffix; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return substr($other, 0 - strlen($this->suffix)) == $this->suffix; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'ends with "' . $this->suffix . '"'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringStartsWith.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringStartsWith.php new file mode 100644 index 00000000..d5a1e2e7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/StringStartsWith.php @@ -0,0 +1,101 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the string it is evaluated for begins with a + * given prefix. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_Constraint_StringStartsWith extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $prefix; + + /** + * @param string $prefix + */ + public function __construct($prefix) + { + $this->prefix = $prefix; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + return strpos($other, $this->prefix) === 0; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'starts with "' . $this->prefix . '"'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/TraversableContains.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/TraversableContains.php new file mode 100644 index 00000000..55b361bd --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/TraversableContains.php @@ -0,0 +1,134 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the Traversable it is applied to contains + * a given value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_TraversableContains extends PHPUnit_Framework_Constraint +{ + /** + * @var mixed + */ + protected $value; + + /** + * @param mixed $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + if ($other instanceof SplObjectStorage) { + return $other->contains($this->value); + } + + if (is_object($this->value)) { + foreach ($other as $element) { + if ($element === $this->value) { + return TRUE; + } + } + } else { + foreach ($other as $element) { + if ($element == $this->value) { + return TRUE; + } + } + } + + return FALSE; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + if (is_string($this->value) && strpos($this->value, "\n") !== FALSE) { + return 'contains "' . $this->value . '"'; + } else { + return 'contains ' . PHPUnit_Util_Type::toString($this->value); + } + } + + protected function customFailureDescription($other, $description, $not) + { + return sprintf( + 'Failed asserting that an %s %s.', + + is_array($other) ? 'array' : 'iterator', + $this->toString() + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/TraversableContainsOnly.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/TraversableContainsOnly.php new file mode 100644 index 00000000..1df9962c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/TraversableContainsOnly.php @@ -0,0 +1,122 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.4 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Constraint that asserts that the Traversable it is applied to contains + * only values of a given type. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Framework_Constraint_TraversableContainsOnly extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @var string + */ + protected $type; + + /** + * @param string $type + * @param boolean $isNativeType + */ + public function __construct($type, $isNativeType = TRUE) + { + if ($isNativeType) { + $this->constraint = new PHPUnit_Framework_Constraint_IsType($type); + } else { + $this->constraint = new PHPUnit_Framework_Constraint_IsInstanceOf( + $type + ); + } + + $this->type = $type; + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + foreach ($other as $item) { + if (!$this->constraint->evaluate($item)) { + return FALSE; + } + } + + return TRUE; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'contains only values of type "' . $this->type . '"'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Xor.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Xor.php new file mode 100644 index 00000000..0e6f8957 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Constraint/Xor.php @@ -0,0 +1,151 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Type.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Logical XOR. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_Xor extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint[] + */ + protected $constraints = array(); + + /** + * @param PHPUnit_Framework_Constraint[] $constraints + */ + public function setConstraints(array $constraints) + { + $this->constraints = array(); + + foreach($constraints as $key => $constraint) { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $constraint + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other. Returns TRUE if the + * constraint is met, FALSE otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + public function evaluate($other) + { + $result = FALSE; + + foreach($this->constraints as $constraint) { + if ($constraint->evaluate($other)) { + if ( $result ) + { + return FALSE; + } + + $result = TRUE; + } + } + + return $result; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $text = ''; + + foreach($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' xor '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + $count = 1; + + foreach ($this->constraints as $constraint) { + $count += count($constraint); + } + + return $count; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error.php new file mode 100644 index 00000000..5002f47a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error.php @@ -0,0 +1,82 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.2.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Wrapper for PHP errors. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.2.0 + */ +class PHPUnit_Framework_Error extends Exception +{ + /** + * Constructor. + * + * @param string $message + * @param integer $code + * @param string $file + * @param integer $line + * @param array $trace + */ + public function __construct($message, $code, $file, $line, $trace) + { + parent::__construct($message, $code); + + $this->file = $file; + $this->line = $line; + $this->trace = $trace; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error/Notice.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error/Notice.php new file mode 100644 index 00000000..02344e57 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error/Notice.php @@ -0,0 +1,71 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Wrapper for PHP notices. + * You can disable notice-to-exception conversion by setting + * + * + * PHPUnit_Framework_Error_Notice::$enabled = FALSE; + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error +{ + public static $enabled = TRUE; +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error/Warning.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error/Warning.php new file mode 100644 index 00000000..a5f9122e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Error/Warning.php @@ -0,0 +1,71 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Wrapper for PHP warnings. + * You can disable notice-to-exception conversion by setting + * + * + * PHPUnit_Framework_Error_Warning::$enabled = FALSE; + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Error_Warning extends PHPUnit_Framework_Error +{ + public static $enabled = TRUE; +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Exception.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Exception.php new file mode 100644 index 00000000..a120d24d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Exception.php @@ -0,0 +1,69 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +if (!class_exists('PHPUnit_Framework_Exception', FALSE)) { + +/** + * Exception for PHPUnit runtime errors. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_Exception extends RuntimeException +{ +} + +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ExpectationFailedException.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ExpectationFailedException.php new file mode 100644 index 00000000..62f48061 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/ExpectationFailedException.php @@ -0,0 +1,129 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Exception for expectations which failed their check. + * + * The exception contains the error message and optionally a + * PHPUnit_Framework_ComparisonFailure which is used to + * generate diff output of the failed expectations. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ExpectationFailedException extends PHPUnit_Framework_AssertionFailedError +{ + /** + * @var PHPUnit_Framework_ComparisonFailure + */ + protected $comparisonFailure; + + /** + * @var string + */ + protected $description; + + /** + * @var string + */ + protected $customMessage; + + public function __construct($description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL, $message = '') + { + $this->description = $description; + $this->comparisonFailure = $comparisonFailure; + $this->customMessage = $message; + + if (!empty($message)) { + $description .= "\n" . $message; + } + + parent::__construct($description); + } + + /** + * @return PHPUnit_Framework_ComparisonFailure + */ + public function getComparisonFailure() + { + return $this->comparisonFailure; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @return string + */ + public function getCustomMessage() + { + return $this->customMessage; + } + + /** + * @param string $customMessage + * @since Method available since Release 3.4.0 + */ + public function setCustomMessage($customMessage) + { + $this->customMessage = $customMessage; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/IncompleteTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/IncompleteTest.php new file mode 100644 index 00000000..fd870ce1 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/IncompleteTest.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A marker interface for marking any exception/error as result of an unit + * test as incomplete implementation or currently not implemented. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Framework_IncompleteTest +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/IncompleteTestError.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/IncompleteTestError.php new file mode 100644 index 00000000..3c71594f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/IncompleteTestError.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of an incomplete test. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_IncompleteTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_IncompleteTest +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Identity.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Identity.php new file mode 100644 index 00000000..71badf32 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Identity.php @@ -0,0 +1,77 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Builder interface for unique identifiers. + * + * Defines the interface for recording unique identifiers. The identifiers + * can be used to define the invocation order of expectations. The expectation + * is recorded using id() and then defined in order using + * PHPUnit_Framework_MockObject_Builder_Match::after(). + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Identity +{ + /** + * Sets the identification of the expectation to $id. + * + * @note The identifier is unique per mock object. + * @param string $id Unique identifiation of expectation. + */ + public function id($id); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php new file mode 100644 index 00000000..00172e3c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php @@ -0,0 +1,203 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Builder for mocked or stubbed invocations. + * + * Provides methods for building expectations without having to resort to + * instantiating the various matchers manually. These methods also form a + * more natural way of reading the expectation. This class should be together + * with the test case PHPUnit_Framework_MockObject_TestCase. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Builder_InvocationMocker implements PHPUnit_Framework_MockObject_Builder_MethodNameMatch +{ + /** + * @var PHPUnit_Framework_MockObject_Stub_MatcherCollection + */ + protected $collection; + + /** + * @var PHPUnit_Framework_MockObject_Matcher + */ + protected $matcher; + + /** + * @param PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher + */ + public function __construct(PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection, PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher) + { + $this->collection = $collection; + $this->matcher = new PHPUnit_Framework_MockObject_Matcher( + $invocationMatcher + ); + + $this->collection->addMatcher($this->matcher); + } + + /** + * @return PHPUnit_Framework_MockObject_Matcher + */ + public function getMatcher() + { + return $this->matcher; + } + + /** + * @param mixed $id + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function id($id) + { + $this->collection->registerId($id, $this); + + return $this; + } + + /** + * @param PHPUnit_Framework_MockObject_Stub $stub + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function will(PHPUnit_Framework_MockObject_Stub $stub) + { + $this->matcher->stub = $stub; + + return $this; + } + + /** + * @param mixed $id + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function after($id) + { + $this->matcher->afterMatchBuilderId = $id; + + return $this; + } + + /** + * @param mixed $argument, ... + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function with() + { + $args = func_get_args(); + + if ($this->matcher->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'Method name matcher is not defined, cannot define parameter ' . + ' matcher without one' + ); + } + + if ($this->matcher->parametersMatcher !== NULL) { + throw new PHPUnit_Framework_Exception( + 'Parameter matcher is already defined, cannot redefine' + ); + } + + $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($args); + + return $this; + } + + /** + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function withAnyParameters() + { + if ($this->matcher->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'Method name matcher is not defined, cannot define parameter ' . + 'matcher without one' + ); + } + + if ($this->matcher->parametersMatcher !== NULL) { + throw new PHPUnit_Framework_Exception( + 'Parameter matcher is already defined, cannot redefine' + ); + } + + $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters; + + return $this; + } + + /** + * @param PHPUnit_Framework_Constraint|string $constraint + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function method($constraint) + { + if ($this->matcher->methodNameMatcher !== NULL) { + throw new PHPUnit_Framework_Exception( + 'Method name matcher is already defined, cannot redefine' + ); + } + + $this->matcher->methodNameMatcher = new PHPUnit_Framework_MockObject_Matcher_MethodName($constraint); + + return $this; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Match.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Match.php new file mode 100644 index 00000000..1565668f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Match.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/Stub.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Builder interface for invocation order matches. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Match extends PHPUnit_Framework_MockObject_Builder_Stub +{ + /** + * Defines the expectation which must occur before the current is valid. + * + * @param string $id The identification of the expectation that should + * occur before this one. + * @return PHPUnit_Framework_MockObject_Builder_Stub + */ + public function after($id); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php new file mode 100644 index 00000000..274667aa --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php @@ -0,0 +1,76 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/ParametersMatch.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Builder interface for matcher of method names. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_MethodNameMatch extends PHPUnit_Framework_MockObject_Builder_ParametersMatch +{ + /** + * Adds a new method name match and returns the parameter match object for + * further matching possibilities. + * + * @param PHPUnit_Framework_Constraint $name + * Constraint for matching method, if a string is passed it will use + * the PHPUnit_Framework_Constraint_IsEqual. + * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch + */ + public function method($name); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Namespace.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Namespace.php new file mode 100644 index 00000000..1c416ab9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Namespace.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/Match.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Interface for builders which can register builders with a given identification. + * + * This interface relates to PHPUnit_Framework_MockObject_Builder_Identity. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Namespace +{ + /** + * Looks up the match builder with identification $id and returns it. + * + * @param string $id The identifiction of the match builder. + * @return PHPUnit_Framework_MockObject_Builder_Match + */ + public function lookupId($id); + + /** + * Registers the match builder $builder with the identification $id. The + * builder can later be looked up using lookupId() to figure out if it + * has been invoked. + * + * @param string $id + * The identification of the match builder. + * @param PHPUnit_Framework_MockObject_Builder_Match $builder + * The builder which is being registered. + */ + public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/ParametersMatch.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/ParametersMatch.php new file mode 100644 index 00000000..faf8c62b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/ParametersMatch.php @@ -0,0 +1,97 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/Match.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Builder interface for parameter matchers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_ParametersMatch extends PHPUnit_Framework_MockObject_Builder_Match +{ + /** + * Sets the parameters to match for, each parameter to this funtion will + * be part of match. To perform specific matches or constraints create a + * new PHPUnit_Framework_Constraint and use it for the parameter. + * If the parameter value is not a constraint it will use the + * PHPUnit_Framework_Constraint_IsEqual for the value. + * + * Some examples: + * + * // match first parameter with value 2 + * $b->with(2); + * // match first parameter with value 'smock' and second identical to 42 + * $b->with('smock', new PHPUnit_Framework_Constraint_IsEqual(42)); + * + * + * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch + */ + public function with(); + + /** + * Sets a matcher which allows any kind of parameters. + * + * Some examples: + * + * // match any number of parameters + * $b->withAnyParamers(); + * + * + * @return PHPUnit_Framework_MockObject_Matcher_AnyParameters + */ + public function withAnyParameters(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Stub.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Stub.php new file mode 100644 index 00000000..707847b0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Builder/Stub.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/Identity.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Builder interface for stubs which are actions replacing an invocation. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Stub extends PHPUnit_Framework_MockObject_Builder_Identity +{ + /** + * Stubs the matching method with the stub object $stub. Any invocations of + * the matched method will now be handled by the stub instead. + * + * @param PHPUnit_Framework_MockObject_Stub $stub The stub object. + * @return PHPUnit_Framework_MockObject_Builder_Identity + */ + public function will(PHPUnit_Framework_MockObject_Stub $stub); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator.php new file mode 100644 index 00000000..ac080ea5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator.php @@ -0,0 +1,530 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Framework/MockObject/Matcher.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/MockObject.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Template.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Mock Object Code Generator + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_MockObject_Generator +{ + /** + * @var array + */ + protected static $cache = array(); + + /** + * @var array + */ + protected static $blacklistedMethodNames = array( + '__clone' => TRUE, + 'abstract' => TRUE, + 'and' => TRUE, + 'array' => TRUE, + 'as' => TRUE, + 'break' => TRUE, + 'case' => TRUE, + 'catch' => TRUE, + 'class' => TRUE, + 'clone' => TRUE, + 'const' => TRUE, + 'continue' => TRUE, + 'declare' => TRUE, + 'default' => TRUE, + 'do' => TRUE, + 'else' => TRUE, + 'elseif' => TRUE, + 'enddeclare' => TRUE, + 'endfor' => TRUE, + 'endforeach' => TRUE, + 'endif' => TRUE, + 'endswitch' => TRUE, + 'endwhile' => TRUE, + 'extends' => TRUE, + 'final' => TRUE, + 'for' => TRUE, + 'foreach' => TRUE, + 'function' => TRUE, + 'global' => TRUE, + 'goto' => TRUE, + 'if' => TRUE, + 'implements' => TRUE, + 'interface' => TRUE, + 'instanceof' => TRUE, + 'namespace' => TRUE, + 'new' => TRUE, + 'or' => TRUE, + 'private' => TRUE, + 'protected' => TRUE, + 'public' => TRUE, + 'static' => TRUE, + 'switch' => TRUE, + 'throw' => TRUE, + 'try' => TRUE, + 'use' => TRUE, + 'var' => TRUE, + 'while' => TRUE, + 'xor' => TRUE + ); + + /** + * @var boolean + */ + protected static $soapLoaded = NULL; + + /** + * @param string $originalClassName + * @param array $methods + * @param string $mockClassName + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @return array + */ + public static function generate($originalClassName, array $methods = NULL, $mockClassName = '', $callOriginalClone = TRUE, $callAutoload = TRUE) + { + if ($mockClassName == '') { + $key = md5( + $originalClassName . + serialize($methods) . + serialize($callOriginalClone) + ); + + if (isset(self::$cache[$key])) { + return self::$cache[$key]; + } + } + + $mock = self::generateMock( + $originalClassName, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload + ); + + if (isset($key)) { + self::$cache[$key] = $mock; + } + + return $mock; + } + + /** + * @param string $wsdlFile + * @param string $originalClassName + * @param array $methods + * @return array + */ + public static function generateClassFromWsdl($wsdlFile, $originalClassName, array $methods = array()) + { + if (self::$soapLoaded === NULL) { + self::$soapLoaded = extension_loaded('soap'); + } + + if (self::$soapLoaded) { + $client = new SOAPClient($wsdlFile); + $_methods = $client->__getFunctions(); + unset($client); + + $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . + 'Generator' . DIRECTORY_SEPARATOR; + $methodTemplate = new PHPUnit_Util_Template( + $templateDir . 'wsdl_method.tpl' + ); + $methodsBuffer = ''; + + foreach ($_methods as $method) { + $nameStart = strpos($method, ' ') + 1; + $nameEnd = strpos($method, '('); + $name = substr($method, $nameStart, $nameEnd - $nameStart); + + if (empty($methods) || in_array($name, $methods)) { + $args = explode( + ',', + substr( + $method, + $nameEnd + 1, + strpos($method, ')') - $nameEnd - 1 + ) + ); + $numArgs = count($args); + + for ($i = 0; $i < $numArgs; $i++) { + $args[$i] = substr($args[$i], strpos($args[$i], '$')); + } + + $methodTemplate->setVar( + array( + 'method_name' => $name, + 'arguments' => join(', ', $args) + ) + ); + + $methodsBuffer .= $methodTemplate->render(); + } + } + + $classTemplate = new PHPUnit_Util_Template( + $templateDir . 'wsdl_class.tpl' + ); + + $classTemplate->setVar( + array( + 'class_name' => $originalClassName, + 'wsdl' => $wsdlFile, + 'methods' => $methodsBuffer + ) + ); + + return $classTemplate->render(); + } else { + throw new PHPUnit_Framework_Exception( + 'The SOAP extension is required to generate a mock object ' . + 'from WSDL.' + ); + } + } + + /** + * @param string $originalClassName + * @param array $methods + * @param string $mockClassName + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @return array + */ + protected static function generateMock($originalClassName, array $methods = NULL, $mockClassName, $callOriginalClone, $callAutoload) + { + $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . + DIRECTORY_SEPARATOR; + $classTemplate = new PHPUnit_Util_Template( + $templateDir . 'mocked_class.tpl' + ); + $cloneTemplate = ''; + $isClass = FALSE; + $isInterface = FALSE; + + $mockClassName = self::generateMockClassName( + $originalClassName, $mockClassName + ); + + if (class_exists($mockClassName['fullClassName'], $callAutoload)) { + $isClass = TRUE; + } else { + if (interface_exists($mockClassName['fullClassName'], $callAutoload)) { + $isInterface = TRUE; + } + } + + if (!class_exists($mockClassName['fullClassName'], $callAutoload) && + !interface_exists($mockClassName['fullClassName'], $callAutoload)) { + $prologue = 'class ' . $mockClassName['className'] . "\n{\n}\n\n"; + + if (!empty($mockClassName['namespaceName'])) { + $prologue = 'namespace ' . $mockClassName['namespaceName'] . + ";\n\n" . $prologue; + } + + $cloneTemplate = new PHPUnit_Util_Template( + $templateDir . 'mocked_clone.tpl' + ); + } else { + $class = new ReflectionClass($mockClassName['fullClassName']); + + if ($class->isFinal()) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Class "%s" is declared "final" and cannot be mocked.', + $mockClassName['fullClassName'] + ) + ); + } + + if ($class->hasMethod('__clone')) { + $cloneMethod = $class->getMethod('__clone'); + + if (!$cloneMethod->isFinal()) { + if ($callOriginalClone) { + $cloneTemplate = new PHPUnit_Util_Template( + $templateDir . 'unmocked_clone.tpl' + ); + } else { + $cloneTemplate = new PHPUnit_Util_Template( + $templateDir . 'mocked_clone.tpl' + ); + } + } + } else { + $cloneTemplate = new PHPUnit_Util_Template( + $templateDir . 'mocked_clone.tpl' + ); + } + } + + if (is_object($cloneTemplate)) { + $cloneTemplate = $cloneTemplate->render(); + } + + if (is_array($methods) && empty($methods) && + ($isClass || $isInterface)) { + $methods = get_class_methods($mockClassName['fullClassName']); + } + + if (!is_array($methods)) { + $methods = array(); + } + + $constructor = NULL; + $mockedMethods = ''; + + if (isset($class)) { + if ($class->hasMethod('__construct')) { + $constructor = $class->getMethod('__construct'); + } + + else if ($class->hasMethod($originalClassName)) { + $constructor = $class->getMethod($originalClassName); + } + + foreach ($methods as $methodName) { + try { + $method = $class->getMethod($methodName); + + if (self::canMockMethod($method)) { + $mockedMethods .= self::generateMockedMethodDefinitionFromExisting( + $templateDir, $method + ); + } + } + + catch (ReflectionException $e) { + $mockedMethods .= self::generateMockedMethodDefinition( + $templateDir, $mockClassName['fullClassName'], $methodName + ); + } + } + } else { + foreach ($methods as $methodName) { + $mockedMethods .= self::generateMockedMethodDefinition( + $templateDir, $mockClassName['fullClassName'], $methodName + ); + } + } + + $classTemplate->setVar( + array( + 'prologue' => isset($prologue) ? $prologue : '', + 'class_declaration' => self::generateMockClassDeclaration( + $mockClassName, $isInterface + ), + 'clone' => $cloneTemplate, + 'mocked_methods' => $mockedMethods + ) + ); + + return array( + 'code' => $classTemplate->render(), + 'mockClassName' => $mockClassName['mockClassName'] + ); + } + + /** + * @param string $originalClassName + * @param string $mockClassName + * @return array + */ + protected static function generateMockClassName($originalClassName, $mockClassName) + { + $classNameParts = explode('\\', $originalClassName); + + if (count($classNameParts) > 1) { + $originalClassName = array_pop($classNameParts); + $namespaceName = join('\\', $classNameParts); + $fullClassName = $namespaceName . '\\' . $originalClassName; + } else { + $namespaceName = ''; + $fullClassName = $originalClassName; + } + + if ($mockClassName == '') { + do { + $mockClassName = 'Mock_' . $originalClassName . '_' . + substr(md5(microtime()), 0, 8); + } + while (class_exists($mockClassName, FALSE)); + } + + return array( + 'mockClassName' => $mockClassName, + 'className' => $originalClassName, + 'fullClassName' => $fullClassName, + 'namespaceName' => $namespaceName + ); + } + + /** + * @param array $mockClassName + * @param boolean $isInterface + * @return array + */ + protected static function generateMockClassDeclaration(array $mockClassName, $isInterface) + { + $buffer = 'class '; + + if ($isInterface) { + $buffer .= sprintf( + "%s implements PHPUnit_Framework_MockObject_MockObject, %s%s", + $mockClassName['mockClassName'], + !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '', + $mockClassName['className'] + ); + } else { + $buffer .= sprintf( + "%s extends %s%s implements PHPUnit_Framework_MockObject_MockObject", + $mockClassName['mockClassName'], + !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '', + $mockClassName['className'] + ); + } + + return $buffer; + } + + /** + * @param string $templateDir + * @param ReflectionMethod $method + * @return string + */ + protected static function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method) + { + if ($method->isPrivate()) { + $modifier = 'private'; + } + + else if ($method->isProtected()) { + $modifier = 'protected'; + } + + else { + $modifier = 'public'; + } + + if ($method->returnsReference()) { + $reference = '&'; + } else { + $reference = ''; + } + + return self::generateMockedMethodDefinition( + $templateDir, + $method->getDeclaringClass()->getName(), + $method->getName(), + $modifier, + PHPUnit_Util_Class::getMethodParameters($method), + $reference + ); + } + + /** + * @param string $templateDir + * @param string $className + * @param string $methodName + * @param string $modifier + * @param string $arguments + * @param string $reference + * @return string + */ + protected static function generateMockedMethodDefinition($templateDir, $className, $methodName, $modifier = 'public', $arguments = '', $reference = '') + { + $template = new PHPUnit_Util_Template( + $templateDir . 'mocked_method.tpl' + ); + + $template->setVar( + array( + 'arguments' => $arguments, + 'class_name' => $className, + 'method_name' => $methodName, + 'modifier' => $modifier, + 'reference' => $reference + ) + ); + + return $template->render(); + } + + /** + * @param ReflectionMethod $method + * @return boolean + */ + protected static function canMockMethod(ReflectionMethod $method) + { + if ($method->isConstructor() || + $method->isFinal() || + $method->isStatic() || + isset(self::$blacklistedMethodNames[$method->getName()])) { + return FALSE; + } + + return TRUE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_class.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_class.tpl.dist new file mode 100644 index 00000000..82739ee0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_class.tpl.dist @@ -0,0 +1,29 @@ +{prologue}{class_declaration} +{ + protected $invocationMocker; + +{clone}{mocked_methods} + public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) + { + return $this->__phpunit_getInvocationMocker()->expects($matcher); + } + + public function __phpunit_getInvocationMocker() + { + if ($this->invocationMocker === NULL) { + $this->invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this); + } + + return $this->invocationMocker; + } + + public function __phpunit_verify() + { + $this->__phpunit_getInvocationMocker()->verify(); + } + + public function __phpunit_cleanup() + { + $this->invocationMocker = NULL; + } +} diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_clone.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_clone.tpl.dist new file mode 100644 index 00000000..9f561b07 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_clone.tpl.dist @@ -0,0 +1,4 @@ + public function __clone() + { + $this->invocationMocker = clone $this->__phpunit_getInvocationMocker(); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_method.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_method.tpl.dist new file mode 100644 index 00000000..4945c17d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/mocked_method.tpl.dist @@ -0,0 +1,13 @@ + + {modifier} function {reference}{method_name}({arguments}) + { + $args = func_get_args(); + + $result = $this->__phpunit_getInvocationMocker()->invoke( + new PHPUnit_Framework_MockObject_Invocation( + $this, '{class_name}', '{method_name}', $args + ) + ); + + return $result; + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/unmocked_clone.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/unmocked_clone.tpl.dist new file mode 100644 index 00000000..9d1146d6 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/unmocked_clone.tpl.dist @@ -0,0 +1,5 @@ + public function __clone() + { + $this->invocationMocker = clone $this->__phpunit_getInvocationMocker(); + parent::__clone(); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/wsdl_class.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/wsdl_class.tpl.dist new file mode 100644 index 00000000..0bd37f58 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/wsdl_class.tpl.dist @@ -0,0 +1,7 @@ +class {class_name} extends SOAPClient +{ + public function __construct($wsdl, array $options) + { + parent::__construct('{wsdl}'); + } +{methods}} diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/wsdl_method.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/wsdl_method.tpl.dist new file mode 100644 index 00000000..bb16e763 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Generator/wsdl_method.tpl.dist @@ -0,0 +1,4 @@ + + public function {method_name}({arguments}) + { + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Invocation.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Invocation.php new file mode 100644 index 00000000..466cf9d9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Invocation.php @@ -0,0 +1,159 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Jan Borsodi + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Encapsulates information on a method invocation which can be passed to matchers. + * + * The invocation consists of the object it occured from, the class name, the + * method name and all the parameters. The mock object must instantiate this + * class with the values from the mocked method and pass it to an object of + * PHPUnit_Framework_MockObject_Invokable. + * + * @category Testing + * @package PHPUnit + * @author Jan Borsodi + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Invocation implements PHPUnit_Framework_SelfDescribing +{ + /** + * @var object + */ + public $object; + + /** + * @var string + */ + public $className; + + /** + * @var string + */ + public $methodName; + + /** + * @var array + */ + public $parameters; + + /** + * @param string $className + * @param string $methodname + * @param array $parameters + * @param object $object + */ + public function __construct($object, $className, $methodName, array $parameters) + { + $this->object = $object; + $this->className = $className; + $this->methodName = $methodName; + $this->parameters = $parameters; + + foreach ($this->parameters as $key => $value) { + if (is_object($value)) { + $this->parameters[$key] = $this->cloneObject($value); + } + } + } + + /** + * @return string + */ + public function toString() + { + return sprintf( + "%s::%s(%s)", + + $this->className, + $this->methodName, + join( + ', ', + array_map( + array('PHPUnit_Util_Type', 'shortenedExport'), + $this->parameters + ) + ) + ); + } + + /** + * @param object $original + * @return object + */ + protected function cloneObject($original) + { + $object = new ReflectionObject($original); + + if ($object->hasMethod('__clone')) { + $method = $object->getMethod('__clone'); + + if (!$method->isPublic()) { + return $original; + } + + try { + return clone $original; + } + + catch (Exception $e) { + return $original; + } + } + + return clone $original; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/InvocationMocker.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/InvocationMocker.php new file mode 100644 index 00000000..f2168fd5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/InvocationMocker.php @@ -0,0 +1,197 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/InvocationMocker.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/Match.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/Namespace.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invokable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Mocker for invocations which are sent from + * PHPUnit_Framework_MockObject_MockObject objects. + * + * Keeps track of all expectations and stubs as well as registering + * identifications for builders. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_InvocationMocker implements PHPUnit_Framework_MockObject_Stub_MatcherCollection, PHPUnit_Framework_MockObject_Invokable, PHPUnit_Framework_MockObject_Builder_Namespace +{ + /** + * @var PHPUnit_Framework_MockObject_Matcher_Invocation[] + */ + protected $matchers = array(); + + /** + * @var PHPUnit_Framework_MockObject_Builder_Match[] + */ + protected $builderMap = array(); + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + */ + public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) + { + $this->matchers[] = $matcher; + } + + /** + * @param mixed $id + * @return boolean|null + */ + public function lookupId($id) + { + if (isset($this->builderMap[$id])) { + return $this->builderMap[$id]; + } + + return NULL; + } + + /** + * @param mixed $id + * @param PHPUnit_Framework_MockObject_Builder_Match $builder + * @throws PHPUnit_Framework_Exception + */ + public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder) + { + if (isset($this->builderMap[$id])) { + throw new PHPUnit_Framework_Exception( + 'Match builder with id <' . $id . '> is already registered.' + ); + } + + $this->builderMap[$id] = $builder; + } + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) + { + return new PHPUnit_Framework_MockObject_Builder_InvocationMocker( + $this, $matcher + ); + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return mixed + */ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $exception = NULL; + $hasReturnValue = FALSE; + + if (strtolower($invocation->methodName) == '__tostring') { + $returnValue = ''; + } else { + $returnValue = NULL; + } + + foreach ($this->matchers as $match) { + try { + if ($match->matches($invocation)) { + $value = $match->invoked($invocation); + + if (!$hasReturnValue) { + $returnValue = $value; + $hasReturnValue = TRUE; + } + } + } + + catch (Exception $e) { + $exception = $e; + } + } + + if ($exception !== NULL) { + throw $exception; + } + + return $returnValue; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + foreach($this->matchers as $matcher) { + if (!$matcher->matches($invocation)) { + return FALSE; + } + } + + return TRUE; + } + + /** + * @return boolean + */ + public function verify() + { + foreach($this->matchers as $matcher) { + $matcher->verify(); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Invokable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Invokable.php new file mode 100644 index 00000000..d4f1e281 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Invokable.php @@ -0,0 +1,88 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Verifiable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Interface for classes which can be invoked. + * + * The invocation will be taken from a mock object and passed to an object + * of this class. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Invokable extends PHPUnit_Framework_MockObject_Verifiable +{ + /** + * Invokes the invocation object $invocation so that it can be checked for + * expectations or matched against stubs. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * The invocation object passed from mock object. + * @return object + */ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation); + + /** + * Checks if the invocation matches. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * The invocation object passed from mock object. + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher.php new file mode 100644 index 00000000..f32b9b8d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher.php @@ -0,0 +1,323 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Main matcher which defines a full expectation using method, parameter and + * invocation matchers. + * This matcher encapsulates all the other matchers and allows the builder to + * set the specific matchers when the appropriate methods are called (once(), + * where() etc.). + * + * All properties are public so that they can easily be accessed by the builder. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * @var PHPUnit_Framework_MockObject_Matcher_Invocation + */ + public $invocationMatcher; + + /** + * @var mixed + */ + public $afterMatchBuilderId = NULL; + + /** + * @var boolean + */ + public $afterMatchBuilderIsInvoked = FALSE; + + /** + * @var PHPUnit_Framework_MockObject_Matcher_MethodName + */ + public $methodNameMatcher = NULL; + + /** + * @var PHPUnit_Framework_MockObject_Matcher_Parameters + */ + public $parametersMatcher = NULL; + + /** + * @var PHPUnit_Framework_MockObject_Stub + */ + public $stub = NULL; + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher + */ + public function __construct(PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher) + { + $this->invocationMatcher = $invocationMatcher; + } + + /** + * @return string + */ + public function toString() + { + $list = array(); + + if ($this->invocationMatcher !== NULL) { + $list[] = $this->invocationMatcher->toString(); + } + + if ($this->methodNameMatcher !== NULL) { + $list[] = 'where ' . $this->methodNameMatcher->toString(); + } + + if ($this->parametersMatcher !== NULL) { + $list[] = 'and ' . $this->parametersMatcher->toString(); + } + + if ($this->afterMatchBuilderId !== NULL) { + $list[] = 'after ' . $this->afterMatchBuilderId; + } + + if ($this->stub !== NULL) { + $list[] = 'will ' . $this->stub->toString(); + } + + return join(' ', $list); + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return mixed + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if ($this->invocationMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'No invocation matcher is set' + ); + } + + if ($this->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception('No method matcher is set'); + } + + if ($this->afterMatchBuilderId !== NULL) { + $builder = $invocation->object + ->__phpunit_getInvocationMocker() + ->lookupId($this->afterMatchBuilderId); + + if (!$builder) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'No builder found for match builder identification <%s>', + + $this->afterMatchBuilderId + ) + ); + } + + $matcher = $builder->getMatcher(); + + if ($matcher && $matcher->invocationMatcher->hasBeenInvoked()) { + $this->afterMatchBuilderIsInvoked = TRUE; + } + } + + $this->invocationMatcher->invoked($invocation); + + try { + if ( $this->parametersMatcher !== NULL && + !$this->parametersMatcher->matches($invocation)) { + $this->parametersMatcher->verify(); + } + } + + catch (PHPUnit_Framework_ExpectationFailedException $e) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + "Expectation failed for %s when %s\n%s", + + $this->methodNameMatcher->toString(), + $this->invocationMatcher->toString(), + $e->getDescription() + ), + $e->getComparisonFailure() + ); + } + + if ($this->stub) { + return $this->stub->invoke($invocation); + } + + return NULL; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if ($this->afterMatchBuilderId !== NULL) { + $builder = $invocation->object + ->__phpunit_getInvocationMocker() + ->lookupId($this->afterMatchBuilderId); + + if (!$builder) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'No builder found for match builder identification <%s>', + + $this->afterMatchBuilderId + ) + ); + } + + $matcher = $builder->getMatcher(); + + if (!$matcher) { + return FALSE; + } + + if (!$matcher->invocationMatcher->hasBeenInvoked()) { + return FALSE; + } + } + + if ($this->invocationMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'No invocation matcher is set' + ); + } + + if ($this->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception('No method matcher is set'); + } + + if (!$this->invocationMatcher->matches($invocation)) { + return FALSE; + } + + try { + if (!$this->methodNameMatcher->matches($invocation)) { + return FALSE; + } + } + + catch (PHPUnit_Framework_ExpectationFailedException $e) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + "Expectation failed for %s when %s\n%s", + + $this->methodNameMatcher->toString(), + $this->invocationMatcher->toString(), + $e->getDescription() + ), + $e->getComparisonFailure() + ); + } + + return TRUE; + } + + /** + * @throws PHPUnit_Framework_Exception + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + if ($this->invocationMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'No invocation matcher is set' + ); + } + + if ($this->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception('No method matcher is set'); + } + + try { + $this->invocationMatcher->verify(); + + if ($this->parametersMatcher !== NULL) { + $this->parametersMatcher->verify(); + } + } + + catch (PHPUnit_Framework_ExpectationFailedException $e) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + "Expectation failed for %s when %s.\n%s", + + $this->methodNameMatcher->toString(), + $this->invocationMatcher->toString(), + $e->getDescription() + ) + ); + } + } +} + +require_once 'PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/AnyParameters.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedCount.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/MethodName.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/Parameters.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php new file mode 100644 index 00000000..cc57f647 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php @@ -0,0 +1,81 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which checks if a method has been invoked zero or more + * times. This matcher will always match. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @return string + */ + public function toString() + { + return 'invoked zero or more times'; + } + + /** + */ + public function verify() + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php new file mode 100644 index 00000000..17e1e156 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php @@ -0,0 +1,83 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which allos any parameters to a method. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_AnyParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + /** + * @return string + */ + public function toString() + { + return 'with any parameters'; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return TRUE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/Invocation.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/Invocation.php new file mode 100644 index 00000000..d0e0f655 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/Invocation.php @@ -0,0 +1,98 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Verifiable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Interface for classes which matches an invocation based on its + * method name, argument, order or call count. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Matcher_Invocation extends PHPUnit_Framework_SelfDescribing, PHPUnit_Framework_MockObject_Verifiable +{ + /** + * Registers the invocation $invocation in the object as being invoked. + * This will only occur after matches() returns true which means the + * current invocation is the correct one. + * + * The matcher can store information from the invocation which can later + * be checked in verify(), or it can check the values directly and throw + * and exception if an expectation is not met. + * + * If the matcher is a stub it will also have a return value. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return mixed + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation); + + /** + * Checks if the invocation $invocation matches the current rules. If it does + * the matcher will get the invoked() method called which should check if an + * expectation is met. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return bool + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php new file mode 100644 index 00000000..8b98fbcc --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php @@ -0,0 +1,137 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which checks if a method was invoked at a certain index. + * + * If the expected index number does not match the current invocation index it + * will not match which means it skips all method and parameter matching. Only + * once the index is reached will the method and parameter start matching and + * verifying. + * + * If the index is never reached it will throw an exception in index. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * @var integer + */ + protected $sequenceIndex; + + /** + * @var integer + */ + protected $currentIndex = -1; + + /** + * @param integer $sequenceIndex + */ + public function __construct($sequenceIndex) + { + $this->sequenceIndex = $sequenceIndex; + } + + /** + * @return string + */ + public function toString() + { + return 'invoked at sequence index ' . $this->sequenceIndex; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->currentIndex++; + + return $this->currentIndex == $this->sequenceIndex; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + if ($this->currentIndex < $this->sequenceIndex) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + 'The expected invocation at index %s was never reached.', + + $this->sequenceIndex + ) + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php new file mode 100644 index 00000000..aa515295 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php @@ -0,0 +1,94 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which checks if a method has been invoked at least one + * time. + * + * If the number of invocations is 0 it will throw an exception in verify. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @return string + */ + public function toString() + { + return 'invoked at least once'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + $count = $this->getInvocationCount(); + + if ($count < 1) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Expected invocation at least once but it never occured.' + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedCount.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedCount.php new file mode 100644 index 00000000..e3fff667 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedCount.php @@ -0,0 +1,153 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which checks if a method has been invoked a certain amount + * of times. + * If the number of invocations exceeds the value it will immediately throw an + * exception, + * If the number is less it will later be checked in verify() and also throw an + * exception. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @var integer + */ + protected $expectedCount; + + /** + * @param interger $expectedCount + */ + public function __construct($expectedCount) + { + $this->expectedCount = $expectedCount; + } + + /** + * @return string + */ + public function toString() + { + return 'invoked ' . $this->expectedCount . ' time(s)'; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + parent::invoked($invocation); + + $count = $this->getInvocationCount(); + + if ($count > $this->expectedCount) { + $message = $invocation->toString() . ' '; + + switch ($this->expectedCount) { + case 0: { + $message .= 'was not expected to be called.'; + } + break; + + case 1: { + $message .= 'was not expected to be called more than once.'; + } + break; + + default: { + $message .= sprintf( + 'was not expected to be called more than %d times.', + + $this->expectedCount + ); + } + } + + throw new PHPUnit_Framework_ExpectationFailedException($message); + } + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + $count = $this->getInvocationCount(); + + if ($count !== $this->expectedCount) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + 'Method was expected to be called %d times, ' . + 'actually called %d times.', + + $this->expectedCount, + $count + ) + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php new file mode 100644 index 00000000..135dcedf --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php @@ -0,0 +1,116 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Records invocations and provides convenience methods for checking them later + * on. + * This abstract class can be implemented by matchers which needs to check the + * number of times an invocation has occured. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + * @abstract + */ +abstract class PHPUnit_Framework_MockObject_Matcher_InvokedRecorder implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * @var PHPUnit_Framework_MockObject_Invocation[] + */ + protected $invocations = array(); + + /** + * @return integer + */ + public function getInvocationCount() + { + return count($this->invocations); + } + + /** + * @return PHPUnit_Framework_MockObject_Invocation[] + */ + public function getInvocations() + { + return $this->invocations; + } + + /** + * @return boolean + */ + public function hasBeenInvoked() + { + return count($this->invocations) > 0; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->invocations[] = $invocation; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return TRUE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/MethodName.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/MethodName.php new file mode 100644 index 00000000..bc7f2032 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/MethodName.php @@ -0,0 +1,113 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which looks for a specific method name in the invocations. + * + * Checks the method name all incoming invocations, the name is checked against + * the defined constraint $constraint. If the constraint is met it will return + * true in matches(). + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_MethodName extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @param PHPUnit_Framework_Constraint|string + * @throws PHPUnit_Framework_Constraint + */ + public function __construct($constraint) + { + if (!$constraint instanceof PHPUnit_Framework_Constraint) { + if (!is_string($constraint)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $constraint, 0, 10, FALSE, TRUE + ); + } + + $this->constraint = $constraint; + } + + /** + * @return string + */ + public function toString() + { + return 'method name ' . $this->constraint->toString(); + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return $this->constraint->evaluate($invocation->methodName); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/Parameters.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/Parameters.php new file mode 100644 index 00000000..bb2e0272 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/Parameters.php @@ -0,0 +1,172 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which looks for specific parameters in the invocations. + * + * Checks the parameters of all incoming invocations, the parameter list is + * checked against the defined constraints in $parameters. If the constraint + * is met it will return true in matches(). + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_Parameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + /** + * @var array + */ + protected $parameters = array(); + + /** + * @var PHPUnit_Framework_MockObject_Invocation + */ + protected $invocation; + + /** + * @param array $parameters + */ + public function __construct(array $parameters) + { + foreach($parameters as $parameter) { + if (!($parameter instanceof PHPUnit_Framework_Constraint)) { + $parameter = new PHPUnit_Framework_Constraint_IsEqual( + $parameter + ); + } + + $this->parameters[] = $parameter; + } + } + + /** + * @return string + */ + public function toString() + { + $text = 'with parameter'; + + foreach($this->parameters as $index => $parameter) { + if ($index > 0) { + $text .= ' and'; + } + + $text .= ' ' . $index . ' ' . $parameter->toString(); + } + + return $text; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->invocation = $invocation; + $this->verify(); + + return count($invocation->parameters) < count($this->parameters); + } + + /** + * Checks if the invocation $invocation matches the current rules. If it + * does the matcher will get the invoked() method called which should check + * if an expectation is met. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return bool + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + if ($this->invocation === NULL) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Mocked method does not exist.' + ); + } + + if (count($this->invocation->parameters) < count($this->parameters)) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + 'Parameter count for invocation %s is too low.', + + $this->invocation->toString() + ) + ); + } + + foreach ($this->parameters as $i => $parameter) { + if (!$parameter->evaluate($this->invocation->parameters[$i])) { + $parameter->fail( + $this->invocation->parameters[$i], + sprintf( + 'Parameter %s for invocation %s does not match expected ' . + 'value.', + + $i, + $this->invocation->toString() + ) + ); + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php new file mode 100644 index 00000000..9b0884a2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php @@ -0,0 +1,105 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Invocation matcher which does not care about previous state from earlier + * invocations. + * + * This abstract class can be implemented by matchers which does not care about + * state but only the current run-time value of the invocation itself. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + * @abstract + */ +abstract class PHPUnit_Framework_MockObject_Matcher_StatelessInvocation implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * Registers the invocation $invocation in the object as being invoked. + * This will only occur after matches() returns true which means the + * current invocation is the correct one. + * + * The matcher can store information from the invocation which can later + * be checked in verify(), or it can check the values directly and throw + * and exception if an expectation is not met. + * + * If the matcher is a stub it will also have a return value. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return mixed + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + } + + /** + * Checks if the invocation $invocation matches the current rules. If it does + * the matcher will get the invoked() method called which should check if an + * expectation is met. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return bool + */ + public function verify() + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/MockObject.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/MockObject.php new file mode 100644 index 00000000..5d819b21 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/MockObject.php @@ -0,0 +1,91 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher.php'; +require_once 'PHPUnit/Framework/MockObject/InvocationMocker.php'; +require_once 'PHPUnit/Framework/MockObject/Verifiable.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Interface for all mock objects which are generated by + * PHPUnit_Framework_MockObject_Mock. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_MockObject /*extends PHPUnit_Framework_MockObject_Verifiable*/ +{ + /** + * Registers a new expectation in the mock object and returns the match + * object which can be infused with further details. + * + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher); + + /** + * @return PHPUnit_Framework_MockObject_InvocationMocker + */ + public function __phpunit_getInvocationMocker(); + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function __phpunit_verify(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub.php new file mode 100644 index 00000000..779716ee --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * An object that stubs the process of a normal method for a mock object. + * + * The stub object will replace the code for the stubbed method and return a + * specific value instead of the original value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Stub extends PHPUnit_Framework_SelfDescribing +{ + /** + * Fakes the processing of the invocation $invocation by returning a + * specific value. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * The invocation which was mocked and matched by the current method + * and argument matchers. + * @return mixed + */ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation); +} + +require_once 'PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php'; +require_once 'PHPUnit/Framework/MockObject/Stub/Exception.php'; +require_once 'PHPUnit/Framework/MockObject/Stub/MatcherCollection.php'; +require_once 'PHPUnit/Framework/MockObject/Stub/Return.php'; +require_once 'PHPUnit/Framework/MockObject/Stub/ReturnArgument.php'; +require_once 'PHPUnit/Framework/MockObject/Stub/ReturnCallback.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php new file mode 100644 index 00000000..f971b211 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php @@ -0,0 +1,96 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Patrick Müller + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Stubs a method by returning a user-defined stack of values. + * + * @category Testing + * @package PHPUnit + * @author Patrick Müller + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls implements PHPUnit_Framework_MockObject_Stub +{ + protected $stack; + protected $value; + + public function __construct($stack) + { + $this->stack = $stack; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->value = array_shift($this->stack); + + if ($this->value instanceof PHPUnit_Framework_MockObject_Stub) { + $this->value = $this->value->invoke($invocation); + } + + return $this->value; + } + + public function toString() + { + return sprintf( + 'return user-specified value %s', + + PHPUnit_Util_Type::toString($this->value) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/Exception.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/Exception.php new file mode 100644 index 00000000..3f6f1cd5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/Exception.php @@ -0,0 +1,89 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Oliver Schlicht + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Stubs a method by raising a user-defined exception. + * + * @category Testing + * @package PHPUnit + * @author Oliver Schlicht + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_MockObject_Stub_Exception implements PHPUnit_Framework_MockObject_Stub +{ + protected $exception; + + public function __construct(Exception $exception) + { + $this->exception = $exception; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + throw $this->exception; + } + + public function toString() + { + return sprintf( + 'raise user-specified exception %s', + + PHPUnit_Util_Type::toString($this->exception) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/MatcherCollection.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/MatcherCollection.php new file mode 100644 index 00000000..74ff4c56 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/MatcherCollection.php @@ -0,0 +1,74 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Stubs a method by returning a user-defined value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Stub_MatcherCollection +{ + /** + * Adds a new matcher to the collection which can be used as an expectation + * or a stub. + * + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + * Matcher for invocations to mock objects. + */ + public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/Return.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/Return.php new file mode 100644 index 00000000..f9e09126 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/Return.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Stubs a method by returning a user-defined value. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_Return implements PHPUnit_Framework_MockObject_Stub +{ + protected $value; + + public function __construct($value) + { + $this->value = $value; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return $this->value; + } + + public function toString() + { + return sprintf( + 'return user-specified value %s', + + PHPUnit_Util_Type::toString($this->value) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ReturnArgument.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ReturnArgument.php new file mode 100644 index 00000000..0cc3a513 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ReturnArgument.php @@ -0,0 +1,86 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Stub/Return.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Stubs a method by returning an argument that was passed to the mocked method. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_MockObject_Stub_ReturnArgument extends PHPUnit_Framework_MockObject_Stub_Return +{ + protected $argumentIndex; + + public function __construct($argumentIndex) + { + $this->argumentIndex = $argumentIndex; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if (isset($invocation->parameters[$this->argumentIndex])) { + return $invocation->parameters[$this->argumentIndex]; + } else { + return NULL; + } + } + + public function toString() + { + return sprintf('return argument #%d', $this->argumentIndex); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php new file mode 100644 index 00000000..ecd38f0c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php @@ -0,0 +1,103 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Framework/MockObject/Invocation.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_MockObject_Stub_ReturnCallback implements PHPUnit_Framework_MockObject_Stub +{ + protected $callback; + + public function __construct($callback) + { + $this->callback = $callback; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return call_user_func_array($this->callback, $invocation->parameters); + } + + public function toString() + { + if (is_array($this->callback)) { + if (is_object($this->callback[0])) { + $class = get_class($this->callback[0]); + $type = '->'; + } else { + $class = $this->callback[0]; + $type = '::'; + } + + return sprintf( + 'return result of user defined callback %s%s%s() with the ' . + 'passed arguments', + + $class, + $type, + $this->callback[1] + ); + } else { + return 'return result of user defined callback ' . $this->callback . + ' with the passed arguments'; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Verifiable.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Verifiable.php new file mode 100644 index 00000000..bc62b77e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/MockObject/Verifiable.php @@ -0,0 +1,72 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Interface for classes which must verify a given expectation. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_MockObject_Verifiable +{ + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Process/TestCaseMethod.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Process/TestCaseMethod.tpl.dist new file mode 100644 index 00000000..492ad71e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Process/TestCaseMethod.tpl.dist @@ -0,0 +1,44 @@ +collectRawCodeCoverageInformation({collectCodeCoverageInformation}); + + $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}'); + $test->setDependencyInput(unserialize('{dependencyInput}')); + $test->setInIsolation(TRUE); + + ob_end_clean(); + ob_start(); + $test->run($result); + $output = ob_get_contents(); + ob_end_clean(); + + print serialize( + array( + 'testResult' => $test->getResult(), + 'numAssertions' => $test->getNumAssertions(), + 'result' => $result, + 'output' => $output + ) + ); + + ob_start(); +} + +if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + require_once $GLOBALS['__PHPUNIT_BOOTSTRAP']; + unset($GLOBALS['__PHPUNIT_BOOTSTRAP']); +} + +{constants} +{globals} +{included_files} + +__phpunit_run_isolated_test(); +ob_end_clean(); +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SelfDescribing.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SelfDescribing.php new file mode 100644 index 00000000..ea6d5623 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SelfDescribing.php @@ -0,0 +1,71 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Interface for classes that can return a description of itself. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_SelfDescribing +{ + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTest.php new file mode 100644 index 00000000..a3b0ee2c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTest.php @@ -0,0 +1,65 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A marker interface for marking a unit test as being skipped. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_SkippedTest +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTestError.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTestError.php new file mode 100644 index 00000000..6aca58ed --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTestError.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a skipped test. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTestSuiteError.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTestSuiteError.php new file mode 100644 index 00000000..957c2d4c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/SkippedTestSuiteError.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a skipped test suite. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_SkippedTestSuiteError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Test.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Test.php new file mode 100644 index 00000000..fa87c9b3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Test.php @@ -0,0 +1,72 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A Test can be run and collect its results. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Framework_Test extends Countable +{ + /** + * Runs a test and collects its result in a TestResult instance. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = NULL); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestCase.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestCase.php new file mode 100644 index 00000000..b5c1a2a0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestCase.php @@ -0,0 +1,1552 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Framework/MockObject/Generator.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php'; +require_once 'PHPUnit/Framework/MockObject/Matcher/InvokedCount.php'; +require_once 'PHPUnit/Framework/MockObject/Stub.php'; +require_once 'PHPUnit/Runner/BaseTestRunner.php'; +require_once 'PHPUnit/Util/GlobalState.php'; +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; +require_once 'PHPUnit/Util/PHP.php'; +require_once 'PHPUnit/Util/Template.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestCase defines the fixture to run multiple tests. + * + * To define a TestCase + * + * 1) Implement a subclass of PHPUnit_Framework_TestCase. + * 2) Define instance variables that store the state of the fixture. + * 3) Initialize the fixture state by overriding setUp(). + * 4) Clean-up after a test by overriding tearDown(). + * + * Each test runs in its own fixture so there can be no side effects + * among test runs. + * + * Here is an example: + * + * + * value1 = 2; + * $this->value2 = 3; + * } + * } + * ?> + * + * + * For each test implement a method which interacts with the fixture. + * Verify the expected results with assertions specified by calling + * assert with a boolean. + * + * + * assertTrue($this->value1 + $this->value2 == 5); + * } + * ?> + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + * @abstract + */ +abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * Enable or disable the backup and restoration of the $GLOBALS array. + * Overwrite this attribute in a child class of TestCase. + * Setting this attribute in setUp() has no effect! + * + * @var boolean + */ + protected $backupGlobals = NULL; + + /** + * @var array + */ + protected $backupGlobalsBlacklist = array(); + + /** + * Enable or disable the backup and restoration of static attributes. + * Overwrite this attribute in a child class of TestCase. + * Setting this attribute in setUp() has no effect! + * + * @var boolean + */ + protected $backupStaticAttributes = NULL; + + /** + * @var array + */ + protected $backupStaticAttributesBlacklist = array(); + + /** + * Whether or not this test is to be run in a separate PHP process. + * + * @var boolean + */ + protected $runTestInSeparateProcess = NULL; + + /** + * Whether or not this test should preserve the global state when running in a separate PHP process. + * + * @var boolean + */ + protected $preserveGlobalState = TRUE; + + /** + * Whether or not this test is running in a separate PHP process. + * + * @var boolean + */ + protected $inIsolation = FALSE; + + /** + * @var array + */ + protected $data = array(); + + /** + * @var string + */ + protected $dataName = ''; + + /** + * @var boolean + */ + protected $useErrorHandler = NULL; + + /** + * @var boolean + */ + protected $useOutputBuffering = NULL; + + /** + * The name of the expected Exception. + * + * @var mixed + */ + protected $expectedException = NULL; + + /** + * The message of the expected Exception. + * + * @var string + */ + protected $expectedExceptionMessage = ''; + + /** + * The code of the expected Exception. + * + * @var integer + */ + protected $expectedExceptionCode; + + /** + * Fixture that is shared between the tests of a test suite. + * + * @var mixed + */ + protected $sharedFixture; + + /** + * The name of the test case. + * + * @var string + */ + protected $name = NULL; + + /** + * @var array + */ + protected $dependencies = array(); + + /** + * @var array + */ + protected $dependencyInput = array(); + + /** + * @var string + */ + protected $exceptionMessage = NULL; + + /** + * @var integer + */ + protected $exceptionCode = 0; + + /** + * @var Array + */ + protected $iniSettings = array(); + + /** + * @var Array + */ + protected $locale = array(); + + /** + * @var Array + */ + protected $mockObjects = array(); + + /** + * @var integer + */ + protected $status; + + /** + * @var string + */ + protected $statusMessage = ''; + + /** + * @var integer + */ + protected $numAssertions = 0; + + /** + * @var PHPUnit_Framework_TestResult + */ + protected $result; + + /** + * @var mixed + */ + protected $testResult; + + /** + * Constructs a test case with the given name. + * + * @param string $name + * @param array $data + * @param string $dataName + */ + public function __construct($name = NULL, array $data = array(), $dataName = '') + { + if ($name !== NULL) { + $this->setName($name); + } + + $this->data = $data; + $this->dataName = $dataName; + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + $class = new ReflectionClass($this); + + $buffer = sprintf( + '%s::%s', + + $class->name, + $this->getName(FALSE) + ); + + return $buffer . $this->getDataSetAsString(); + } + + /** + * Counts the number of test cases executed by run(TestResult result). + * + * @return integer + */ + public function count() + { + return 1; + } + + /** + * Returns the annotations for this test. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function getAnnotations() + { + return PHPUnit_Util_Test::parseTestMethodAnnotations( + get_class($this), $this->name + ); + } + + /** + * Gets the name of a TestCase. + * + * @param boolean $withDataSet + * @return string + */ + public function getName($withDataSet = TRUE) + { + if ($withDataSet) { + return $this->name . $this->getDataSetAsString(FALSE); + } else { + return $this->name; + } + } + + /** + * @return string + * @since Method available since Release 3.2.0 + */ + public function getExpectedException() + { + return $this->expectedException; + } + + /** + * @param mixed $exceptionName + * @param string $exceptionMessage + * @param integer $exceptionCode + * @since Method available since Release 3.2.0 + */ + public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = 0) + { + $this->expectedException = $exceptionName; + $this->expectedExceptionMessage = $exceptionMessage; + $this->expectedExceptionCode = $exceptionCode; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setExpectedExceptionFromAnnotation() + { + try { + $method = new ReflectionMethod(get_class($this), $this->name); + $methodDocComment = $method->getDocComment(); + $expectedException = PHPUnit_Util_Test::getExpectedException($methodDocComment); + + if ($expectedException !== FALSE) { + $this->setExpectedException( + $expectedException['class'], + $expectedException['message'], + $expectedException['code'] + ); + } + } + + catch (ReflectionException $e) { + } + } + + /** + * @param boolean $useErrorHandler + * @since Method available since Release 3.4.0 + */ + public function setUseErrorHandler($useErrorHandler) + { + $this->useErrorHandler = $useErrorHandler; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setUseErrorHandlerFromAnnotation() + { + try { + $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings( + get_class($this), $this->name + ); + + if ($useErrorHandler !== NULL) { + $this->setUseErrorHandler($useErrorHandler); + } + } + + catch (ReflectionException $e) { + } + } + + /** + * @param boolean $useOutputBuffering + * @since Method available since Release 3.4.0 + */ + public function setUseOutputBuffering($useOutputBuffering) + { + $this->useOutputBuffering = $useOutputBuffering; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setUseOutputBufferingFromAnnotation() + { + try { + $useOutputBuffering = PHPUnit_Util_Test::getOutputBufferingSettings( + get_class($this), $this->name + ); + + if ($useOutputBuffering !== NULL) { + $this->setUseOutputBuffering($useOutputBuffering); + } + } + + catch (ReflectionException $e) { + } + } + + /** + * Returns the status of this test. + * + * @return integer + * @since Method available since Release 3.1.0 + */ + public function getStatus() + { + return $this->status; + } + + /** + * Returns the status message of this test. + * + * @return string + * @since Method available since Release 3.3.0 + */ + public function getStatusMessage() + { + return $this->statusMessage; + } + + /** + * Returns whether or not this test has failed. + * + * @return boolean + * @since Method available since Release 3.0.0 + */ + public function hasFailed() + { + $status = $this->getStatus(); + + return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE || + $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + } + + /** + * Runs the test case and collects the results in a TestResult object. + * If no TestResult object is passed a new one will be created. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws InvalidArgumentException + */ + public function run(PHPUnit_Framework_TestResult $result = NULL) + { + if ($result === NULL) { + $result = $this->createResult(); + } + + $this->setExpectedExceptionFromAnnotation(); + $this->setUseErrorHandlerFromAnnotation(); + $this->setUseOutputBufferingFromAnnotation(); + + if ($this->useErrorHandler !== NULL) { + $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions(); + $result->convertErrorsToExceptions($this->useErrorHandler); + } + + $this->result = $result; + + if (!empty($this->dependencies) && !$this->inIsolation) { + $className = get_class($this); + $passed = $this->result->passed(); + $passedKeys = array_keys($passed); + + foreach ($this->dependencies as $dependency) { + if (strpos($dependency, '::') === FALSE) { + $dependency = $className . '::' . $dependency; + } + + if (!in_array($dependency, $passedKeys)) { + $result->addError( + $this, + new PHPUnit_Framework_SkippedTestError( + sprintf( + 'This test depends on "%s" to pass.', $dependency + ) + ), + 0 + ); + + return; + } else { + $this->dependencyInput[] = $passed[$dependency]; + } + } + } + + if ($this->runTestInSeparateProcess === TRUE && + $this->inIsolation !== TRUE && + !$this instanceof PHPUnit_Extensions_SeleniumTestCase && + !$this instanceof PHPUnit_Extensions_PhptTestCase) { + $class = new ReflectionClass($this); + $collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation(); + + $template = new PHPUnit_Util_Template( + sprintf( + '%s%sProcess%sTestCaseMethod.tpl', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ) + ); + + $template->setVar( + array( + 'filename' => $class->getFileName(), + 'className' => $class->getName(), + 'methodName' => $this->name, + 'data' => addcslashes(serialize($this->data), "'"), + 'dependencyInput' => addcslashes(serialize($this->dependencyInput), "'"), + 'dataName' => $this->dataName, + 'collectCodeCoverageInformation' => $collectCodeCoverageInformation ? 'TRUE' : 'FALSE', + 'included_files' => $this->preserveGlobalState ? PHPUnit_Util_GlobalState::getIncludedFilesAsString() : '', + 'constants' => $this->preserveGlobalState ? PHPUnit_Util_GlobalState::getConstantsAsString() : '', + 'globals' => $this->preserveGlobalState ? PHPUnit_Util_GlobalState::getGlobalsAsString() : '', + 'include_path' => addslashes(get_include_path()) + ) + ); + + $this->prepareTemplate($template); + $job = $template->render(); + $result->startTest($this); + + $jobResult = PHPUnit_Util_PHP::runJob($job); + + if (!empty($jobResult['stderr'])) { + $time = 0; + $result->addError( + $this, + new RuntimeException(trim($jobResult['stderr'])), $time + ); + } else { + $childResult = @unserialize($jobResult['stdout']); + + if ($childResult !== FALSE) { + if (!empty($childResult['output'])) { + print $childResult['output']; + } + + $this->testResult = $childResult['testResult']; + $this->numAssertions = $childResult['numAssertions']; + $childResult = $childResult['result']; + + if ($collectCodeCoverageInformation) { + $codeCoverageInformation = $childResult->getRawCodeCoverageInformation(); + + $result->appendCodeCoverageInformation( + $this, $codeCoverageInformation[0]['data'] + ); + } + + $time = $childResult->time(); + $notImplemented = $childResult->notImplemented(); + $skipped = $childResult->skipped(); + $errors = $childResult->errors(); + $failures = $childResult->failures(); + + if (!empty($notImplemented)) { + $result->addError( + $this, $notImplemented[0]->thrownException(), $time + ); + } + + else if (!empty($skipped)) { + $result->addError( + $this, $skipped[0]->thrownException(), $time + ); + } + + else if (!empty($errors)) { + $result->addError( + $this, $errors[0]->thrownException(), $time + ); + } + + else if (!empty($failures)) { + $result->addFailure( + $this, $failures[0]->thrownException(), $time + ); + } + } else { + $time = 0; + $result->addError( + $this, + new RuntimeException(trim($jobResult['stdout'])), $time + ); + } + } + + $result->endTest($this, $time); + } else { + $result->run($this); + } + + if ($this->useErrorHandler !== NULL) { + $result->convertErrorsToExceptions($oldErrorHandlerSetting); + } + + $this->result = NULL; + + return $result; + } + + /** + * Runs the bare test sequence. + */ + public function runBare() + { + $this->numAssertions = 0; + + // Backup the $GLOBALS array and static attributes. + if ($this->runTestInSeparateProcess !== TRUE && + $this->inIsolation !== TRUE) { + if ($this->backupGlobals === NULL || + $this->backupGlobals === TRUE) { + PHPUnit_Util_GlobalState::backupGlobals( + $this->backupGlobalsBlacklist + ); + } + + if (version_compare(PHP_VERSION, '5.3', '>') && + $this->backupStaticAttributes === TRUE) { + PHPUnit_Util_GlobalState::backupStaticAttributes( + $this->backupStaticAttributesBlacklist + ); + } + } + + // Start output buffering. + if ($this->useOutputBuffering === TRUE) { + ob_start(); + } + + // Clean up stat cache. + clearstatcache(); + + // Run the test. + try { + // Set up the fixture. + $this->setUp(); + + // Assert pre-conditions. + $this->assertPreConditions(); + + $this->testResult = $this->runTest(); + + // Assert post-conditions. + $this->assertPostConditions(); + + // Verify Mock Object conditions. + foreach ($this->mockObjects as $mockObject) { + $this->numAssertions++; + $mockObject->__phpunit_verify(); + $mockObject->__phpunit_cleanup(); + } + + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED; + } + + catch (PHPUnit_Framework_IncompleteTest $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE; + $this->statusMessage = $e->getMessage(); + } + + catch (PHPUnit_Framework_SkippedTest $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED; + $this->statusMessage = $e->getMessage(); + } + + catch (PHPUnit_Framework_AssertionFailedError $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE; + $this->statusMessage = $e->getMessage(); + } + + catch (Exception $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + $this->statusMessage = $e->getMessage(); + } + + $this->mockObjects = array(); + + // Tear down the fixture. An exception raised in tearDown() will be + // caught and passed on when no exception was raised before. + try { + $this->tearDown(); + } + + catch (Exception $_e) { + if (!isset($e)) { + $e = $_e; + } + } + + // Stop output buffering. + if ($this->useOutputBuffering === TRUE) { + ob_end_clean(); + } + + // Clean up stat cache. + clearstatcache(); + + // Restore the $GLOBALS array and static attributes. + if ($this->runTestInSeparateProcess !== TRUE && + $this->inIsolation !== TRUE) { + if ($this->backupGlobals === NULL || + $this->backupGlobals === TRUE) { + PHPUnit_Util_GlobalState::restoreGlobals( + $this->backupGlobalsBlacklist + ); + } + + if (version_compare(PHP_VERSION, '5.3', '>') && + $this->backupStaticAttributes === TRUE) { + PHPUnit_Util_GlobalState::restoreStaticAttributes(); + } + } + + // Clean up INI settings. + foreach ($this->iniSettings as $varName => $oldValue) { + ini_set($varName, $oldValue); + } + + $this->iniSettings = array(); + + // Clean up locale settings. + foreach ($this->locale as $category => $locale) { + setlocale($category, $locale); + } + + // Workaround for missing "finally". + if (isset($e)) { + $this->onNotSuccessfulTest($e); + } + } + + /** + * Override to run the test and assert its state. + * + * @return mixed + * @throws RuntimeException + */ + protected function runTest() + { + if ($this->name === NULL) { + throw new PHPUnit_Framework_Exception( + 'PHPUnit_Framework_TestCase::$name must not be NULL.' + ); + } + + try { + $class = new ReflectionClass($this); + $method = $class->getMethod($this->name); + } + + catch (ReflectionException $e) { + $this->fail($e->getMessage()); + } + + try { + $testResult = $method->invokeArgs( + $this, array_merge($this->data, $this->dependencyInput) + ); + } + + catch (Exception $e) { + if (!$e instanceof PHPUnit_Framework_IncompleteTest && + !$e instanceof PHPUnit_Framework_SkippedTest && + is_string($this->expectedException) && + $e instanceof $this->expectedException) { + if (is_string($this->expectedExceptionMessage) && + !empty($this->expectedExceptionMessage)) { + $this->assertContains( + $this->expectedExceptionMessage, + $e->getMessage() + ); + } + + if (is_int($this->expectedExceptionCode) && + $this->expectedExceptionCode !== 0) { + $this->assertEquals( + $this->expectedExceptionCode, $e->getCode() + ); + } + + $this->numAssertions++; + + return; + } else { + throw $e; + } + } + + if ($this->expectedException !== NULL) { + $this->numAssertions++; + $this->fail('Expected exception ' . $this->expectedException); + } + + return $testResult; + } + + /** + * Sets the name of a TestCase. + * + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Sets the dependencies of a TestCase. + * + * @param array $dependencies + * @since Method available since Release 3.4.0 + */ + public function setDependencies(array $dependencies) + { + $this->dependencies = $dependencies; + } + + /** + * Sets + * + * @param array $dependencyInput + * @since Method available since Release 3.4.0 + */ + public function setDependencyInput(array $dependencyInput) + { + $this->dependencyInput = $dependencyInput; + } + + /** + * Calling this method in setUp() has no effect! + * + * @param boolean $backupGlobals + * @since Method available since Release 3.3.0 + */ + public function setBackupGlobals($backupGlobals) + { + if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * Calling this method in setUp() has no effect! + * + * @param boolean $backupStaticAttributes + * @since Method available since Release 3.4.0 + */ + public function setBackupStaticAttributes($backupStaticAttributes) + { + if (is_null($this->backupStaticAttributes) && + is_bool($backupStaticAttributes)) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * @param boolean $runTestInSeparateProcess + * @throws InvalidArgumentException + * @since Method available since Release 3.4.0 + */ + public function setRunTestInSeparateProcess($runTestInSeparateProcess) + { + if (is_bool($runTestInSeparateProcess)) { + if ($this->runTestInSeparateProcess === NULL) { + $this->runTestInSeparateProcess = $runTestInSeparateProcess; + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @param boolean $preserveGlobalState + * @throws InvalidArgumentException + * @since Method available since Release 3.4.0 + */ + public function setPreserveGlobalState($preserveGlobalState) + { + if (is_bool($preserveGlobalState)) { + $this->preserveGlobalState = $preserveGlobalState; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @param boolean $inIsolation + * @throws InvalidArgumentException + * @since Method available since Release 3.4.0 + */ + public function setInIsolation($inIsolation) + { + if (is_bool($inIsolation)) { + $this->inIsolation = $inIsolation; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Sets the shared fixture. + * + * @param mixed $sharedFixture + * @since Method available since Release 3.1.0 + */ + public function setSharedFixture($sharedFixture) + { + $this->sharedFixture = $sharedFixture; + } + + /** + * @return mixed + * @since Method available since Release 3.4.0 + */ + public function getResult() + { + return $this->testResult; + } + + /** + * @param mixed $result + * @since Method available since Release 3.4.0 + */ + public function setResult($result) + { + $this->testResult = $result; + } + + /** + * This method is a wrapper for the ini_set() function that automatically + * resets the modified php.ini setting to its original value after the + * test is run. + * + * @param string $varName + * @param string $newValue + * @throws InvalidArgumentException + * @throws RuntimeException + * @since Method available since Release 3.0.0 + */ + protected function iniSet($varName, $newValue) + { + if (!is_string($varName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $currentValue = ini_set($varName, $newValue); + + if ($currentValue !== FALSE) { + $this->iniSettings[$varName] = $currentValue; + } else { + throw new PHPUnit_Framework_Exception( + sprintf( + 'INI setting "%s" could not be set to "%s".', + $varName, + $newValue + ) + ); + } + } + + /** + * This method is a wrapper for the setlocale() function that automatically + * resets the locale to its original value after the test is run. + * + * @param integer $category + * @param string $locale + * @throws InvalidArgumentException + * @throws RuntimeException + * @since Method available since Release 3.1.0 + */ + protected function setLocale() + { + $args = func_get_args(); + + if (count($args) < 2) { + throw new InvalidArgumentException; + } + + $category = $args[0]; + $locale = $args[1]; + + $categories = array( + LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME + ); + + if (defined('LC_MESSAGES')) { + $categories[] = LC_MESSAGES; + } + + if (!in_array($category, $categories)) { + throw new InvalidArgumentException; + } + + if (!is_array($locale) && !is_string($locale)) { + throw new InvalidArgumentException; + } + + $this->locale[$category] = setlocale($category, NULL); + + $result = call_user_func_array( 'setlocale', $args ); + + if ($result === FALSE) { + throw new PHPUnit_Framework_Exception( + 'The locale functionality is not implemented on your platform, ' . + 'the specified locale does not exist or the category name is ' . + 'invalid.' + ); + } + } + + /** + * Returns a mock object for the specified class. + * + * @param string $originalClassName + * @param array $methods + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @return object + * @throws InvalidArgumentException + * @since Method available since Release 3.0.0 + */ + protected function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) + { + if (!is_string($originalClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($mockClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'string'); + } + + if (!is_array($methods) && !is_null($methods)) { + throw new InvalidArgumentException; + } + + if ($mockClassName != '' && class_exists($mockClassName, FALSE)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Class "%s" already exists.', + $mockClassName + ) + ); + } + + $mock = PHPUnit_Framework_MockObject_Generator::generate( + $originalClassName, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload + ); + + if (!class_exists($mock['mockClassName'], FALSE)) { + eval($mock['code']); + } + + if ($callOriginalConstructor && !interface_exists($originalClassName, $callAutoload)) { + if (count($arguments) == 0) { + $mockObject = new $mock['mockClassName']; + } else { + $mockClass = new ReflectionClass($mock['mockClassName']); + $mockObject = $mockClass->newInstanceArgs($arguments); + } + } else { + // Use a trick to create a new object of a class + // without invoking its constructor. + $mockObject = unserialize( + sprintf( + 'O:%d:"%s":0:{}', + strlen($mock['mockClassName']), $mock['mockClassName'] + ) + ); + } + + $this->mockObjects[] = $mockObject; + + return $mockObject; + } + + /** + * Returns a mock object for the specified abstract class with all abstract + * methods of the class mocked. Concrete methods are not mocked. + * + * @param string $originalClassName + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @return object + * @since Method available since Release 3.4.0 + * @throws InvalidArgumentException + */ + protected function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) + { + if (!is_string($originalClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($mockClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string'); + } + + if (class_exists($originalClassName, $callAutoload)) { + $methods = array(); + $reflector = new ReflectionClass($originalClassName); + + foreach ($reflector->getMethods() as $method) { + if ($method->isAbstract()) { + $methods[] = $method->getName(); + } + } + + if (empty($methods)) { + $methods = NULL; + } + + return $this->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload + ); + } else { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Class "%s" does not exist.', + $originalClassName + ) + ); + } + } + + /** + * Returns a mock object based on the given WSDL file. + * + * @param string $wsdlFile + * @param string $originalClassName + * @param string $mockClassName + * @param array $methods + * @param boolean $callOriginalConstructor + * @return object + * @since Method available since Release 3.4.0 + */ + protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = TRUE) + { + if ($originalClassName === '') { + $originalClassName = str_replace( + '.wsdl', '', basename($wsdlFile) + ); + } + + eval( + PHPUnit_Framework_MockObject_Generator::generateClassFromWsdl( + $wsdlFile, $originalClassName, $methods + ) + ); + + return $this->getMock( + $originalClassName, + $methods, + array('', array()), + $mockClassName, + $callOriginalConstructor, + FALSE, + FALSE + ); + } + + /** + * Adds a value to the assertion counter. + * + * @param integer $count + * @since Method available since Release 3.3.3 + */ + public function addToAssertionCount($count) + { + $this->numAssertions += $count; + } + + /** + * Returns the number of assertions performed by this test. + * + * @return integer + * @since Method available since Release 3.3.0 + */ + public function getNumAssertions() + { + return $this->numAssertions; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed zero or more times. + * + * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount + * @since Method available since Release 3.0.0 + */ + protected function any() + { + return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is never executed. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + protected function never() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed at least once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce + * @since Method available since Release 3.0.0 + */ + protected function atLeastOnce() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + protected function once() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly $count times. + * + * @param integer $count + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + protected function exactly($count) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is invoked at the given $index. + * + * @param integer $index + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex + * @since Method available since Release 3.0.0 + */ + protected function at($index) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index); + } + + /** + * + * + * @param mixed $value + * @return PHPUnit_Framework_MockObject_Stub_Return + * @since Method available since Release 3.0.0 + */ + protected function returnValue($value) + { + return new PHPUnit_Framework_MockObject_Stub_Return($value); + } + + /** + * + * + * @param integer $argumentIndex + * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument + * @since Method available since Release 3.3.0 + */ + protected function returnArgument($argumentIndex) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnArgument( + $argumentIndex + ); + } + + /** + * + * + * @param mixed $callback + * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback + * @since Method available since Release 3.3.0 + */ + protected function returnCallback($callback) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback); + } + + /** + * + * + * @param Exception $exception + * @return PHPUnit_Framework_MockObject_Stub_Exception + * @since Method available since Release 3.1.0 + */ + protected function throwException(Exception $exception) + { + return new PHPUnit_Framework_MockObject_Stub_Exception($exception); + } + + /** + * + * + * @param mixed $value, ... + * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls + * @since Method available since Release 3.0.0 + */ + protected function onConsecutiveCalls() + { + $args = func_get_args(); + + return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args); + } + + /** + * @param mixed $data + * @return string + * @since Method available since Release 3.2.1 + */ + protected function dataToString($data) + { + $result = array(); + + foreach ($data as $_data) { + if (is_array($_data)) { + $result[] = 'array(' . $this->dataToString($_data) . ')'; + } + + else if (is_object($_data)) { + $object = new ReflectionObject($_data); + + if ($object->hasMethod('__toString')) { + $result[] = (string)$_data; + } else { + $result[] = get_class($_data); + } + } + + else if (is_resource($_data)) { + $result[] = ''; + } + + else { + $result[] = var_export($_data, TRUE); + } + } + + return join(', ', $result); + } + + /** + * Gets the data set description of a TestCase. + * + * @param boolean $includeData + * @return string + * @since Method available since Release 3.3.0 + */ + protected function getDataSetAsString($includeData = TRUE) + { + $buffer = ''; + + if (!empty($this->data)) { + if (is_int($this->dataName)) { + $buffer .= sprintf(' with data set #%d', $this->dataName); + } else { + $buffer .= sprintf(' with data set "%s"', $this->dataName); + } + + if ($includeData) { + $buffer .= sprintf(' (%s)', $this->dataToString($this->data)); + } + } + + return $buffer; + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * This method is called before the first test of this test class is run. + * + * @since Method available since Release 3.4.0 + */ + public static function setUpBeforeClass() + { + } + + /** + * Sets up the fixture, for example, open a network connection. + * This method is called before a test is executed. + * + */ + protected function setUp() + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called before the execution of a test starts + * and after setUp() is called. + * + * @since Method available since Release 3.2.8 + */ + protected function assertPreConditions() + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called before the execution of a test ends + * and before tearDown() is called. + * + * @since Method available since Release 3.2.8 + */ + protected function assertPostConditions() + { + } + + /** + * Tears down the fixture, for example, close a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + } + + /** + * This method is called after the last test of this test class is run. + * + * @since Method available since Release 3.4.0 + */ + public static function tearDownAfterClass() + { + } + + /** + * This method is called when a test method did not execute successfully. + * + * @param Exception $e + * @since Method available since Release 3.4.0 + */ + protected function onNotSuccessfulTest(Exception $e) + { + throw $e; + } + + /** + * Performs custom preparations on the process isolation template. + * + * @param PHPUnit_Util_Template $template + * @since Method available since Release 3.4.0 + */ + protected function prepareTemplate(PHPUnit_Util_Template $template) + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestFailure.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestFailure.php new file mode 100644 index 00000000..2e605c60 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestFailure.php @@ -0,0 +1,242 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestFailure collects a failed test together with the caught exception. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_TestFailure +{ + /** + * @var PHPUnit_Framework_Test + */ + protected $failedTest; + + /** + * @var Exception + */ + protected $thrownException; + + /** + * Constructs a TestFailure with the given test and exception. + * + * @param PHPUnit_Framework_Test $failedTest + * @param Exception $thrownException + */ + public function __construct(PHPUnit_Framework_Test $failedTest, Exception $thrownException) + { + $this->failedTest = $failedTest; + $this->thrownException = $thrownException; + } + + /** + * Returns a short description of the failure. + * + * @return string + */ + public function toString() + { + return sprintf( + '%s: %s', + + $this->failedTest, + $this->thrownException->getMessage() + ); + } + + /** + * Returns a description for the thrown exception. + * + * @return string + * @since Method available since Release 3.4.0 + */ + public function getExceptionAsString() + { + return self::exceptionToString($this->thrownException); + } + + /** + * Returns a description for an exception. + * + * @param Exception $e + * @return string + * @since Method available since Release 3.2.0 + */ + public static function exceptionToString(Exception $e) + { + if ($e instanceof PHPUnit_Framework_SelfDescribing) { + if ($e instanceof PHPUnit_Framework_ExpectationFailedException) { + $comparisonFailure = $e->getComparisonFailure(); + $description = $e->getDescription(); + $message = $e->getCustomMessage(); + + if ($message == '') { + $buffer = ''; + } else { + $buffer = $message . "\n"; + } + + if ($comparisonFailure !== NULL) { + if ($comparisonFailure->identical()) { + if ($comparisonFailure instanceof PHPUnit_Framework_ComparisonFailure_Object) { + $buffer .= 'Failed asserting that two variables ' . + "reference the same object.\n"; + } else { + $buffer .= $comparisonFailure->toString() . "\n"; + } + } else { + if ($comparisonFailure instanceof PHPUnit_Framework_ComparisonFailure_Scalar) { + $buffer .= sprintf( + "Failed asserting that %s matches expected %s.\n", + + PHPUnit_Util_Type::toString( + $comparisonFailure->getActual() + ), + PHPUnit_Util_Type::toString( + $comparisonFailure->getExpected() + ) + ); + } + + else if ($comparisonFailure instanceof PHPUnit_Framework_ComparisonFailure_Array || + $comparisonFailure instanceof PHPUnit_Framework_ComparisonFailure_Object || + $comparisonFailure instanceof PHPUnit_Framework_ComparisonFailure_String) { + $buffer .= sprintf( + "Failed asserting that two %ss are equal.\n%s\n", + + strtolower( + substr(get_class($comparisonFailure), 36) + ), + $comparisonFailure->toString() + ); + } + } + } else { + $buffer .= $e->toString(); + + if (!empty($buffer)) { + $buffer .= "\n"; + } + + if (strpos($buffer, $description) === FALSE) { + $buffer .= $description . "\n"; + } + } + } + + else { + $buffer = $e->toString(); + + if (!empty($buffer)) { + $buffer .= "\n"; + } + } + } + + else if ($e instanceof PHPUnit_Framework_Error) { + $buffer = $e->getMessage() . "\n"; + } + + else { + $buffer = get_class($e) . ': ' . $e->getMessage() . "\n"; + } + + return $buffer; + } + + /** + * Gets the failed test. + * + * @return Test + */ + public function failedTest() + { + return $this->failedTest; + } + + /** + * Gets the thrown exception. + * + * @return Exception + */ + public function thrownException() + { + return $this->thrownException; + } + + /** + * Returns the exception's message. + * + * @return string + */ + public function exceptionMessage() + { + return $this->thrownException()->getMessage(); + } + + /** + * Returns TRUE if the thrown exception + * is of type AssertionFailedError. + * + * @return boolean + */ + public function isFailure() + { + return ($this->thrownException() instanceof PHPUnit_Framework_AssertionFailedError); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestListener.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestListener.php new file mode 100644 index 00000000..5e416494 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestListener.php @@ -0,0 +1,132 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A Listener for test progress. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Framework_TestListener +{ + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time); + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite); + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite); + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test); + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestResult.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestResult.php new file mode 100644 index 00000000..70b536c2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestResult.php @@ -0,0 +1,819 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/ErrorHandler.php'; +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/Test.php'; +require_once 'PHPUnit/Util/Timer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestResult collects the results of executing a test case. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_TestResult implements Countable +{ + /** + * @var boolean + */ + protected static $xdebugLoaded = NULL; + + /** + * @var boolean + */ + protected static $useXdebug = NULL; + + /** + * @var array + */ + protected $passed = array(); + + /** + * @var array + */ + protected $errors = array(); + + /** + * @var array + */ + protected $failures = array(); + + /** + * @var array + */ + protected $notImplemented = array(); + + /** + * @var array + */ + protected $skipped = array(); + + /** + * @var array + */ + protected $listeners = array(); + + /** + * @var integer + */ + protected $runTests = 0; + + /** + * @var float + */ + protected $time = 0; + + /** + * @var PHPUnit_Framework_TestSuite + */ + protected $topTestSuite = NULL; + + /** + * Code Coverage information provided by Xdebug. + * + * @var array + */ + protected $codeCoverageInformation = array(); + + /** + * @var boolean + */ + protected $collectCodeCoverageInformation = FALSE; + + /** + * @var boolean + */ + protected $collectRawCodeCoverageInformation = FALSE; + + /** + * @var boolean + */ + protected $convertErrorsToExceptions = TRUE; + + /** + * @var boolean + */ + protected $stop = FALSE; + + /** + * @var boolean + */ + protected $stopOnFailure = FALSE; + + /** + * @var boolean + */ + protected $lastTestFailed = FALSE; + + /** + * Registers a TestListener. + * + * @param PHPUnit_Framework_TestListener + */ + public function addListener(PHPUnit_Framework_TestListener $listener) + { + $this->listeners[] = $listener; + } + + /** + * Unregisters a TestListener. + * + * @param PHPUnit_Framework_TestListener $listener + */ + public function removeListener(PHPUnit_Framework_TestListener $listener) + { + foreach ($this->listeners as $key => $_listener) { + if ($listener === $_listener) { + unset($this->listeners[$key]); + } + } + } + + /** + * Flushes all flushable TestListeners. + * + * @since Method available since Release 3.0.0 + */ + public function flushListeners() + { + foreach ($this->listeners as $listener) { + if ($listener instanceof PHPUnit_Util_Printer) { + $listener->flush(); + } + } + } + + /** + * Adds an error to the list of errors. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($e instanceof PHPUnit_Framework_IncompleteTest) { + $this->notImplemented[] = new PHPUnit_Framework_TestFailure( + $test, $e + ); + + $notifyMethod = 'addIncompleteTest'; + } + + else if ($e instanceof PHPUnit_Framework_SkippedTest) { + $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addSkippedTest'; + } + + else { + $this->errors[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addError'; + + if ($this->stopOnFailure) { + $this->stop(); + } + } + + foreach ($this->listeners as $listener) { + $listener->$notifyMethod($test, $e, $time); + } + + $this->lastTestFailed = TRUE; + $this->time += $time; + } + + /** + * Adds a failure to the list of failures. + * The passed in exception caused the failure. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + if ($e instanceof PHPUnit_Framework_IncompleteTest) { + $this->notImplemented[] = new PHPUnit_Framework_TestFailure( + $test, $e + ); + + $notifyMethod = 'addIncompleteTest'; + } + + else if ($e instanceof PHPUnit_Framework_SkippedTest) { + $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addSkippedTest'; + } + + else { + $this->failures[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addFailure'; + + if ($this->stopOnFailure) { + $this->stop(); + } + } + + foreach ($this->listeners as $listener) { + $listener->$notifyMethod($test, $e, $time); + } + + $this->lastTestFailed = TRUE; + $this->time += $time; + } + + /** + * Informs the result that a testsuite will be started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + if ($this->topTestSuite === NULL) { + $this->topTestSuite = $suite; + } + + foreach ($this->listeners as $listener) { + $listener->startTestSuite($suite); + } + } + + /** + * Informs the result that a testsuite was completed. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + foreach ($this->listeners as $listener) { + $listener->endTestSuite($suite); + } + } + + /** + * Informs the result that a test will be started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->lastTestFailed = FALSE; + $this->runTests += count($test); + + foreach ($this->listeners as $listener) { + $listener->startTest($test); + } + } + + /** + * Informs the result that a test was completed. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + foreach ($this->listeners as $listener) { + $listener->endTest($test, $time); + } + + if (!$this->lastTestFailed && $test instanceof PHPUnit_Framework_TestCase) { + $this->passed[get_class($test) . '::' . $test->getName()] = $test->getResult(); + $this->time += $time; + } + } + + /** + * Returns TRUE if no incomplete test occured. + * + * @return boolean + */ + public function allCompletlyImplemented() + { + return $this->notImplementedCount() == 0; + } + + /** + * Gets the number of incomplete tests. + * + * @return integer + */ + public function notImplementedCount() + { + return count($this->notImplemented); + } + + /** + * Returns an Enumeration for the incomplete tests. + * + * @return array + */ + public function notImplemented() + { + return $this->notImplemented; + } + + /** + * Returns TRUE if no test has been skipped. + * + * @return boolean + * @since Method available since Release 3.0.0 + */ + public function noneSkipped() + { + return $this->skippedCount() == 0; + } + + /** + * Gets the number of skipped tests. + * + * @return integer + * @since Method available since Release 3.0.0 + */ + public function skippedCount() + { + return count($this->skipped); + } + + /** + * Returns an Enumeration for the skipped tests. + * + * @return array + * @since Method available since Release 3.0.0 + */ + public function skipped() + { + return $this->skipped; + } + + /** + * Gets the number of detected errors. + * + * @return integer + */ + public function errorCount() + { + return count($this->errors); + } + + /** + * Returns an Enumeration for the errors. + * + * @return array + */ + public function errors() + { + return $this->errors; + } + + /** + * Gets the number of detected failures. + * + * @return integer + */ + public function failureCount() + { + return count($this->failures); + } + + /** + * Returns an Enumeration for the failures. + * + * @return array + */ + public function failures() + { + return $this->failures; + } + + /** + * Returns the names of the tests that have passed. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function passed() + { + return $this->passed; + } + + /** + * Returns the (top) test suite. + * + * @return PHPUnit_Framework_TestSuite + * @since Method available since Release 3.0.0 + */ + public function topTestSuite() + { + return $this->topTestSuite; + } + + /** + * Enables or disables the collection of Code Coverage information. + * + * @param boolean $flag + * @throws InvalidArgumentException + * @since Method available since Release 2.3.0 + */ + public function collectCodeCoverageInformation($flag) + { + if (is_bool($flag)) { + $this->collectCodeCoverageInformation = $flag; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Enables or disables the collection of raw Code Coverage information. + * + * @param boolean $flag + * @throws InvalidArgumentException + * @since Method available since Release 3.4.0 + */ + public function collectRawCodeCoverageInformation($flag) + { + if (is_bool($flag)) { + $this->collectRawCodeCoverageInformation = $flag; + + if ($flag === TRUE) { + $this->collectCodeCoverageInformation = $flag; + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Returns whether code coverage information should be collected. + * + * @return boolean If code coverage should be collected + * @since Method available since Release 3.2.0 + */ + public function getCollectCodeCoverageInformation() + { + return $this->collectCodeCoverageInformation; + } + + /** + * Appends code coverage information to the test + * + * @param PHPUnit_Framework_Test $test + * @param array $data + * @since Method available since Release 3.2.0 + */ + public function appendCodeCoverageInformation(PHPUnit_Framework_Test $test, $data) + { + if ($this->collectRawCodeCoverageInformation) { + $this->codeCoverageInformation[] = array( + 'test' => $test, 'data' => $data + ); + } else { + $deadCode = array(); + $executableCode = array(); + + foreach (array_keys($data) as $file) { + if (PHPUnit_Util_Filter::isFiltered($file, FALSE)) { + unset($data[$file]); + } + } + + $newFilesToCollect = array_diff_key($data, PHPUnit_Util_Filter::getCoveredFiles()); + + if (count($newFilesToCollect) > 0) { + $deadCode = PHPUnit_Util_CodeCoverage::getDeadLines( + $newFilesToCollect + ); + + $executableCode = PHPUnit_Util_CodeCoverage::getExecutableLines( + $newFilesToCollect + ); + + foreach (array_keys($newFilesToCollect) as $file) { + PHPUnit_Util_Filter::addCoveredFile($file); + } + + unset($newFilesToCollect); + } + + if ($test instanceof PHPUnit_Framework_TestCase) { + $linesToBeCovered = PHPUnit_Util_Test::getLinesToBeCovered( + get_class($test), $test->getName() + ); + + if (!empty($linesToBeCovered)) { + $data = array_intersect_key($data, $linesToBeCovered); + + foreach (array_keys($data) as $file) { + $data[$file] = array_intersect_key( + $data[$file], array_flip($linesToBeCovered[$file]) + ); + } + } + } + + $executed = PHPUnit_Util_CodeCoverage::getExecutedLines($data); + unset($data); + + $this->codeCoverageInformation[] = array( + 'test' => $test, + 'files' => $executed, + 'dead' => $deadCode, + 'executable' => $executableCode, + ); + } + } + + /** + * Returns the raw Code Coverage information. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function getRawCodeCoverageInformation() + { + return $this->codeCoverageInformation; + } + + /** + * Returns Code Coverage data per test case. + * + * Format of the result array: + * + * + * array( + * array( + * 'test' => PHPUnit_Framework_Test + * 'files' => array( + * "/tested/code.php" => array( + * linenumber => flag + * ) + * ) + * ) + * ) + * + * + * flag < 0: Line is executable but was not executed. + * flag > 0: Line was executed. + * + * @param boolean $filterTests + * @return array + */ + public function getCodeCoverageInformation($filterTests = TRUE) + { + return PHPUnit_Util_Filter::getFilteredCodeCoverage( + $this->codeCoverageInformation, $filterTests + ); + } + + /** + * Returns unfiltered Code Coverage data per test case. + * Returns data in the same form as getCodeCoverageInformation(). + * + * @return array + */ + public function getUncoveredWhitelistFiles() + { + list(, $missing) = PHPUnit_Util_Filter::getFileCodeCoverageDisposition( + $this->codeCoverageInformation + ); + + return $missing; + } + + /** + * Runs a TestCase. + * + * @param PHPUnit_Framework_Test $test + */ + public function run(PHPUnit_Framework_Test $test) + { + PHPUnit_Framework_Assert::resetCount(); + + $error = FALSE; + $failure = FALSE; + + $this->startTest($test); + + $errorHandlerSet = FALSE; + + if ($this->convertErrorsToExceptions) { + $oldErrorHandler = set_error_handler( + array('PHPUnit_Util_ErrorHandler', 'handleError'), + E_ALL | E_STRICT + ); + + if ($oldErrorHandler === NULL) { + $errorHandlerSet = TRUE; + } else { + restore_error_handler(); + } + } + + if (self::$xdebugLoaded === NULL) { + self::$xdebugLoaded = extension_loaded('xdebug'); + self::$useXdebug = self::$xdebugLoaded; + } + + $useXdebug = self::$useXdebug && + $this->collectCodeCoverageInformation && + !$test instanceof PHPUnit_Extensions_SeleniumTestCase; + + if ($useXdebug) { + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + } + + PHPUnit_Util_Timer::start(); + + try { + $test->runBare(); + } + + catch (PHPUnit_Framework_AssertionFailedError $e) { + $failure = TRUE; + } + + catch (Exception $e) { + $error = TRUE; + } + + $time = PHPUnit_Util_Timer::stop(); + + if ($useXdebug) { + $codeCoverage = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + if (!$test instanceof PHPUnit_Framework_Warning) { + $this->appendCodeCoverageInformation( + $test, $codeCoverage + ); + } + } + + if ($errorHandlerSet === TRUE) { + restore_error_handler(); + } + + $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount()); + + if ($error === TRUE) { + $this->addError($test, $e, $time); + } + + else if ($failure === TRUE) { + $this->addFailure($test, $e, $time); + } + + $this->endTest($test, $time); + } + + /** + * Gets the number of run tests. + * + * @return integer + */ + public function count() + { + return $this->runTests; + } + + /** + * Checks whether the test run should stop. + * + * @return boolean + */ + public function shouldStop() + { + return $this->stop; + } + + /** + * Marks that the test run should stop. + * + */ + public function stop() + { + $this->stop = TRUE; + } + + /** + * Enables or disables the error-to-exception conversion. + * + * @param boolean $flag + * @throws InvalidArgumentException + * @since Method available since Release 3.2.14 + */ + public function convertErrorsToExceptions($flag) + { + if (is_bool($flag)) { + $this->convertErrorsToExceptions = $flag; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Returns the error-to-exception conversion setting. + * + * @return boolean + * @since Method available since Release 3.4.0 + */ + public function getConvertErrorsToExceptions() + { + return $this->convertErrorsToExceptions; + } + + /** + * Enables or disables the stopping when a failure or error occurs. + * + * @param boolean $flag + * @throws InvalidArgumentException + * @since Method available since Release 3.1.0 + */ + public function stopOnFailure($flag) + { + if (is_bool($flag)) { + $this->stopOnFailure = $flag; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Returns the time spent running the tests. + * + * @return float + */ + public function time() + { + return $this->time; + } + + /** + * Returns whether the entire test was successful or not. + * + * @return boolean + */ + public function wasSuccessful() + { + return empty($this->errors) && empty($this->failures); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestSuite.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestSuite.php new file mode 100644 index 00000000..9dc269ee --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestSuite.php @@ -0,0 +1,950 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +require_once 'PHPUnit/Runner/BaseTestRunner.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Fileloader.php'; +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; +require_once 'PHPUnit/Util/Test.php'; +require_once 'PHPUnit/Util/TestSuiteIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestSuite is a composite of Tests. It runs a collection of test cases. + * + * Here is an example using the dynamic test definition. + * + * + * addTest(new MathTest('testPass')); + * ?> + * + * + * Alternatively, a TestSuite can extract the tests to be run automatically. + * To do so you pass a ReflectionClass instance for your + * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite + * constructor. + * + * + * + * + * + * This constructor creates a suite with all the methods starting with + * "test" that take no arguments. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate +{ + /** + * Enable or disable the backup and restoration of the $GLOBALS array. + * + * @var boolean + */ + protected $backupGlobals = NULL; + + /** + * Enable or disable the backup and restoration of static attributes. + * + * @var boolean + */ + protected $backupStaticAttributes = NULL; + + /** + * Fixture that is shared between the tests of this test suite. + * + * @var mixed + */ + protected $sharedFixture; + + /** + * The name of the test suite. + * + * @var string + */ + protected $name = ''; + + /** + * The test groups of the test suite. + * + * @var array + */ + protected $groups = array(); + + /** + * The tests in the test suite. + * + * @var array + */ + protected $tests = array(); + + /** + * The number of tests in the test suite. + * + * @var integer + */ + protected $numTests = -1; + + /** + * @var array + */ + protected static $setUpBeforeClassCalled = array(); + + /** + * @var array + */ + protected static $tearDownAfterClassCalled = array(); + + /** + * Constructs a new TestSuite: + * + * - PHPUnit_Framework_TestSuite() constructs an empty TestSuite. + * + * - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a + * TestSuite from the given class. + * + * - PHPUnit_Framework_TestSuite(ReflectionClass, String) + * constructs a TestSuite from the given class with the given + * name. + * + * - PHPUnit_Framework_TestSuite(String) either constructs a + * TestSuite from the given class (if the passed string is the + * name of an existing class) or constructs an empty TestSuite + * with the given name. + * + * @param mixed $theClass + * @param string $name + * @throws InvalidArgumentException + */ + public function __construct($theClass = '', $name = '') + { + $argumentsValid = FALSE; + + if (is_object($theClass) && + $theClass instanceof ReflectionClass) { + $argumentsValid = TRUE; + } + + else if (is_string($theClass) && $theClass !== '' + && class_exists($theClass, FALSE)) { + $argumentsValid = TRUE; + + if ($name == '') { + $name = $theClass; + } + + $theClass = new ReflectionClass($theClass); + } + + else if (is_string($theClass)) { + $this->setName($theClass); + return; + } + + if (!$argumentsValid) { + throw new InvalidArgumentException; + } + + $filename = $theClass->getFilename(); + + if (strpos($filename, 'eval()') === FALSE) { + PHPUnit_Util_Filter::addFileToFilter(realpath($filename), 'TESTS'); + } + + if ($name != '') { + $this->setName($name); + } else { + $this->setName($theClass->getName()); + } + + $constructor = $theClass->getConstructor(); + + if ($constructor !== NULL && + !$constructor->isPublic()) { + $this->addTest( + self::warning( + sprintf( + 'Class "%s" has no public constructor.', + + $theClass->getName() + ) + ) + ); + + return; + } + + $names = array(); + + foreach ($theClass->getMethods() as $method) { + if (strpos($method->getDeclaringClass()->getName(), 'PHPUnit_') !== 0) { + $this->addTestMethod($theClass, $method, $names); + } + } + + if (empty($this->tests)) { + $this->addTest( + self::warning( + sprintf( + 'No tests found in class "%s".', + + $theClass->getName() + ) + ) + ); + } + } + + /** + * Returns a string representation of the test suite. + * + * @return string + */ + public function toString() + { + return $this->getName(); + } + + /** + * Adds a test to the suite. + * + * @param PHPUnit_Framework_Test $test + * @param array $groups + */ + public function addTest(PHPUnit_Framework_Test $test, $groups = array()) + { + $class = new ReflectionClass($test); + + if (!$class->isAbstract()) { + $this->tests[] = $test; + $this->numTests = -1; + + if ($test instanceof PHPUnit_Framework_TestSuite && + empty($groups)) { + $groups = $test->getGroups(); + } + + if (empty($groups)) { + $groups = array('__nogroup__'); + } + + foreach ($groups as $group) { + if (!isset($this->groups[$group])) { + $this->groups[$group] = array($test); + } else { + $this->groups[$group][] = $test; + } + } + } + } + + /** + * Adds the tests from the given class to the suite. + * + * @param mixed $testClass + * @throws InvalidArgumentException + */ + public function addTestSuite($testClass) + { + if (is_string($testClass) && class_exists($testClass)) { + $testClass = new ReflectionClass($testClass); + } + + if (!is_object($testClass)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'class name or object' + ); + } + + if ($testClass instanceof PHPUnit_Framework_TestSuite) { + $this->addTest($testClass); + } + + else if ($testClass instanceof ReflectionClass) { + $suiteMethod = FALSE; + + if (!$testClass->isAbstract()) { + if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { + $method = $testClass->getMethod( + PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME + ); + + if ($method->isStatic()) { + $this->addTest( + $method->invoke(NULL, $testClass->getName()) + ); + + $suiteMethod = TRUE; + } + } + } + + if (!$suiteMethod && !$testClass->isAbstract()) { + $this->addTest(new PHPUnit_Framework_TestSuite($testClass)); + } + } + + else { + throw new InvalidArgumentException; + } + } + + /** + * Wraps both addTest() and addTestSuite + * as well as the separate import statements for the user's convenience. + * + * If the named file cannot be read or there are no new tests that can be + * added, a PHPUnit_Framework_Warning will be created instead, + * leaving the current test run untouched. + * + * @param string $filename + * @param boolean $syntaxCheck + * @param array $phptOptions Array with ini settings for the php instance + * run, key being the name if the setting, + * value the ini value. + * @throws InvalidArgumentException + * @since Method available since Release 2.3.0 + * @author Stefano F. Rausch + */ + public function addTestFile($filename, $syntaxCheck = FALSE, $phptOptions = array()) + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (file_exists($filename) && substr($filename, -5) == '.phpt') { + require_once 'PHPUnit/Extensions/PhptTestCase.php'; + + $this->addTest( + new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions) + ); + + return; + } + + if (!file_exists($filename)) { + $includePaths = explode(PATH_SEPARATOR, get_include_path()); + + foreach ($includePaths as $includePath) { + $file = $includePath . DIRECTORY_SEPARATOR . $filename; + + if (file_exists($file)) { + $filename = $file; + break; + } + } + } + + PHPUnit_Util_Class::collectStart(); + PHPUnit_Util_Fileloader::checkAndLoad($filename, $syntaxCheck); + $newClasses = PHPUnit_Util_Class::collectEnd(); + $baseName = str_replace('.php', '', basename($filename)); + + foreach ($newClasses as $className) { + if (substr($className, 0 - strlen($baseName)) == $baseName) { + $newClasses = array($className); + break; + } + } + + $testsFound = FALSE; + + foreach ($newClasses as $className) { + $class = new ReflectionClass($className); + + if (!$class->isAbstract()) { + if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { + $method = $class->getMethod( + PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME + ); + + if ($method->isStatic()) { + $this->addTest($method->invoke(NULL, $className)); + + $testsFound = TRUE; + } + } + + else if ($class->implementsInterface('PHPUnit_Framework_Test')) { + $this->addTestSuite($class); + + $testsFound = TRUE; + } + } + } + + $this->numTests = -1; + } + + /** + * Wrapper for addTestFile() that adds multiple test files. + * + * @param array|Iterator $filenames + * @throws InvalidArgumentException + * @since Method available since Release 2.3.0 + */ + public function addTestFiles($filenames, $syntaxCheck = FALSE) + { + if (!(is_array($filenames) || + (is_object($filenames) && $filenames instanceof Iterator))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'array or iterator' + ); + } + + foreach ($filenames as $filename) { + $this->addTestFile((string)$filename, $syntaxCheck); + } + } + + /** + * Counts the number of test cases that will be run by this test. + * + * @return integer + */ + public function count() + { + if ($this->numTests > -1) { + return $this->numTests; + } + + $this->numTests = 0; + + foreach ($this->tests as $test) { + $this->numTests += count($test); + } + + return $this->numTests; + } + + /** + * @param ReflectionClass $theClass + * @param string $name + * @param array $classGroups + * @return PHPUnit_Framework_Test + */ + public static function createTest(ReflectionClass $theClass, $name, array $classGroups = array()) + { + $className = $theClass->getName(); + + if (!$theClass->isInstantiable()) { + return self::warning( + sprintf('Cannot instantiate class "%s".', $className) + ); + } + + $classDocComment = $theClass->getDocComment(); + $method = new ReflectionMethod($className, $name); + $methodDocComment = $method->getDocComment(); + $backupSettings = PHPUnit_Util_Test::getBackupSettings( + $className, $name + ); + $preserveGlobalState = PHPUnit_Util_Test::getPreserveGlobalStateSettings( + $className, $name + ); + $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings( + $className, $name + ); + + $constructor = $theClass->getConstructor(); + + if ($constructor !== NULL) { + $parameters = $constructor->getParameters(); + + // TestCase() or TestCase($name) + if (count($parameters) < 2) { + $test = new $className; + } + + // TestCase($name, $data) + else { + $data = PHPUnit_Util_Test::getProvidedData($className, $name); + $groups = PHPUnit_Util_Test::getGroups($className, $name); + + if (is_array($data) || $data instanceof Iterator) { + $test = new PHPUnit_Framework_TestSuite_DataProvider( + $className . '::' . $name + ); + + foreach ($data as $_dataName => $_data) { + $_test = new $className($name, $_data, $_dataName); + + if ($runTestInSeparateProcess) { + $_test->setRunTestInSeparateProcess(TRUE); + + if ($preserveGlobalState !== NULL) { + $_test->setPreserveGlobalState($preserveGlobalState); + } + } + + if ($backupSettings['backupGlobals'] !== NULL) { + $_test->setBackupGlobals( + $backupSettings['backupGlobals'] + ); + } + + if ($backupSettings['backupStaticAttributes'] !== NULL) { + $_test->setBackupStaticAttributes( + $backupSettings['backupStaticAttributes'] + ); + } + + $test->addTest($_test, $groups); + } + } else { + $test = new $className; + } + } + } + + if ($test instanceof PHPUnit_Framework_TestCase) { + $test->setName($name); + + if ($runTestInSeparateProcess) { + $test->setRunTestInSeparateProcess(TRUE); + + if ($preserveGlobalState !== NULL) { + $test->setPreserveGlobalState($preserveGlobalState); + } + } + + if ($backupSettings['backupGlobals'] !== NULL) { + $test->setBackupGlobals($backupSettings['backupGlobals']); + } + + if ($backupSettings['backupStaticAttributes'] !== NULL) { + $test->setBackupStaticAttributes( + $backupSettings['backupStaticAttributes'] + ); + } + } + + return $test; + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * Returns the name of the suite. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Returns the test groups of the suite. + * + * @return array + * @since Method available since Release 3.2.0 + */ + public function getGroups() + { + return array_keys($this->groups); + } + + /** + * Runs the tests and collects their result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + * @param mixed $filter + * @param array $groups + * @param array $excludeGroups + * @param boolean $processIsolation + * @return PHPUnit_Framework_TestResult + * @throws InvalidArgumentException + */ + public function run(PHPUnit_Framework_TestResult $result = NULL, $filter = FALSE, array $groups = array(), array $excludeGroups = array(), $processIsolation = FALSE) + { + if ($result === NULL) { + $result = $this->createResult(); + } + + try { + $this->setUp(); + } + + catch (PHPUnit_Framework_SkippedTestSuiteError $e) { + $numTests = count($this); + + for ($i = 0; $i < $numTests; $i++) { + $result->addFailure($this, $e, 0); + } + + return $result; + } + + $result->startTestSuite($this); + + if (empty($groups)) { + $tests = $this->tests; + } else { + $tests = new SplObjectStorage; + + foreach ($groups as $group) { + if (isset($this->groups[$group])) { + foreach ($this->groups[$group] as $test) { + $tests->attach($test); + } + } + } + } + + $currentClass = ''; + + foreach ($tests as $test) { + if ($result->shouldStop()) { + break; + } + + if ($test instanceof PHPUnit_Framework_TestSuite) { + $test->setBackupGlobals($this->backupGlobals); + $test->setBackupStaticAttributes($this->backupStaticAttributes); + $test->setSharedFixture($this->sharedFixture); + + $test->run( + $result, $filter, $groups, $excludeGroups, $processIsolation + ); + } else { + $runTest = TRUE; + + if ($filter !== FALSE ) { + $tmp = PHPUnit_Util_Test::describe($test, FALSE); + + if ($tmp[0] != '') { + $name = join('::', $tmp); + } else { + $name = $tmp[1]; + } + + if (preg_match($filter, $name) == 0) { + $runTest = FALSE; + } + } + + if ($runTest && !empty($excludeGroups)) { + foreach ($this->groups as $_group => $_tests) { + if (in_array($_group, $excludeGroups)) { + foreach ($_tests as $_test) { + if ($test === $_test) { + $runTest = FALSE; + break 2; + } + } + } + } + } + + if ($runTest) { + if ($test instanceof PHPUnit_Framework_TestCase) { + $test->setBackupGlobals($this->backupGlobals); + $test->setBackupStaticAttributes( + $this->backupStaticAttributes + ); + $test->setSharedFixture($this->sharedFixture); + $test->setRunTestInSeparateProcess($processIsolation); + + $_currentClass = get_class($test); + + if ($_currentClass != $currentClass) { + if ($currentClass != '') { + call_user_func(array($currentClass, 'tearDownAfterClass')); + self::$tearDownAfterClassCalled[$currentClass] = TRUE; + } + + $currentClass = $_currentClass; + } + + if (!isset(self::$setUpBeforeClassCalled[$currentClass])) { + call_user_func(array($currentClass, 'setUpBeforeClass')); + self::$setUpBeforeClassCalled[$currentClass] = TRUE; + } + } + + $this->runTest($test, $result); + } + } + } + + if ($currentClass != '' && + !isset(self::$tearDownAfterClassCalled[$currentClass])) { + call_user_func(array($currentClass, 'tearDownAfterClass')); + self::$tearDownAfterClassCalled[$currentClass] = TRUE; + } + + $result->endTestSuite($this); + $this->tearDown(); + + return $result; + } + + /** + * Runs a test. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_TestResult $testResult + */ + public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result) + { + $test->run($result); + } + + /** + * Sets the name of the suite. + * + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Returns the test at the given index. + * + * @param integer + * @return PHPUnit_Framework_Test + */ + public function testAt($index) + { + if (isset($this->tests[$index])) { + return $this->tests[$index]; + } else { + return FALSE; + } + } + + /** + * Returns the tests as an enumeration. + * + * @return array + */ + public function tests() + { + return $this->tests; + } + + /** + * Mark the test suite as skipped. + * + * @param string $message + * @throws PHPUnit_Framework_SkippedTestSuiteError + * @since Method available since Release 3.0.0 + */ + public function markTestSuiteSkipped($message = '') + { + throw new PHPUnit_Framework_SkippedTestSuiteError($message); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param array $names + */ + protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method, array &$names) + { + $name = $method->getName(); + + if (in_array($name, $names)) { + return; + } + + if ($this->isPublicTestMethod($method)) { + $names[] = $name; + + $test = self::createTest($class, $name); + + if ($test instanceof PHPUnit_Framework_TestCase || + $test instanceof PHPUnit_Framework_TestSuite_DataProvider) { + $test->setDependencies( + PHPUnit_Util_Test::getDependencies($class->getName(), $name) + ); + } + + $this->addTest($test, PHPUnit_Util_Test::getGroups( + $class->getName(), $name) + ); + } + + else if ($this->isTestMethod($method)) { + $this->addTest( + self::warning( + sprintf( + 'Test method "%s" is not public.', + + $name + ) + ) + ); + } + } + + /** + * @param ReflectionMethod $method + * @return boolean + */ + public static function isPublicTestMethod(ReflectionMethod $method) + { + return (self::isTestMethod($method) && $method->isPublic()); + } + + /** + * @param ReflectionMethod $method + * @return boolean + */ + public static function isTestMethod(ReflectionMethod $method) + { + if (strpos($method->name, 'test') === 0) { + return TRUE; + } + + // @scenario on TestCase::testMethod() + // @test on TestCase::testMethod() + return strpos($method->getDocComment(), '@test') !== FALSE || + strpos($method->getDocComment(), '@scenario') !== FALSE; + } + + /** + * @param string $message + * @return PHPUnit_Framework_Warning + */ + protected static function warning($message) + { + return new PHPUnit_Framework_Warning($message); + } + + /** + * @param boolean $backupGlobals + * @since Method available since Release 3.3.0 + */ + public function setBackupGlobals($backupGlobals) + { + if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * @param boolean $backupStaticAttributes + * @since Method available since Release 3.4.0 + */ + public function setBackupStaticAttributes($backupStaticAttributes) + { + if (is_null($this->backupStaticAttributes) && + is_bool($backupStaticAttributes)) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * Sets the shared fixture for the tests of this test suite. + * + * @param mixed $sharedFixture + * @since Method available since Release 3.1.0 + */ + public function setSharedFixture($sharedFixture) + { + $this->sharedFixture = $sharedFixture; + } + + /** + * Returns an iterator for this test suite. + * + * @return RecursiveIteratorIterator + * @since Method available since Release 3.1.0 + */ + public function getIterator() + { + return new RecursiveIteratorIterator( + new PHPUnit_Util_TestSuiteIterator($this) + ); + } + + /** + * Template Method that is called before the tests + * of this test suite are run. + * + * @since Method available since Release 3.1.0 + */ + protected function setUp() + { + } + + /** + * Template Method that is called after the tests + * of this test suite have finished running. + * + * @since Method available since Release 3.1.0 + */ + protected function tearDown() + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestSuite/DataProvider.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestSuite/DataProvider.php new file mode 100644 index 00000000..79367969 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/TestSuite/DataProvider.php @@ -0,0 +1,77 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_TestSuite_DataProvider extends PHPUnit_Framework_TestSuite +{ + /** + * Sets the dependencies of a TestCase. + * + * @param array $dependencies + */ + public function setDependencies(array $dependencies) + { + foreach ($this->tests as $test) { + $test->setDependencies($dependencies); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Warning.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Warning.php new file mode 100644 index 00000000..862cfb52 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Framework/Warning.php @@ -0,0 +1,106 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A warning. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_Warning extends PHPUnit_Framework_TestCase +{ + /** + * @var string + */ + protected $message = ''; + + /** + * @param string $message + */ + public function __construct($message = '') + { + $this->message = $message; + parent::__construct('Warning'); + } + + /** + * @throws RuntimeException + */ + protected function runTest() + { + $this->fail($this->message); + } + + /** + * @return string + * @since Method available since Release 3.0.0 + */ + public function getMessage() + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + * + * @return string + * @since Method available since Release 3.4.0 + */ + public function toString() + { + return 'Warning'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/BaseTestRunner.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/BaseTestRunner.php new file mode 100644 index 00000000..46a3b4b0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/BaseTestRunner.php @@ -0,0 +1,191 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Runner/StandardTestSuiteLoader.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Base class for all test runners. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + * @abstract + */ +abstract class PHPUnit_Runner_BaseTestRunner +{ + const STATUS_PASSED = 0; + const STATUS_SKIPPED = 1; + const STATUS_INCOMPLETE = 2; + const STATUS_FAILURE = 3; + const STATUS_ERROR = 4; + const SUITE_METHODNAME = 'suite'; + + /** + * Returns the loader to be used. + * + * @return PHPUnit_Runner_TestSuiteLoader + */ + public function getLoader() + { + return new PHPUnit_Runner_StandardTestSuiteLoader; + } + + /** + * Returns the Test corresponding to the given suite. + * This is a template method, subclasses override + * the runFailed() and clearStatus() methods. + * + * @param string $suiteClassName + * @param string $suiteClassFile + * @param boolean $syntaxCheck + * @return PHPUnit_Framework_Test + */ + public function getTest($suiteClassName, $suiteClassFile = '', $syntaxCheck = FALSE) + { + if (is_dir($suiteClassName) && + !is_file($suiteClassName . '.php') && empty($suiteClassFile)) { + $testCollector = new PHPUnit_Runner_IncludePathTestCollector( + array($suiteClassName) + ); + + $suite = new PHPUnit_Framework_TestSuite($suiteClassName); + $suite->addTestFiles($testCollector->collectTests(), $syntaxCheck); + + return $suite; + } + + try { + $testClass = $this->loadSuiteClass( + $suiteClassName, $suiteClassFile, $syntaxCheck + ); + } + + catch (Exception $e) { + $this->runFailed($e->getMessage()); + return NULL; + } + + try { + $suiteMethod = $testClass->getMethod(self::SUITE_METHODNAME); + + if (!$suiteMethod->isStatic()) { + $this->runFailed( + 'suite() method must be static.' + ); + + return NULL; + } + + try { + $test = $suiteMethod->invoke(NULL, $testClass->getName()); + } + + catch (ReflectionException $e) { + $this->runFailed( + sprintf( + "Failed to invoke suite() method.\n%s", + + $e->getMessage() + ) + ); + + return NULL; + } + } + + catch (ReflectionException $e) { + $test = new PHPUnit_Framework_TestSuite($testClass); + } + + $this->clearStatus(); + + return $test; + } + + /** + * Returns the loaded ReflectionClass for a suite name. + * + * @param string $suiteClassName + * @param string $suiteClassFile + * @param boolean $syntaxCheck + * @return ReflectionClass + */ + protected function loadSuiteClass($suiteClassName, $suiteClassFile = '', $syntaxCheck = FALSE) + { + $loader = $this->getLoader(); + + if ($loader instanceof PHPUnit_Runner_StandardTestSuiteLoader) { + return $loader->load($suiteClassName, $suiteClassFile, $syntaxCheck); + } else { + return $loader->load($suiteClassName, $suiteClassFile); + } + } + + /** + * Clears the status message. + * + */ + protected function clearStatus() + { + } + + /** + * Override to define how to handle a failed loading of + * a test suite. + * + * @param string $message + */ + abstract protected function runFailed($message); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/IncludePathTestCollector.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/IncludePathTestCollector.php new file mode 100644 index 00000000..9383c63e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/IncludePathTestCollector.php @@ -0,0 +1,160 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.1.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Runner/TestCollector.php'; +require_once 'PHPUnit/Util/FilterIterator.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A test collector that collects tests from one or more directories + * recursively. If no directories are specified, the include_path is searched. + * + * + * $testCollector = new PHPUnit_Runner_IncludePathTestCollector( + * array('/path/to/*Test.php files') + * ); + * + * $suite = new PHPUnit_Framework_TestSuite('My Test Suite'); + * $suite->addTestFiles($testCollector->collectTests()); + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Runner_IncludePathTestCollector implements PHPUnit_Runner_TestCollector +{ + /** + * @var string + */ + protected $filterIterator; + + /** + * @var array + */ + protected $paths; + + /** + * @var mixed + */ + protected $suffixes; + + /** + * @var mixed + */ + protected $prefixes; + + /** + * @param array $paths + * @param mixed $suffixes + * @param mixed $prefixes + */ + public function __construct(array $paths = array(), $suffixes = array('Test.php', '.phpt'), $prefixes = array()) + { + if (!empty($paths)) { + $this->paths = $paths; + } else { + $this->paths = explode(PATH_SEPARATOR, get_include_path()); + } + + $this->suffixes = $suffixes; + $this->prefixes = $prefixes; + } + + /** + * @return array + */ + public function collectTests() + { + $pathIterator = new AppendIterator; + $result = array(); + + foreach ($this->paths as $path) { + $pathIterator->append( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path) + ) + ); + } + + $filterIterator = new PHPUnit_Util_FilterIterator( + $pathIterator, $this->suffixes, $this->prefixes + ); + + if ($this->filterIterator !== NULL) { + $class = new ReflectionClass($this->filterIterator); + $filterIterator = $class->newInstance($filterIterator); + } + + return $filterIterator; + } + + /** + * Adds a FilterIterator to filter the source files to be collected. + * + * @param string $filterIterator + * @throws InvalidArgumentException + */ + public function setFilterIterator($filterIterator) + { + if (is_string($filterIterator) && class_exists($filterIterator)) { + $class = new ReflectionClass($filterIterator); + + if ($class->isSubclassOf('FilterIterator')) { + $this->filterIterator = $filterIterator; + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/StandardTestSuiteLoader.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/StandardTestSuiteLoader.php new file mode 100644 index 00000000..5acc9e25 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/StandardTestSuiteLoader.php @@ -0,0 +1,176 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Runner/TestSuiteLoader.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Fileloader.php'; +require_once 'PHPUnit/Util/Filesystem.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * The standard test suite loader. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Runner_StandardTestSuiteLoader implements PHPUnit_Runner_TestSuiteLoader +{ + /** + * @param string $suiteClassName + * @param string $suiteClassFile + * @param boolean $syntaxCheck + * @return ReflectionClass + * @throws RuntimeException + */ + public function load($suiteClassName, $suiteClassFile = '', $syntaxCheck = FALSE) + { + $suiteClassName = str_replace('.php', '', $suiteClassName); + + if (empty($suiteClassFile)) { + $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename( + $suiteClassName + ); + } + + if (!class_exists($suiteClassName, FALSE)) { + if (!file_exists($suiteClassFile)) { + $includePaths = explode(PATH_SEPARATOR, get_include_path()); + + foreach ($includePaths as $includePath) { + $file = $includePath . DIRECTORY_SEPARATOR . + $suiteClassFile; + + if (file_exists($file)) { + $suiteClassFile = $file; + break; + } + } + } + + PHPUnit_Util_Class::collectStart(); + PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile, $syntaxCheck); + $loadedClasses = PHPUnit_Util_Class::collectEnd(); + } + + if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) { + $offset = 0 - strlen($suiteClassName); + + foreach ($loadedClasses as $loadedClass) { + if (substr($loadedClass, $offset) === $suiteClassName) { + $suiteClassName = $loadedClass; + break; + } + } + } + + if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) { + $testCaseClass = 'PHPUnit_Framework_TestCase'; + + foreach ($loadedClasses as $loadedClass) { + $class = new ReflectionClass($loadedClass); + $classFile = $class->getFileName(); + + if ($class->isSubclassOf($testCaseClass) && + !$class->isAbstract()) { + $suiteClassName = $loadedClass; + $testCaseClass = $loadedClass; + + if ($classFile == realpath($suiteClassFile)) { + break; + } + } + + if ($class->hasMethod('suite')) { + $method = $class->getMethod('suite'); + + if (!$method->isAbstract() && + $method->isPublic() && + $method->isStatic()) { + $suiteClassName = $loadedClass; + + if ($classFile == realpath($suiteClassFile)) { + break; + } + } + } + } + } + + if (class_exists($suiteClassName, FALSE)) { + $class = new ReflectionClass($suiteClassName); + + if ($class->getFileName() == realpath($suiteClassFile)) { + return $class; + } + } + + throw new PHPUnit_Framework_Exception( + sprintf( + 'Class %s could not be found in %s.', + + $suiteClassName, + $suiteClassFile + ) + ); + } + + /** + * @param ReflectionClass $aClass + * @return ReflectionClass + */ + public function reload(ReflectionClass $aClass) + { + return $aClass; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/TestCollector.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/TestCollector.php new file mode 100644 index 00000000..b03b7737 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/TestCollector.php @@ -0,0 +1,70 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Collects Test class names to be presented + * by the TestSelector. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Runner_TestCollector +{ + /** + * @return array + */ + public function collectTests(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/TestSuiteLoader.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/TestSuiteLoader.php new file mode 100644 index 00000000..0b834999 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/TestSuiteLoader.php @@ -0,0 +1,77 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * An interface to define how a test suite should be loaded. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Runner_TestSuiteLoader +{ + /** + * @param string $suiteClassName + * @param string $suiteClassFile + * @return ReflectionClass + */ + public function load($suiteClassName, $suiteClassFile = ''); + + /** + * @param ReflectionClass $aClass + * @return ReflectionClass + */ + public function reload(ReflectionClass $aClass); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/Version.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/Version.php new file mode 100644 index 00000000..f90b24cc --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Runner/Version.php @@ -0,0 +1,82 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * This class defines the current version of PHPUnit. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Runner_Version +{ + /** + * Returns the current version of PHPUnit. + * + * @return string + */ + public static function id() + { + return '3.4.9'; + } + + /** + * @return string + */ + public static function getVersionString() + { + return 'PHPUnit 3.4.9 by Sebastian Bergmann.'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccount/BankAccount.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccount/BankAccount.php new file mode 100644 index 00000000..539d67bf --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccount/BankAccount.php @@ -0,0 +1,120 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +class BankAccountException extends RuntimeException {} + +/** + * A bank account. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class BankAccount +{ + /** + * The bank account's balance. + * + * @var float + */ + protected $balance = 0; + + /** + * Returns the bank account's balance. + * + * @return float + */ + public function getBalance() + { + return $this->balance; + } + + /** + * Sets the bank account's balance. + * + * @param float $balance + * @throws BankAccountException + */ + protected function setBalance($balance) + { + if ($balance >= 0) { + $this->balance = $balance; + } else { + throw new BankAccountException; + } + } + + /** + * Deposits an amount of money to the bank account. + * + * @param float $balance + * @throws BankAccountException + */ + public function depositMoney($balance) + { + $this->setBalance($this->getBalance() + $balance); + + return $this->getBalance(); + } + + /** + * Withdraws an amount of money from the bank account. + * + * @param float $balance + * @throws BankAccountException + */ + public function withdrawMoney($balance) + { + $this->setBalance($this->getBalance() - $balance); + + return $this->getBalance(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccount/BankAccountTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccount/BankAccountTest.php new file mode 100644 index 00000000..22dec538 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccount/BankAccountTest.php @@ -0,0 +1,137 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Framework/TestCase.php'; +require_once 'BankAccount.php'; + +/** + * Tests for the BankAccount class. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class BankAccountTest extends PHPUnit_Framework_TestCase +{ + protected $ba; + + protected function setUp() + { + $this->ba = new BankAccount; + } + + /** + * @covers BankAccount::getBalance + * @group balanceIsInitiallyZero + * @group specification + */ + public function testBalanceIsInitiallyZero() + { + $this->assertEquals(0, $this->ba->getBalance()); + } + + /** + * @covers BankAccount::withdrawMoney + * @group balanceCannotBecomeNegative + * @group specification + */ + public function testBalanceCannotBecomeNegative() + { + try { + $this->ba->withdrawMoney(1); + } + + catch (BankAccountException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /** + * @covers BankAccount::depositMoney + * @group balanceCannotBecomeNegative + * @group specification + */ + public function testBalanceCannotBecomeNegative2() + { + try { + $this->ba->depositMoney(-1); + } + + catch (BankAccountException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /** + * @covers BankAccount::getBalance + * @covers BankAccount::depositMoney + * @covers BankAccount::withdrawMoney + * @group balanceCannotBecomeNegative + */ +/* + public function testDepositWithdrawMoney() + { + $this->assertEquals(0, $this->ba->getBalance()); + $this->ba->depositMoney(1); + $this->assertEquals(1, $this->ba->getBalance()); + $this->ba->withdrawMoney(1); + $this->assertEquals(0, $this->ba->getBalance()); + } +*/ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccount.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccount.php new file mode 100644 index 00000000..ab5218e7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccount.php @@ -0,0 +1,209 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +class BankAccountException extends RuntimeException {} + +/** + * A bank account. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class BankAccount +{ + /** + * The bank account's balance. + * + * @var float + */ + protected $balance = 0; + + /** + * The bank account's number. + * + * @var float + */ + protected $accountNumber = 0; + + /** + * The PDO connection used to store and retrieve bank account information. + * + * @var PDO + */ + protected $pdo; + + public function __construct($accountNumber, PDO $pdo) + { + $this->accountNumber = $accountNumber; + $this->pdo = $pdo; + + $this->loadAccount(); + } + + /** + * Returns the bank account's balance. + * + * @return float + */ + public function getBalance() + { + return $this->balance; + } + + /** + * Sets the bank account's balance. + * + * @param float $balance + * @throws BankAccountException + */ + protected function setBalance($balance) + { + if ($balance >= 0) { + $this->balance = $balance; + $this->updateAccount(); + } else { + throw new BankAccountException; + } + } + + /** + * Returns the bank account's number. + * + * @return float + */ + public function getAccountNumber() + { + return $this->accountNumber; + } + + /** + * Deposits an amount of money to the bank account. + * + * @param float $balance + * @throws BankAccountException + */ + public function depositMoney($balance) + { + $this->setBalance($this->getBalance() + $balance); + + return $this->getBalance(); + } + + /** + * Withdraws an amount of money from the bank account. + * + * @param float $balance + * @throws BankAccountException + */ + public function withdrawMoney($balance) + { + $this->setBalance($this->getBalance() - $balance); + + return $this->getBalance(); + } + + /** + * Loads account information from the database. + */ + protected function loadAccount() + { + $query = "SELECT * FROM bank_account WHERE account_number = ?"; + + $statement = $this->pdo->prepare($query); + + $statement->execute(array($this->accountNumber)); + + if ($bankAccountInfo = $statement->fetch(PDO::FETCH_ASSOC)) + { + $this->balance = $bankAccountInfo['balance']; + } + else + { + $this->balance = 0; + $this->addAccount(); + } + } + + /** + * Saves account information to the database. + */ + protected function updateAccount() + { + $query = "UPDATE bank_account SET balance = ? WHERE account_number = ?"; + + $statement = $this->pdo->prepare($query); + $statement->execute(array($this->balance, $this->accountNumber)); + } + + /** + * Adds account information to the database. + */ + protected function addAccount() + { + $query = "INSERT INTO bank_account (balance, account_number) VALUES(?, ?)"; + + $statement = $this->pdo->prepare($query); + $statement->execute(array($this->balance, $this->accountNumber)); + } + + static public function createTable(PDO $pdo) + { + $query = " + CREATE TABLE bank_account ( + account_number VARCHAR(17) PRIMARY KEY, + balance DECIMAL(9,2) NOT NULL DEFAULT 0 + ); + "; + + $pdo->query($query); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccountDBTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccountDBTest.php new file mode 100644 index 00000000..4e37d78b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccountDBTest.php @@ -0,0 +1,149 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Extensions/Database/TestCase.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php'; + +require_once 'BankAccount.php'; + +/** + * Tests for the BankAccount class. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class BankAccountDBTest extends PHPUnit_Extensions_Database_TestCase +{ + protected $pdo; + + public function __construct() + { + $this->pdo = new PDO('sqlite::memory:'); + BankAccount::createTable($this->pdo); + } + + /** + * Returns the test database connection. + * + * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected function getConnection() + { + return $this->createDefaultDBConnection($this->pdo, 'sqlite'); + } + + protected function getDataSet() + { + return $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml'); + } + + public function testNewAccountBalanceIsInitiallyZero() + { + $bank_account = new BankAccount('12345678912345678', $this->pdo); + $this->assertEquals(0, $bank_account->getBalance()); + } + + public function testOldAccountInfoInitiallySet() + { + $bank_account = new BankAccount('15934903649620486', $this->pdo); + $this->assertEquals(100, $bank_account->getBalance()); + $this->assertEquals('15934903649620486', $bank_account->getAccountNumber()); + + $bank_account = new BankAccount('15936487230215067', $this->pdo); + $this->assertEquals(1216, $bank_account->getBalance()); + $this->assertEquals('15936487230215067', $bank_account->getAccountNumber()); + + $bank_account = new BankAccount('12348612357236185', $this->pdo); + $this->assertEquals(89, $bank_account->getBalance()); + $this->assertEquals('12348612357236185', $bank_account->getAccountNumber()); + } + + public function testAccountBalanceDeposits() + { + $bank_account = new BankAccount('15934903649620486', $this->pdo); + $bank_account->depositMoney(100); + + $bank_account = new BankAccount('15936487230215067', $this->pdo); + $bank_account->depositMoney(230); + + $bank_account = new BankAccount('12348612357236185', $this->pdo); + $bank_account->depositMoney(24); + + $xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-deposits.xml'); + $this->assertDataSetsEqual($xml_dataset, $this->getConnection()->createDataSet()); + } + + public function testAccountBalanceWithdrawals() + { + $bank_account = new BankAccount('15934903649620486', $this->pdo); + $bank_account->withdrawMoney(100); + + $bank_account = new BankAccount('15936487230215067', $this->pdo); + $bank_account->withdrawMoney(230); + + $bank_account = new BankAccount('12348612357236185', $this->pdo); + $bank_account->withdrawMoney(24); + + $xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-withdrawals.xml'); + $this->assertDataSetsEqual($xml_dataset, $this->getConnection()->createDataSet()); + } + + public function testNewAccountCreation() + { + $bank_account = new BankAccount('12345678912345678', $this->pdo); + + $xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-new-account.xml'); + $this->assertDataSetsEqual($xml_dataset, $this->getConnection()->createDataSet()); + } + /* + */ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccountDBTestMySQL.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccountDBTestMySQL.php new file mode 100644 index 00000000..b0dde3c9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/BankAccountDBTestMySQL.php @@ -0,0 +1,149 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Extensions/Database/TestCase.php'; +require_once 'PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php'; + +require_once 'BankAccount.php'; + +/** + * Tests for the BankAccount class. + * + * @category Testing + * @package PHPUnit + * @author Mike Lively + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class BankAccountDBTestMySQL extends PHPUnit_Extensions_Database_TestCase +{ + protected $pdo; + + public function __construct() + { + $this->pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'selkirk'); + BankAccount::createTable($this->pdo); + } + + /** + * Returns the test database connection. + * + * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected function getConnection() + { + return $this->createDefaultDBConnection($this->pdo, 'test'); + } + + protected function getDataSet() + { + return $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-seed.xml'); + } + + public function testNewAccountBalanceIsInitiallyZero() + { + $bank_account = new BankAccount('12345678912345678', $this->pdo); + $this->assertEquals(0, $bank_account->getBalance()); + } + + public function testOldAccountInfoInitiallySet() + { + $bank_account = new BankAccount('15934903649620486', $this->pdo); + $this->assertEquals(100, $bank_account->getBalance()); + $this->assertEquals('15934903649620486', $bank_account->getAccountNumber()); + + $bank_account = new BankAccount('15936487230215067', $this->pdo); + $this->assertEquals(1216, $bank_account->getBalance()); + $this->assertEquals('15936487230215067', $bank_account->getAccountNumber()); + + $bank_account = new BankAccount('12348612357236185', $this->pdo); + $this->assertEquals(89, $bank_account->getBalance()); + $this->assertEquals('12348612357236185', $bank_account->getAccountNumber()); + } + + public function testAccountBalanceDeposits() + { + $bank_account = new BankAccount('15934903649620486', $this->pdo); + $bank_account->depositMoney(100); + + $bank_account = new BankAccount('15936487230215067', $this->pdo); + $bank_account->depositMoney(230); + + $bank_account = new BankAccount('12348612357236185', $this->pdo); + $bank_account->depositMoney(24); + + $xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-deposits.xml'); + $this->assertDataSetsEqual($xml_dataset, $this->getConnection()->createDataSet()); + } + + public function testAccountBalanceWithdrawals() + { + $bank_account = new BankAccount('15934903649620486', $this->pdo); + $bank_account->withdrawMoney(100); + + $bank_account = new BankAccount('15936487230215067', $this->pdo); + $bank_account->withdrawMoney(230); + + $bank_account = new BankAccount('12348612357236185', $this->pdo); + $bank_account->withdrawMoney(24); + + $xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-withdrawals.xml'); + $this->assertDataSetsEqual($xml_dataset, $this->getConnection()->createDataSet()); + } + + public function testNewAccountCreation() + { + $bank_account = new BankAccount('12345678912345678', $this->pdo); + + $xml_dataset = $this->createFlatXMLDataSet(dirname(__FILE__).'/_files/bank-account-after-new-account.xml'); + $this->assertDataSetsEqual($xml_dataset, $this->getConnection()->createDataSet()); + } + /* + */ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-deposits.xml b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-deposits.xml new file mode 100644 index 00000000..ab4f178c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-deposits.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-new-account.xml b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-new-account.xml new file mode 100644 index 00000000..67517ab4 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-new-account.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-withdrawals.xml b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-withdrawals.xml new file mode 100644 index 00000000..bc1c0b68 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-after-withdrawals.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-seed.xml b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-seed.xml new file mode 100644 index 00000000..deb2eb98 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BankAccountDB/_files/bank-account-seed.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGame.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGame.php new file mode 100644 index 00000000..566738be --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGame.php @@ -0,0 +1,106 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +class BowlingGame +{ + protected $rolls = array(); + + public function roll($pins) + { + $this->rolls[] = $pins; + } + + protected function isSpare($frameIndex) + { + return $this->sumOfPinsInFrame($frameIndex) == 10; + } + + protected function isStrike($frameIndex) + { + return $this->rolls[$frameIndex] == 10; + } + + protected function sumOfPinsInFrame($frameIndex) + { + return $this->rolls[$frameIndex] + + $this->rolls[$frameIndex + 1]; + } + + protected function spareBonus($frameIndex) + { + return $this->rolls[$frameIndex + 2]; + } + + protected function strikeBonus($frameIndex) + { + return $this->rolls[$frameIndex + 1] + + $this->rolls[$frameIndex + 2]; + } + + public function score() + { + $score = 0; + $frameIndex = 0; + + for ($frame = 0; $frame < 10; $frame++) { + if ($this->isStrike($frameIndex)) { + $score += 10 + $this->strikeBonus($frameIndex); + $frameIndex++; + } + + else if ($this->isSpare($frameIndex)) { + $score += 10 + $this->spareBonus($frameIndex); + $frameIndex += 2; + } + + else { + $score += $this->sumOfPinsInFrame($frameIndex); + $frameIndex += 2; + } + } + + return $score; + } +} diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGameSpec.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGameSpec.php new file mode 100644 index 00000000..b14523b6 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGameSpec.php @@ -0,0 +1,182 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Extensions/Story/TestCase.php'; +require_once 'BowlingGame.php'; + +class BowlingGameSpec extends PHPUnit_Extensions_Story_TestCase +{ + /** + * @scenario + */ + public function scoreForGutterGameIs0() + { + $this->given('New game') + ->then('Score should be', 0); + } + + /** + * @scenario + */ + public function scoreForAllOnesIs20() + { + $this->given('New game') + ->when('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->and('Player rolls', 1) + ->then('Score should be', 20); + } + + /** + * @scenario + */ + public function scoreForOneSpareAnd3Is16() + { + $this->given('New game') + ->when('Player rolls', 5) + ->and('Player rolls', 5) + ->and('Player rolls', 3) + ->then('Score should be', 16); + } + + /** + * @scenario + */ + public function scoreForOneStrikeAnd3And4Is24() + { + $this->given('New game') + ->when('Player rolls', 10) + ->and('Player rolls', 3) + ->and('Player rolls', 4) + ->then('Score should be', 24); + } + + /** + * @scenario + */ + public function scoreForPerfectGameIs300() + { + $this->given('New game') + ->when('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->and('Player rolls', 10) + ->then('Score should be', 300); + } + + public function runGiven(&$world, $action, $arguments) + { + switch($action) { + case 'New game': { + $world['game'] = new BowlingGame; + $world['rolls'] = 0; + } + break; + + default: { + return $this->notImplemented($action); + } + } + } + + public function runWhen(&$world, $action, $arguments) + { + switch($action) { + case 'Player rolls': { + $world['game']->roll($arguments[0]); + $world['rolls']++; + } + break; + + default: { + return $this->notImplemented($action); + } + } + } + + public function runThen(&$world, $action, $arguments) + { + switch($action) { + case 'Score should be': { + for ($i = $world['rolls']; $i < 20; $i++) { + $world['game']->roll(0); + } + + $this->assertEquals($arguments[0], $world['game']->score()); + } + break; + + default: { + return $this->notImplemented($action); + } + } + } +} + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGameTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGameTest.php new file mode 100644 index 00000000..4d12ac8c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/BowlingGame/BowlingGameTest.php @@ -0,0 +1,109 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'BowlingGame.php'; + +class BowlingGameTest extends PHPUnit_Framework_TestCase +{ + protected $game; + + protected function setUp() + { + $this->game = new BowlingGame; + } + + public function testScoreForGutterGameIs0() + { + $this->rollMany(20, 0); + $this->assertEquals(0, $this->game->score()); + } + + public function testScoreForAllOnesIs20() + { + $this->rollMany(20, 1); + $this->assertEquals(20, $this->game->score()); + } + + public function testScoreForOneSpareAnd3Is16() + { + $this->rollSpare(); + $this->game->roll(3); + $this->rollMany(17, 0); + $this->assertEquals(16, $this->game->score()); + } + + public function testScoreForOneStrikeAnd3And4Is24() + { + $this->rollStrike(); + $this->game->roll(3); + $this->game->roll(4); + $this->rollMany(17, 0); + $this->assertEquals(24, $this->game->score()); + } + + public function testScoreForPerfectGameIs300() + { + $this->rollMany(12, 10); + $this->assertEquals(300, $this->game->score()); + } + + protected function rollMany($n, $pins) + { + for ($i = 0; $i < $n; $i++) { + $this->game->roll($pins); + } + } + + protected function rollSpare() + { + $this->game->roll(5); + $this->game->roll(5); + } + + protected function rollStrike() + { + $this->game->roll(10); + } +} diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/IMoney.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/IMoney.php new file mode 100644 index 00000000..8d8baf76 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/IMoney.php @@ -0,0 +1,72 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'Money.php'; +require_once 'MoneyBag.php'; + +/** + * Money Interface. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +interface IMoney +{ + public function add(IMoney $m); + public function addMoney(Money $m); + public function addMoneyBag(MoneyBag $s); + public function isZero(); + public function multiply($factor); + public function negate(); + public function subtract(IMoney $m); + public function appendTo(MoneyBag $m); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/Money.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/Money.php new file mode 100644 index 00000000..e863a220 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/Money.php @@ -0,0 +1,150 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'IMoney.php'; + +/** + * A Money. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class Money implements IMoney +{ + protected $fAmount; + protected $fCurrency; + + public function __construct($amount, $currency) + { + $this->fAmount = $amount; + $this->fCurrency = $currency; + } + + public function add(IMoney $m) + { + return $m->addMoney($this); + } + + public function addMoney(Money $m) + { + if ($this->currency() == $m->currency()) { + return new Money($this->amount() + $m->amount(), $this->currency()); + } + + return MoneyBag::create($this, $m); + } + + public function addMoneyBag(MoneyBag $s) + { + return $s->addMoney($this); + } + + public function amount() + { + return $this->fAmount; + } + + public function currency() + { + return $this->fCurrency; + } + + public function equals($anObject) + { + if ($this->isZero() && + $anObject instanceof IMoney) { + return $anObject->isZero(); + } + + if ($anObject instanceof Money) { + return ($this->currency() == $anObject->currency() && + $this->amount() == $anObject->amount()); + } + + return FALSE; + } + + public function hashCode() + { + return crc32($this->fCurrency) + $this->fAmount; + } + + public function isZero() + { + return $this->amount() == 0; + } + + public function multiply($factor) + { + return new Money($this->amount() * $factor, $this->currency()); + } + + public function negate() + { + return new Money(-1 * $this->amount(), $this->currency()); + } + + public function subtract(IMoney $m) + { + return $this->add($m->negate()); + } + + public function toString() + { + return '[' . $this->amount() . ' ' . $this->currency() . ']'; + } + + public function appendTo(MoneyBag $m) + { + $m->appendMoney($this); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/MoneyBag.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/MoneyBag.php new file mode 100644 index 00000000..124c87cf --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/MoneyBag.php @@ -0,0 +1,249 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'IMoney.php'; +require_once 'Money.php'; + +/** + * A MoneyBag. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class MoneyBag implements IMoney +{ + protected $fMonies = array(); + + public static function create(IMoney $m1, IMoney $m2) + { + $result = new MoneyBag; + $m1->appendTo($result); + $m2->appendTo($result); + + return $result->simplify(); + } + + public function add(IMoney $m) + { + return $m->addMoneyBag($this); + } + + public function addMoney(Money $m) + { + return MoneyBag::create($m, $this); + } + + public function addMoneyBag(MoneyBag $s) + { + return MoneyBag::create($s, $this); + } + + public function appendBag(MoneyBag $aBag) + { + foreach ($aBag->monies() as $aMoney) { + $this->appendMoney($aMoney); + } + } + + public function monies() + { + return $this->fMonies; + } + + public function appendMoney(Money $aMoney) + { + if ($aMoney->isZero()) { + return; + } + + $old = $this->findMoney($aMoney->currency()); + + if ($old == NULL) { + $this->fMonies[] = $aMoney; + return; + } + + $keys = array_keys($this->fMonies); + $max = count($keys); + + for ($i = 0; $i < $max; $i++) { + if ($this->fMonies[$keys[$i]] === $old) { + unset($this->fMonies[$keys[$i]]); + break; + } + } + + $sum = $old->add($aMoney); + + if ($sum->isZero()) { + return; + } + + $this->fMonies[] = $sum; + } + + public function equals($anObject) + { + if ($this->isZero() && + $anObject instanceof IMoney) { + return $anObject->isZero(); + } + + if ($anObject instanceof MoneyBag) { + if (count($anObject->monies()) != count($this->fMonies)) { + return FALSE; + } + + foreach ($this->fMonies as $m) { + if (!$anObject->contains($m)) { + return FALSE; + } + } + + return TRUE; + } + + return FALSE; + } + + protected function findMoney($currency) + { + foreach ($this->fMonies as $m) { + if ($m->currency() == $currency) { + return $m; + } + } + + return NULL; + } + + protected function contains(Money $m) + { + $found = $this->findMoney($m->currency()); + + if ($found == NULL) { + return FALSE; + } + + return $found->amount() == $m->amount(); + } + + public function hashCode() + { + $hash = 0; + + foreach ($this->fMonies as $m) { + $hash ^= $m->hashCode(); + } + + return $hash; + } + + public function isZero() + { + return count($this->fMonies) == 0; + } + + public function multiply($factor) + { + $result = new MoneyBag; + + if ($factor != 0) { + foreach ($this->fMonies as $m) { + $result->appendMoney($m->multiply($factor)); + } + } + + return $result; + } + + public function negate() + { + $result = new MoneyBag; + + foreach ($this->fMonies as $m) { + $result->appendMoney($m->negate()); + } + + return $result; + } + + protected function simplify() + { + if (count($this->fMonies) == 1) { + return array_pop($this->fMonies); + } + + return $this; + } + + public function subtract(IMoney $m) + { + return $this->add($m->negate()); + } + + public function toString() + { + $buffer = '{'; + + foreach ($this->fMonies as $m) { + $buffer .= $m->toString(); + } + + return $buffer . '}'; + } + + public function appendTo(MoneyBag $m) + { + $m->appendBag($this); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/MoneyTest.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/MoneyTest.php new file mode 100644 index 00000000..f3c09b24 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Samples/Money/MoneyTest.php @@ -0,0 +1,247 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Framework/TestCase.php'; + +require_once 'Money.php'; +require_once 'MoneyBag.php'; + +/** + * Tests for the Money and MoneyBag classes. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class MoneyTest extends PHPUnit_Framework_TestCase +{ + protected $f12EUR; + protected $f14EUR; + protected $f7USD; + protected $f21USD; + + protected $fMB1; + protected $fMB2; + + protected function setUp() + { + $this->f12EUR = new Money(12, 'EUR'); + $this->f14EUR = new Money(14, 'EUR'); + $this->f7USD = new Money( 7, 'USD'); + $this->f21USD = new Money(21, 'USD'); + + $this->fMB1 = MoneyBag::create($this->f12EUR, $this->f7USD); + $this->fMB2 = MoneyBag::create($this->f14EUR, $this->f21USD); + } + + public function testBagMultiply() + { + // {[12 EUR][7 USD]} *2 == {[24 EUR][14 USD]} + $expected = MoneyBag::create(new Money(24, 'EUR'), new Money(14, 'USD')); + + $this->assertTrue($expected->equals($this->fMB1->multiply(2))); + $this->assertTrue($this->fMB1->equals($this->fMB1->multiply(1))); + $this->assertTrue($this->fMB1->multiply(0)->isZero()); + } + + public function testBagNegate() + { + // {[12 EUR][7 USD]} negate == {[-12 EUR][-7 USD]} + $expected = MoneyBag::create(new Money(-12, 'EUR'), new Money(-7, 'USD')); + $this->assertTrue($expected->equals($this->fMB1->negate())); + } + + public function testBagSimpleAdd() + { + // {[12 EUR][7 USD]} + [14 EUR] == {[26 EUR][7 USD]} + $expected = MoneyBag::create(new Money(26, 'EUR'), new Money(7, 'USD')); + $this->assertTrue($expected->equals($this->fMB1->add($this->f14EUR))); + } + + public function testBagSubtract() + { + // {[12 EUR][7 USD]} - {[14 EUR][21 USD] == {[-2 EUR][-14 USD]} + $expected = MoneyBag::create(new Money(-2, 'EUR'), new Money(-14, 'USD')); + $this->assertTrue($expected->equals($this->fMB1->subtract($this->fMB2))); + } + + public function testBagSumAdd() + { + // {[12 EUR][7 USD]} + {[14 EUR][21 USD]} == {[26 EUR][28 USD]} + $expected = MoneyBag::create(new Money(26, 'EUR'), new Money(28, 'USD')); + $this->assertTrue($expected->equals($this->fMB1->add($this->fMB2))); + } + + public function testIsZero() + { + //$this->assertTrue($this->fMB1->subtract($this->fMB1)->isZero()); + $this->assertTrue(MoneyBag::create(new Money (0, 'EUR'), new Money (0, 'USD'))->isZero()); + } + + public function testMixedSimpleAdd() + { + // [12 EUR] + [7 USD] == {[12 EUR][7 USD]} + $expected = MoneyBag::create($this->f12EUR, $this->f7USD); + $this->assertTrue($expected->equals($this->f12EUR->add($this->f7USD))); + } + + public function testBagNotEquals() + { + $bag1 = MoneyBag::create($this->f12EUR, $this->f7USD); + $bag2 = new Money(12, 'CHF'); + $bag2->add($this->f7USD); + $this->assertFalse($bag1->equals($bag2)); + } + + public function testMoneyBagEquals() + { + $this->assertTrue(!$this->fMB1->equals(NULL)); + + $this->assertTrue($this->fMB1->equals($this->fMB1)); + $equal = MoneyBag::create(new Money(12, 'EUR'), new Money(7, 'USD')); + $this->assertTrue($this->fMB1->equals($equal)); + $this->assertTrue(!$this->fMB1->equals($this->f12EUR)); + $this->assertTrue(!$this->f12EUR->equals($this->fMB1)); + $this->assertTrue(!$this->fMB1->equals($this->fMB2)); + } + + public function testMoneyBagHash() + { + $equal = MoneyBag::create(new Money(12, 'EUR'), new Money(7, 'USD')); + $this->assertEquals($this->fMB1->hashCode(), $equal->hashCode()); + } + + public function testMoneyEquals() + { + $this->assertTrue(!$this->f12EUR->equals(NULL)); + $equalMoney = new Money(12, 'EUR'); + $this->assertTrue($this->f12EUR->equals($this->f12EUR)); + $this->assertTrue($this->f12EUR->equals($equalMoney)); + $this->assertEquals($this->f12EUR->hashCode(), $equalMoney->hashCode()); + $this->assertFalse($this->f12EUR->equals($this->f14EUR)); + } + + public function testMoneyHash() + { + $this->assertNotNull($this->f12EUR); + $equal= new Money(12, 'EUR'); + $this->assertEquals($this->f12EUR->hashCode(), $equal->hashCode()); + } + + public function testSimplify() + { + $money = MoneyBag::create(new Money(26, 'EUR'), new Money(28, 'EUR')); + $this->assertTrue($money->equals(new Money(54, 'EUR'))); + } + + public function testNormalize2() + { + // {[12 EUR][7 USD]} - [12 EUR] == [7 USD] + $expected = new Money(7, 'USD'); + $this->assertTrue($expected->equals($this->fMB1->subtract($this->f12EUR))); + } + + public function testNormalize3() + { + // {[12 EUR][7 USD]} - {[12 EUR][3 USD]} == [4 USD] + $ms1 = MoneyBag::create(new Money(12, 'EUR'), new Money(3, 'USD')); + $expected = new Money(4, 'USD'); + $this->assertTrue($expected->equals($this->fMB1->subtract($ms1))); + } + + public function testNormalize4() + { + // [12 EUR] - {[12 EUR][3 USD]} == [-3 USD] + $ms1 = MoneyBag::create(new Money(12, 'EUR'), new Money(3, 'USD')); + $expected = new Money(-3, 'USD'); + $this->assertTrue($expected->equals($this->f12EUR->subtract($ms1))); + } + + public function testPrint() + { + $this->assertEquals('[12 EUR]', $this->f12EUR->toString()); + } + + public function testSimpleAdd() + { + // [12 EUR] + [14 EUR] == [26 EUR] + $expected = new Money(26, 'EUR'); + $this->assertTrue($expected->equals($this->f12EUR->add($this->f14EUR))); + } + + public function testSimpleBagAdd() + { + // [14 EUR] + {[12 EUR][7 USD]} == {[26 EUR][7 USD]} + $expected = MoneyBag::create(new Money(26, 'EUR'), new Money(7, 'USD')); + $this->assertTrue($expected->equals($this->f14EUR->add($this->fMB1))); + } + + public function testSimpleMultiply() + { + // [14 EUR] *2 == [28 EUR] + $expected = new Money(28, 'EUR'); + $this->assertTrue($expected->equals($this->f14EUR->multiply(2))); + } + + public function testSimpleNegate() + { + // [14 EUR] negate == [-14 EUR] + $expected = new Money(-14, 'EUR'); + $this->assertTrue($expected->equals($this->f14EUR->negate())); + } + + public function testSimpleSubtract() + { + // [14 EUR] - [12 EUR] == [2 EUR] + $expected = new Money(2, 'EUR'); + $this->assertTrue($expected->equals($this->f14EUR->subtract($this->f12EUR))); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/Command.php b/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/Command.php new file mode 100644 index 00000000..139c1153 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/Command.php @@ -0,0 +1,1006 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/TextUI/TestRunner.php'; +require_once 'PHPUnit/Util/Configuration.php'; +require_once 'PHPUnit/Util/Fileloader.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Getopt.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestRunner for the Command Line Interface (CLI) + * PHP SAPI Module. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_TextUI_Command +{ + /** + * @var array + */ + protected $arguments = array( + 'listGroups' => FALSE, + 'loader' => NULL, + 'syntaxCheck' => FALSE, + 'useDefaultConfiguration' => TRUE + ); + + /** + * @var array + */ + protected $options = array(); + + /** + * @var array + */ + protected $longOptions = array( + 'ansi' => NULL, + 'colors' => NULL, + 'bootstrap=' => NULL, + 'configuration=' => NULL, + 'coverage-html=' => NULL, + 'coverage-clover=' => NULL, + 'coverage-source=' => NULL, + 'coverage-xml=' => NULL, + 'debug' => NULL, + 'exclude-group=' => NULL, + 'filter=' => NULL, + 'group=' => NULL, + 'help' => NULL, + 'include-path=' => NULL, + 'list-groups' => NULL, + 'loader=' => NULL, + 'log-graphviz=' => NULL, + 'log-json=' => NULL, + 'log-junit=' => NULL, + 'log-metrics=' => NULL, + 'log-pmd=' => NULL, + 'log-tap=' => NULL, + 'log-xml=' => NULL, + 'process-isolation' => NULL, + 'repeat=' => NULL, + 'report=' => NULL, + 'skeleton' => NULL, + 'skeleton-class' => NULL, + 'skeleton-test' => NULL, + 'stderr' => NULL, + 'stop-on-failure' => NULL, + 'story' => NULL, + 'story-html=' => NULL, + 'story-text=' => NULL, + 'syntax-check' => NULL, + 'tap' => NULL, + 'test-db-dsn=' => NULL, + 'test-db-log-rev=' => NULL, + 'test-db-log-prefix=' => NULL, + 'test-db-log-info=' => NULL, + 'testdox' => NULL, + 'testdox-html=' => NULL, + 'testdox-text=' => NULL, + 'no-configuration' => NULL, + 'no-globals-backup' => NULL, + 'static-backup' => NULL, + 'verbose' => NULL, + 'version' => NULL, + 'wait' => NULL + ); + + /** + * @param boolean $exit + */ + public static function main($exit = TRUE) + { + $command = new PHPUnit_TextUI_Command; + $command->run($_SERVER['argv'], $exit); + } + + /** + * @param array $argv + * @param boolean $exit + */ + public function run(array $argv, $exit = TRUE) + { + $this->handleArguments($argv); + + $runner = new PHPUnit_TextUI_TestRunner($this->arguments['loader']); + + if (is_object($this->arguments['test']) && + $this->arguments['test'] instanceof PHPUnit_Framework_Test) { + $suite = $this->arguments['test']; + } else { + $suite = $runner->getTest( + $this->arguments['test'], + $this->arguments['testFile'], + $this->arguments['syntaxCheck'] + ); + } + + if ($suite->testAt(0) instanceof PHPUnit_Framework_Warning && + strpos($suite->testAt(0)->getMessage(), 'No tests found in class') !== FALSE) { + $message = $suite->testAt(0)->getMessage(); + $start = strpos($message, '"') + 1; + $end = strpos($message, '"', $start); + $className = substr($message, $start, $end - $start); + + require_once 'PHPUnit/Util/Skeleton/Test.php'; + + $skeleton = new PHPUnit_Util_Skeleton_Test( + $className, + $this->arguments['testFile'] + ); + + $result = $skeleton->generate(TRUE); + + if (!$result['incomplete']) { + eval(str_replace(array(''), '', $result['code'])); + $suite = new PHPUnit_Framework_TestSuite( + $this->arguments['test'] . 'Test' + ); + } + } + + if ($this->arguments['listGroups']) { + PHPUnit_TextUI_TestRunner::printVersionString(); + + print "Available test group(s):\n"; + + $groups = $suite->getGroups(); + sort($groups); + + foreach ($groups as $group) { + print " - $group\n"; + } + + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } + + unset($this->arguments['test']); + unset($this->arguments['testFile']); + + try { + $result = $runner->doRun($suite, $this->arguments); + } + + catch (PHPUnit_Framework_Exception $e) { + print $e->getMessage() . "\n"; + } + + if ($exit) { + if (isset($result) && $result->wasSuccessful()) { + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } + + else if (!isset($result) || $result->errorCount() > 0) { + exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); + } + + else { + exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); + } + } + } + + /** + * Handles the command-line arguments. + * + * A child class of PHPUnit_TextUI_Command can hook into the argument + * parsing by adding the switch(es) to the $longOptions array and point to a + * callback method that handles the switch(es) in the child class like this + * + * + * longOptions['--my-switch'] = 'myHandler'; + * } + * + * // --my-switch foo -> myHandler('foo') + * protected function myHandler($value) + * { + * } + * } + * + * + * @param array $argv + */ + protected function handleArguments(array $argv) + { + try { + $this->options = PHPUnit_Util_Getopt::getopt( + $argv, + 'd:', + array_keys($this->longOptions) + ); + } + + catch (RuntimeException $e) { + PHPUnit_TextUI_TestRunner::showError($e->getMessage()); + } + + $skeletonClass = FALSE; + $skeletonTest = FALSE; + + foreach ($this->options[0] as $option) { + switch ($option[0]) { + case '--ansi': { + $this->showMessage( + 'The --ansi option is deprecated, please use --colors ' . + 'instead.', + FALSE + ); + } + + case '--colors': { + $this->arguments['colors'] = TRUE; + } + break; + + case '--bootstrap': { + $this->arguments['bootstrap'] = $option[1]; + } + break; + + case '--configuration': { + $this->arguments['configuration'] = $option[1]; + } + break; + + case '--coverage-xml': { + $this->showMessage( + 'The --coverage-xml option is deprecated, please use ' . + '--coverage-clover instead.', + FALSE + ); + } + + case '--coverage-clover': { + if (extension_loaded('tokenizer') && + extension_loaded('xdebug')) { + $this->arguments['coverageClover'] = $option[1]; + } else { + if (!extension_loaded('tokenizer')) { + $this->showMessage( + 'The tokenizer extension is not loaded.' + ); + } else { + $this->showMessage( + 'The Xdebug extension is not loaded.' + ); + } + } + } + break; + + case '--coverage-source': { + if (extension_loaded('tokenizer') && + extension_loaded('xdebug')) { + $this->arguments['coverageSource'] = $option[1]; + } else { + if (!extension_loaded('tokenizer')) { + $this->showMessage( + 'The tokenizer extension is not loaded.' + ); + } else { + $this->showMessage( + 'The Xdebug extension is not loaded.' + ); + } + } + } + break; + + case '--report': { + $this->showMessage( + 'The --report option is deprecated, please use ' . + '--coverage-html instead.', + FALSE + ); + } + + case '--coverage-html': { + if (extension_loaded('tokenizer') && + extension_loaded('xdebug')) { + $this->arguments['reportDirectory'] = $option[1]; + } else { + if (!extension_loaded('tokenizer')) { + $this->showMessage( + 'The tokenizer extension is not loaded.' + ); + } else { + $this->showMessage( + 'The Xdebug extension is not loaded.' + ); + } + } + } + break; + + case 'd': { + $ini = explode('=', $option[1]); + + if (isset($ini[0])) { + if (isset($ini[1])) { + ini_set($ini[0], $ini[1]); + } else { + ini_set($ini[0], TRUE); + } + } + } + break; + + case '--debug': { + $this->arguments['debug'] = TRUE; + } + break; + + case '--help': { + $this->showHelp(); + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } + break; + + case '--filter': { + $this->arguments['filter'] = $option[1]; + } + break; + + case '--group': { + $this->arguments['groups'] = explode(',', $option[1]); + } + break; + + case '--exclude-group': { + $this->arguments['excludeGroups'] = explode( + ',', $option[1] + ); + } + break; + + case '--include-path': { + $includePath = $option[1]; + } + break; + + case '--list-groups': { + $this->arguments['listGroups'] = TRUE; + } + break; + + case '--loader': { + $this->arguments['loader'] = $option[1]; + } + break; + + case '--log-json': { + $this->arguments['jsonLogfile'] = $option[1]; + } + break; + + case '--log-xml': { + $this->showMessage( + 'The --log-xml option is deprecated, please use ' . + '--log-junit instead.', + FALSE + ); + } + + case '--log-junit': { + $this->arguments['junitLogfile'] = $option[1]; + } + break; + + case '--log-graphviz': { + $this->showMessage( + 'The --log-graphviz functionality is deprecated and ' . + 'will be removed in the future.', + FALSE + ); + + if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Image/GraphViz.php')) { + $this->arguments['graphvizLogfile'] = $option[1]; + } else { + $this->showMessage( + 'The Image_GraphViz package is not installed.' + ); + } + } + break; + + case '--log-tap': { + $this->arguments['tapLogfile'] = $option[1]; + } + break; + + case '--log-pmd': { + $this->showMessage( + 'The --log-pmd functionality is deprecated and will be ' . + 'removed in the future.', + FALSE + ); + + if (extension_loaded('tokenizer') && + extension_loaded('xdebug')) { + $this->arguments['pmdXML'] = $option[1]; + } else { + if (!extension_loaded('tokenizer')) { + $this->showMessage( + 'The tokenizer extension is not loaded.' + ); + } else { + $this->showMessage( + 'The Xdebug extension is not loaded.' + ); + } + } + } + break; + + case '--log-metrics': { + $this->showMessage( + 'The --log-metrics functionality is deprecated and ' . + 'will be removed in the future.', + FALSE + ); + + if (extension_loaded('tokenizer') && + extension_loaded('xdebug')) { + $this->arguments['metricsXML'] = $option[1]; + } else { + if (!extension_loaded('tokenizer')) { + $this->showMessage( + 'The tokenizer extension is not loaded.' + ); + } else { + $this->showMessage( + 'The Xdebug extension is not loaded.' + ); + } + } + } + break; + + case '--process-isolation': { + $this->arguments['processIsolation'] = TRUE; + $this->arguments['syntaxCheck'] = FALSE; + } + break; + + case '--repeat': { + $this->showMessage( + 'The --repeat functionality is deprecated and will be ' . + 'removed in the future.', + FALSE + ); + + $this->arguments['repeat'] = (int)$option[1]; + } + break; + + case '--stderr': { + $this->arguments['printer'] = new PHPUnit_TextUI_ResultPrinter( + 'php://stderr', + isset($this->arguments['verbose']) ? $this->arguments['verbose'] : FALSE + ); + } + break; + + case '--stop-on-failure': { + $this->arguments['stopOnFailure'] = TRUE; + } + break; + + case '--test-db-dsn': { + $this->showMessage( + 'The test database functionality is deprecated and ' . + 'will be removed in the future.', + FALSE + ); + + if (extension_loaded('pdo')) { + $this->arguments['testDatabaseDSN'] = $option[1]; + } else { + $this->showMessage('The PDO extension is not loaded.'); + } + } + break; + + case '--test-db-log-rev': { + if (extension_loaded('pdo')) { + $this->arguments['testDatabaseLogRevision'] = $option[1]; + } else { + $this->showMessage('The PDO extension is not loaded.'); + } + } + break; + + case '--test-db-prefix': { + if (extension_loaded('pdo')) { + $this->arguments['testDatabasePrefix'] = $option[1]; + } else { + $this->showMessage('The PDO extension is not loaded.'); + } + } + break; + + case '--test-db-log-info': { + if (extension_loaded('pdo')) { + $this->arguments['testDatabaseLogInfo'] = $option[1]; + } else { + $this->showMessage('The PDO extension is not loaded.'); + } + } + break; + + case '--skeleton': { + $this->showMessage( + 'The --skeleton option is deprecated, please use ' . + '--skeleton-test instead.', + FALSE + ); + } + + case '--skeleton-test': { + $skeletonTest = TRUE; + $skeletonClass = FALSE; + } + break; + + case '--skeleton-class': { + $skeletonClass = TRUE; + $skeletonTest = FALSE; + } + break; + + case '--tap': { + require_once 'PHPUnit/Util/Log/TAP.php'; + + $this->arguments['printer'] = new PHPUnit_Util_Log_TAP; + } + break; + + case '--story': { + require_once 'PHPUnit/Extensions/Story/ResultPrinter/Text.php'; + + $this->arguments['printer'] = new PHPUnit_Extensions_Story_ResultPrinter_Text; + } + break; + + case '--story-html': { + $this->arguments['storyHTMLFile'] = $option[1]; + } + break; + + case '--story-text': { + $this->arguments['storyTextFile'] = $option[1]; + } + break; + + case '--syntax-check': { + $this->arguments['syntaxCheck'] = TRUE; + } + break; + + case '--testdox': { + require_once 'PHPUnit/Util/TestDox/ResultPrinter/Text.php'; + + $this->arguments['printer'] = new PHPUnit_Util_TestDox_ResultPrinter_Text; + } + break; + + case '--testdox-html': { + $this->arguments['testdoxHTMLFile'] = $option[1]; + } + break; + + case '--testdox-text': { + $this->arguments['testdoxTextFile'] = $option[1]; + } + break; + + case '--no-configuration': { + $this->arguments['useDefaultConfiguration'] = FALSE; + } + break; + + case '--no-globals-backup': { + $this->arguments['backupGlobals'] = FALSE; + } + break; + + case '--static-backup': { + $this->arguments['backupStaticAttributes'] = TRUE; + } + break; + + case '--verbose': { + $this->arguments['verbose'] = TRUE; + } + break; + + case '--version': { + PHPUnit_TextUI_TestRunner::printVersionString(); + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } + break; + + case '--wait': { + $this->arguments['wait'] = TRUE; + } + break; + + default: { + $optionName = str_replace('--', '', $option[0]); + + if (isset($this->longOptions[$optionName])) { + $handler = $this->longOptions[$optionName]; + } + + else if (isset($this->longOptions[$optionName . '='])) { + $handler = $this->longOptions[$optionName . '=']; + } + + if (isset($handler) && is_callable(array($this, $handler))) { + $this->$handler($option[1]); + } + } + } + } + + if (isset($this->arguments['printer']) && + $this->arguments['printer'] instanceof PHPUnit_Extensions_Story_ResultPrinter_Text && + isset($this->arguments['processIsolation']) && + $this->arguments['processIsolation']) { + $this->showMessage( + 'The story result printer cannot be used in process isolation.' + ); + } + + $this->handleCustomTestSuite(); + + if (!isset($this->arguments['test'])) { + if (isset($this->options[1][0])) { + $this->arguments['test'] = $this->options[1][0]; + } + + if (isset($this->options[1][1])) { + $this->arguments['testFile'] = $this->options[1][1]; + } else { + $this->arguments['testFile'] = ''; + } + + if (isset($this->arguments['test']) && is_file($this->arguments['test'])) { + $this->arguments['testFile'] = realpath($this->arguments['test']); + $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.')); + } + } + + if (isset($includePath)) { + ini_set( + 'include_path', + $includePath . PATH_SEPARATOR . ini_get('include_path') + ); + } + + if (isset($this->arguments['bootstrap'])) { + PHPUnit_Util_Fileloader::load($this->arguments['bootstrap']); + } + + if ($this->arguments['loader'] !== NULL) { + $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']); + } + + if (!isset($this->arguments['configuration']) && $this->arguments['useDefaultConfiguration']) { + if (file_exists('phpunit.xml')) { + $this->arguments['configuration'] = realpath('phpunit.xml'); + } + + else if (file_exists('phpunit.xml.dist')) { + $this->arguments['configuration'] = realpath('phpunit.xml.dist'); + } + } + + if (isset($this->arguments['configuration'])) { + $configuration = PHPUnit_Util_Configuration::getInstance( + $this->arguments['configuration'] + ); + + $phpunit = $configuration->getPHPUnitConfiguration(); + + if (isset($phpunit['syntaxCheck'])) { + $this->arguments['syntaxCheck'] = $phpunit['syntaxCheck']; + } + + if (isset($phpunit['testSuiteLoaderClass'])) { + if (isset($phpunit['testSuiteLoaderFile'])) { + $file = $phpunit['testSuiteLoaderFile']; + } else { + $file = ''; + } + + $this->arguments['loader'] = $this->handleLoader( + $phpunit['testSuiteLoaderClass'], $file + ); + } + + $configuration->handlePHPConfiguration(); + + if (!isset($this->arguments['bootstrap'])) { + $phpunitConfiguration = $configuration->getPHPUnitConfiguration(); + + if (isset($phpunitConfiguration['bootstrap'])) { + PHPUnit_Util_Fileloader::load($phpunitConfiguration['bootstrap']); + } + } + + $browsers = $configuration->getSeleniumBrowserConfiguration(); + + if (!empty($browsers)) { + require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; + PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers; + } + + if (!isset($this->arguments['test'])) { + $testSuite = $configuration->getTestSuiteConfiguration( + $this->arguments['syntaxCheck'] + ); + + if ($testSuite !== NULL) { + $this->arguments['test'] = $testSuite; + } + } + } + + if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') { + require_once 'PHPUnit/Extensions/PhptTestCase.php'; + + $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']); + + $this->arguments['test'] = new PHPUnit_Framework_TestSuite; + $this->arguments['test']->addTest($test); + } + + if (!isset($this->arguments['test']) || + (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) { + $this->showHelp(); + exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); + } + + if (!isset($this->arguments['syntaxCheck'])) { + $this->arguments['syntaxCheck'] = FALSE; + } + + if ($skeletonClass || $skeletonTest) { + if (isset($this->arguments['test']) && $this->arguments['test'] !== FALSE) { + PHPUnit_TextUI_TestRunner::printVersionString(); + + if ($skeletonClass) { + require_once 'PHPUnit/Util/Skeleton/Class.php'; + + $class = 'PHPUnit_Util_Skeleton_Class'; + } else { + require_once 'PHPUnit/Util/Skeleton/Test.php'; + + $class = 'PHPUnit_Util_Skeleton_Test'; + } + + try { + $args = array(); + $reflector = new ReflectionClass($class); + + for ($i = 0; $i <= 3; $i++) { + if (isset($this->options[1][$i])) { + $args[] = $this->options[1][$i]; + } + } + + $skeleton = $reflector->newInstanceArgs($args); + $skeleton->write(); + } + + catch (Exception $e) { + print $e->getMessage() . "\n"; + exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); + } + + printf( + 'Wrote skeleton for "%s" to "%s".' . "\n", + $skeleton->getOutClassName(), + $skeleton->getOutSourceFile() + ); + + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } else { + $this->showHelp(); + exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); + } + } + } + + /** + * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation. + * + * @param string $loaderClass + * @param string $loaderFile + */ + protected function handleLoader($loaderClass, $loaderFile = '') + { + if (!class_exists($loaderClass, FALSE)) { + if ($loaderFile == '') { + $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename( + $loaderClass + ); + } + + $loaderFile = PHPUnit_Util_Filesystem::fileExistsInIncludePath( + $loaderFile + ); + + if ($loaderFile !== FALSE) { + require $loaderFile; + } + } + + if (class_exists($loaderClass, FALSE)) { + $class = new ReflectionClass($loaderClass); + + if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') && + $class->isInstantiable()) { + $loader = $class->newInstance(); + } + } + + if (!isset($loader)) { + PHPUnit_TextUI_TestRunner::showError( + sprintf( + 'Could not use "%s" as loader.', + + $loaderClass + ) + ); + } + + return $loader; + } + + /** + * Shows a message. + * + * @param string $message + * @param boolean $exit + */ + protected function showMessage($message, $exit = TRUE) + { + PHPUnit_TextUI_TestRunner::printVersionString(); + print $message . "\n"; + + if ($exit) { + exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); + } else { + print "\n"; + } + } + + /** + * Show the help message. + */ + protected function showHelp() + { + PHPUnit_TextUI_TestRunner::printVersionString(); + + print << + + --log-junit Log test execution in JUnit XML format to file. + --log-tap Log test execution in TAP format to file. + --log-json Log test execution in JSON format. + + --coverage-html Generate code coverage report in HTML format. + --coverage-clover Write code coverage data in Clover XML format. + --coverage-source Write code coverage / source data in XML format. + + --story-html Write Story/BDD results in HTML format to file. + --story-text Write Story/BDD results in Text format to file. + + --testdox-html Write agile documentation in HTML format to file. + --testdox-text Write agile documentation in Text format to file. + + --filter Filter which tests to run. + --group ... Only runs tests from the specified group(s). + --exclude-group ... Exclude tests from the specified group(s). + --list-groups List available test groups. + + --loader TestSuiteLoader implementation to use. + + --story Report test execution progress in Story/BDD format. + --tap Report test execution progress in TAP format. + --testdox Report test execution progress in TestDox format. + + --colors Use colors in output. + --stderr Write to STDERR instead of STDOUT. + --stop-on-failure Stop execution upon first error or failure. + --verbose Output more verbose information. + --wait Waits for a keystroke after each test. + + --skeleton-class Generate Unit class for UnitTest in UnitTest.php. + --skeleton-test Generate UnitTest class for Unit in Unit.php. + + --process-isolation Run each test in a separate PHP process. + --no-globals-backup Do not backup and restore \$GLOBALS for each test. + --static-backup Backup and restore static attributes for each test. + --syntax-check Try to check source files for syntax errors. + + --bootstrap A "bootstrap" PHP file that is run before the tests. + --configuration Read configuration from XML file. + --no-configuration Ignore default configuration file (phpunit.xml). + --include-path Prepend PHP's include_path with given path(s). + -d key[=value] Sets a php.ini value. + + --help Prints this usage information. + --version Prints the version and exits. + +EOT; + } + + /** + * Custom callback for test suite discovery. + */ + protected function handleCustomTestSuite() + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/ResultPrinter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/ResultPrinter.php new file mode 100644 index 00000000..2ce7f2c9 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/ResultPrinter.php @@ -0,0 +1,675 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/Test.php'; +require_once 'PHPUnit/Util/Timer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Prints the result of a TextUI TestRunner run. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + const EVENT_TEST_START = 0; + const EVENT_TEST_END = 1; + const EVENT_TESTSUITE_START = 2; + const EVENT_TESTSUITE_END = 3; + + /** + * @var integer + */ + protected $column = 0; + + /** + * @var integer + */ + protected $indent = 0; + + /** + * @var integer + */ + protected $lastEvent = -1; + + /** + * @var boolean + */ + protected $lastTestFailed = FALSE; + + /** + * @var integer + */ + protected $numAssertions = 0; + + /** + * @var integer + */ + protected $numTests = -1; + + /** + * @var integer + */ + protected $numTestsRun = 0; + + /** + * @var integer + */ + protected $numTestsWidth; + + /** + * @var boolean + */ + protected $colors = FALSE; + + /** + * @var boolean + */ + protected $debug = FALSE; + + /** + * @var boolean + */ + protected $verbose = FALSE; + + /** + * Constructor. + * + * @param mixed $out + * @param boolean $verbose + * @param boolean $colors + * @param boolean $debug + * @throws InvalidArgumentException + * @since Method available since Release 3.0.0 + */ + public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE) + { + parent::__construct($out); + + if (is_bool($verbose)) { + $this->verbose = $verbose; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean'); + } + + if (is_bool($colors)) { + $this->colors = $colors; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean'); + } + + if (is_bool($debug)) { + $this->debug = $debug; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean'); + } + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + public function printResult(PHPUnit_Framework_TestResult $result) + { + $this->printHeader($result->time()); + + if ($result->errorCount() > 0) { + $this->printErrors($result); + } + + if ($result->failureCount() > 0) { + if ($result->errorCount() > 0) { + print "\n--\n\n"; + } + + $this->printFailures($result); + } + + if ($this->verbose) { + if ($result->notImplementedCount() > 0) { + if ($result->failureCount() > 0) { + print "\n--\n\n"; + } + + $this->printIncompletes($result); + } + + if ($result->skippedCount() > 0) { + if ($result->notImplementedCount() > 0) { + print "\n--\n\n"; + } + + $this->printSkipped($result); + } + } + + $this->printFooter($result); + } + + /** + * @param array $defects + * @param integer $count + * @param string $type + */ + protected function printDefects(array $defects, $count, $type) + { + static $called = FALSE; + + if ($count == 0) { + return; + } + + $this->write( + sprintf( + "%sThere %s %d %s%s:\n", + + $called ? "\n" : '', + ($count == 1) ? 'was' : 'were', + $count, + $type, + ($count == 1) ? '' : 's' + ) + ); + + $i = 1; + + foreach ($defects as $defect) { + $this->printDefect($defect, $i++); + } + + $called = TRUE; + } + + /** + * @param PHPUnit_Framework_TestFailure $defect + * @param integer $count + */ + protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count) + { + $this->printDefectHeader($defect, $count); + $this->printDefectTrace($defect); + } + + /** + * @param PHPUnit_Framework_TestFailure $defect + * @param integer $count + */ + protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count) + { + $failedTest = $defect->failedTest(); + + if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) { + $testName = $failedTest->toString(); + } else { + $testName = get_class($failedTest); + } + + $this->write( + sprintf( + "\n%d) %s\n", + + $count, + $testName + ) + ); + } + + /** + * @param PHPUnit_Framework_TestFailure $defect + */ + protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect) + { + $this->write( + $defect->getExceptionAsString() . "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace( + $defect->thrownException(), + FALSE + ) + ); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printErrors(PHPUnit_Framework_TestResult $result) + { + $this->printDefects($result->errors(), $result->errorCount(), 'error'); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printFailures(PHPUnit_Framework_TestResult $result) + { + $this->printDefects( + $result->failures(), + $result->failureCount(), + 'failure' + ); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printIncompletes(PHPUnit_Framework_TestResult $result) + { + $this->printDefects( + $result->notImplemented(), + $result->notImplementedCount(), + 'incomplete test' + ); + } + + /** + * @param PHPUnit_Framework_TestResult $result + * @since Method available since Release 3.0.0 + */ + protected function printSkipped(PHPUnit_Framework_TestResult $result) + { + $this->printDefects( + $result->skipped(), + $result->skippedCount(), + 'skipped test' + ); + } + + /** + * @param float $timeElapsed + */ + protected function printHeader($timeElapsed) + { + if (isset($_SERVER['REQUEST_TIME'])) { + $timeElapsed = PHPUnit_Util_Timer::secondsToTimeString( + time() - $_SERVER['REQUEST_TIME'] + ); + } else { + $timeElapsed = PHPUnit_Util_Timer::secondsToTimeString( + $timeElapsed + ); + } + + if (function_exists('memory_get_peak_usage')) { + $memory = sprintf( + ', Memory: %4.2fMb', + memory_get_peak_usage(TRUE) / 1048576 + ); + } else { + $memory = ''; + } + + $this->write( + sprintf( + "%sTime: %s%s\n\n", + $this->verbose ? "\n" : "\n\n", + $timeElapsed, + $memory + ) + ); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printFooter(PHPUnit_Framework_TestResult $result) + { + if ($result->wasSuccessful() && + $result->allCompletlyImplemented() && + $result->noneSkipped()) { + if ($this->colors) { + $this->write("\x1b[30;42m\x1b[2K"); + } + + $this->write( + sprintf( + "OK (%d test%s, %d assertion%s)\n", + + count($result), + (count($result) == 1) ? '' : 's', + $this->numAssertions, + ($this->numAssertions == 1) ? '' : 's' + ) + ); + + if ($this->colors) { + $this->write("\x1b[0m\x1b[2K"); + } + } + + else if ((!$result->allCompletlyImplemented() || + !$result->noneSkipped())&& + $result->wasSuccessful()) { + if ($this->colors) { + $this->write( + "\x1b[30;43m\x1b[2KOK, but incomplete or skipped tests!\n" . + "\x1b[0m\x1b[30;43m\x1b[2K" + ); + } else { + $this->write("OK, but incomplete or skipped tests!\n"); + } + + $this->write( + sprintf( + "Tests: %d, Assertions: %d%s%s.\n", + + count($result), + $this->numAssertions, + $this->getCountString( + $result->notImplementedCount(), 'Incomplete' + ), + $this->getCountString( + $result->skippedCount(), 'Skipped' + ) + ) + ); + + if ($this->colors) { + $this->write("\x1b[0m\x1b[2K"); + } + } + + else { + $this->write("\n"); + + if ($this->colors) { + $this->write( + "\x1b[37;41m\x1b[2KFAILURES!\n\x1b[0m\x1b[37;41m\x1b[2K" + ); + } else { + $this->write("FAILURES!\n"); + } + + $this->write( + sprintf( + "Tests: %d, Assertions: %s%s%s%s%s.\n", + + count($result), + $this->numAssertions, + $this->getCountString($result->failureCount(), 'Failures'), + $this->getCountString($result->errorCount(), 'Errors'), + $this->getCountString( + $result->notImplementedCount(), 'Incomplete' + ), + $this->getCountString($result->skippedCount(), 'Skipped') + ) + ); + + if ($this->colors) { + $this->write("\x1b[0m\x1b[2K"); + } + } + } + + /** + * @param integer $count + * @param string $name + * @return string + * @since Method available since Release 3.0.0 + */ + protected function getCountString($count, $name) + { + $string = ''; + + if ($count > 0) { + $string = sprintf( + ', %s: %d', + + $name, + $count + ); + } + + return $string; + } + + /** + */ + public function printWaitPrompt() + { + $this->write("\n to continue\n"); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgress('E'); + $this->lastTestFailed = TRUE; + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->writeProgress('F'); + $this->lastTestFailed = TRUE; + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgress('I'); + $this->lastTestFailed = TRUE; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgress('S'); + $this->lastTestFailed = TRUE; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + if ($this->numTests == -1) { + $this->numTests = count($suite); + $this->numTestsWidth = strlen((string)$this->numTests); + } else { + $this->indent++; + } + + if ($this->verbose) { + $name = $suite->getName(); + + if (empty($name)) { + $name = 'Test Suite'; + } else { + $name = preg_replace( '(^.*::(.*?)$)', '\\1', $name ); + } + + $this->write( + sprintf( + "%s%s%s", + + $this->lastEvent == self::EVENT_TESTSUITE_END || + $suite instanceof PHPUnit_Framework_TestSuite_DataProvider ? + "\n" : + '', + str_repeat(' ', $this->indent), + $name + ) + ); + + $this->writeNewLine(); + } + + $this->lastEvent = self::EVENT_TESTSUITE_START; + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->indent--; + + if ($this->verbose) { + if ($this->lastEvent != self::EVENT_TESTSUITE_END) { + $this->writeNewLine(); + } + } + + $this->lastEvent = self::EVENT_TESTSUITE_END; + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->lastEvent = self::EVENT_TEST_START; + + if ($this->debug) { + $this->write( + sprintf( + "\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test) + ) + ); + } + + $this->numTestsRun++; + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if (!$this->lastTestFailed) { + $this->writeProgress('.'); + } + + if ($test instanceof PHPUnit_Framework_TestCase) { + $this->numAssertions += $test->getNumAssertions(); + } + + $this->lastEvent = self::EVENT_TEST_END; + $this->lastTestFailed = FALSE; + } + + /** + * @param string $progress + */ + protected function writeProgress($progress) + { + $this->write($progress); + $this->column++; + + if ($this->column == 60) { + if (!$this->verbose) { + $this->write( + sprintf( + ' %' . $this->numTestsWidth . 'd / %' . + $this->numTestsWidth . "d", + + $this->numTestsRun, + $this->numTests + ) + ); + } + + $this->writeNewLine(); + } + } + + protected function writeNewLine() + { + $this->write("\n"); + + if ($this->verbose) { + $this->column = $this->indent; + $this->write(str_repeat(' ', max(0, $this->indent))); + } else { + $this->column = 0; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/TestRunner.php b/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/TestRunner.php new file mode 100644 index 00000000..76e74b3b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/TextUI/TestRunner.php @@ -0,0 +1,876 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Runner/BaseTestRunner.php'; +require_once 'PHPUnit/Extensions/RepeatedTest.php'; +require_once 'PHPUnit/Runner/StandardTestSuiteLoader.php'; +require_once 'PHPUnit/Runner/Version.php'; +require_once 'PHPUnit/TextUI/ResultPrinter.php'; +require_once 'PHPUnit/Util/Configuration.php'; +require_once 'PHPUnit/Util/PDO.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Report.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestRunner for the Command Line Interface (CLI) + * PHP SAPI Module. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_TextUI_TestRunner extends PHPUnit_Runner_BaseTestRunner +{ + const SUCCESS_EXIT = 0; + const FAILURE_EXIT = 1; + const EXCEPTION_EXIT = 2; + + /** + * @var PHPUnit_Runner_TestSuiteLoader + */ + protected $loader = NULL; + + /** + * @var PHPUnit_TextUI_ResultPrinter + */ + protected $printer = NULL; + + /** + * @var boolean + */ + protected static $versionStringPrinted = FALSE; + + /** + * @param PHPUnit_Runner_TestSuiteLoader $loader + * @since Method available since Release 3.4.0 + */ + public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = NULL) + { + $this->loader = $loader; + } + + /** + * @param mixed $test + * @param array $arguments + * @throws InvalidArgumentException + */ + public static function run($test, array $arguments = array()) + { + if ($test instanceof ReflectionClass) { + $test = new PHPUnit_Framework_TestSuite($test); + } + + if ($test instanceof PHPUnit_Framework_Test) { + $aTestRunner = new PHPUnit_TextUI_TestRunner; + + return $aTestRunner->doRun( + $test, + $arguments + ); + } else { + throw new InvalidArgumentException( + 'No test case or test suite found.' + ); + } + } + + /** + * Runs a single test and waits until the user types RETURN. + * + * @param PHPUnit_Framework_Test $suite + */ + public static function runAndWait(PHPUnit_Framework_Test $suite) + { + $aTestRunner = new PHPUnit_TextUI_TestRunner; + + $aTestRunner->doRun( + $suite, + array( + 'wait' => TRUE + ) + ); + + } + + /** + * @return PHPUnit_Framework_TestResult + */ + protected function createTestResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * @param PHPUnit_Framework_Test $suite + * @param array $arguments + * @return PHPUnit_Framework_TestResult + */ + public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) + { + $this->handleConfiguration($arguments); + + if (isset($arguments['bootstrap'])) { + $bootstrap = PHPUnit_Util_Fileloader::load($arguments['bootstrap']); + + if ($bootstrap) { + $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $bootstrap; + } + } + + if ($arguments['backupGlobals'] === FALSE) { + $suite->setBackupGlobals(FALSE); + } + + if ($arguments['backupStaticAttributes'] === TRUE) { + $suite->setBackupStaticAttributes(TRUE); + } + + if (is_integer($arguments['repeat'])) { + $suite = new PHPUnit_Extensions_RepeatedTest( + $suite, + $arguments['repeat'], + $arguments['filter'], + $arguments['groups'], + $arguments['excludeGroups'], + $arguments['processIsolation'] + ); + } + + $result = $this->createTestResult(); + + if (!$arguments['convertErrorsToExceptions']) { + $result->convertErrorsToExceptions(FALSE); + } + + if (!$arguments['convertNoticesToExceptions']) { + PHPUnit_Framework_Error_Notice::$enabled = FALSE; + } + + if (!$arguments['convertWarningsToExceptions']) { + PHPUnit_Framework_Error_Warning::$enabled = FALSE; + } + + if ($arguments['stopOnFailure']) { + $result->stopOnFailure(TRUE); + } + + if ($this->printer === NULL) { + if (isset($arguments['printer']) && + $arguments['printer'] instanceof PHPUnit_Util_Printer) { + $this->printer = $arguments['printer']; + } else { + $this->printer = new PHPUnit_TextUI_ResultPrinter( + NULL, + $arguments['verbose'], + $arguments['colors'], + $arguments['debug'] + ); + } + } + + if (!$this->printer instanceof PHPUnit_Util_Log_TAP && + !self::$versionStringPrinted) { + $this->printer->write( + PHPUnit_Runner_Version::getVersionString() . "\n\n" + ); + } + + foreach ($arguments['listeners'] as $listener) { + $result->addListener($listener); + } + + $result->addListener($this->printer); + + if (isset($arguments['storyHTMLFile'])) { + require_once 'PHPUnit/Extensions/Story/ResultPrinter/HTML.php'; + + $result->addListener( + new PHPUnit_Extensions_Story_ResultPrinter_HTML( + $arguments['storyHTMLFile'] + ) + ); + } + + if (isset($arguments['storyTextFile'])) { + require_once 'PHPUnit/Extensions/Story/ResultPrinter/Text.php'; + + $result->addListener( + new PHPUnit_Extensions_Story_ResultPrinter_Text( + $arguments['storyTextFile'] + ) + ); + } + + if (isset($arguments['testdoxHTMLFile'])) { + require_once 'PHPUnit/Util/TestDox/ResultPrinter/HTML.php'; + + $result->addListener( + new PHPUnit_Util_TestDox_ResultPrinter_HTML( + $arguments['testdoxHTMLFile'] + ) + ); + } + + if (isset($arguments['testdoxTextFile'])) { + require_once 'PHPUnit/Util/TestDox/ResultPrinter/Text.php'; + + $result->addListener( + new PHPUnit_Util_TestDox_ResultPrinter_Text( + $arguments['testdoxTextFile'] + ) + ); + } + + if (isset($arguments['graphvizLogfile'])) { + if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Image/GraphViz.php')) { + require_once 'PHPUnit/Util/Log/GraphViz.php'; + + $result->addListener( + new PHPUnit_Util_Log_GraphViz($arguments['graphvizLogfile']) + ); + } + } + + if ((isset($arguments['coverageClover']) || + isset($arguments['coverageSource']) || + isset($arguments['metricsXML']) || + isset($arguments['pmdXML']) || + isset($arguments['reportDirectory'])) && + extension_loaded('xdebug')) { + $result->collectCodeCoverageInformation(TRUE); + } + + if (isset($arguments['jsonLogfile'])) { + require_once 'PHPUnit/Util/Log/JSON.php'; + + $result->addListener( + new PHPUnit_Util_Log_JSON($arguments['jsonLogfile']) + ); + } + + if (isset($arguments['tapLogfile'])) { + require_once 'PHPUnit/Util/Log/TAP.php'; + + $result->addListener( + new PHPUnit_Util_Log_TAP($arguments['tapLogfile']) + ); + } + + if (isset($arguments['junitLogfile'])) { + require_once 'PHPUnit/Util/Log/JUnit.php'; + + $result->addListener( + new PHPUnit_Util_Log_JUnit( + $arguments['junitLogfile'], $arguments['logIncompleteSkipped'] + ) + ); + } + + if (isset($arguments['testDatabaseDSN']) && + isset($arguments['testDatabaseLogRevision']) && + extension_loaded('pdo')) { + $writeToTestDatabase = TRUE; + } else { + $writeToTestDatabase = FALSE; + } + + if ($writeToTestDatabase) { + $dbh = PHPUnit_Util_PDO::factory($arguments['testDatabaseDSN']); + + require_once 'PHPUnit/Util/Log/Database.php'; + + $dbListener = PHPUnit_Util_Log_Database::getInstance( + $dbh, + $arguments['testDatabaseLogRevision'], + isset($arguments['testDatabaseLogInfo']) ? $arguments['testDatabaseLogInfo'] : '' + ); + + $result->addListener($dbListener); + $result->collectCodeCoverageInformation(TRUE); + } + + $suite->run( + $result, + $arguments['filter'], + $arguments['groups'], + $arguments['excludeGroups'], + $arguments['processIsolation'] + ); + + unset($suite); + $result->flushListeners(); + + if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) { + $this->printer->printResult($result); + } + + if (extension_loaded('tokenizer') && extension_loaded('xdebug')) { + if (isset($arguments['coverageClover'])) { + $this->printer->write( + "\nWriting code coverage data to XML file, " . + 'this may take a moment.' + ); + + require_once 'PHPUnit/Util/Log/CodeCoverage/XML/Clover.php'; + + $writer = new PHPUnit_Util_Log_CodeCoverage_XML_Clover( + $arguments['coverageClover'] + ); + + $writer->process($result); + $this->printer->write("\n"); + } + + if (isset($arguments['coverageSource'])) { + $this->printer->write( + "\nWriting code coverage data to XML files, " . + 'this may take a moment.' + ); + + require_once 'PHPUnit/Util/Log/CodeCoverage/XML/Source.php'; + + $writer = new PHPUnit_Util_Log_CodeCoverage_XML_Source( + $arguments['coverageSource'] + ); + + $writer->process($result); + $this->printer->write("\n"); + } + + if ($writeToTestDatabase) { + $this->printer->write( + "\nStoring code coverage and software metrics data in " . + "database.\nThis may take a moment." + ); + + require_once 'PHPUnit/Util/Log/CodeCoverage/Database.php'; + + $testDb = new PHPUnit_Util_Log_CodeCoverage_Database($dbh); + $testDb->storeCodeCoverage( + $result, + $dbListener->getRunId(), + $arguments['testDatabaseLogRevision'], + $arguments['testDatabasePrefix'] + ); + + $this->printer->write("\n"); + } + + if (isset($arguments['metricsXML'])) { + $this->printer->write( + "\nWriting metrics report XML file, this may take a moment." + ); + + require_once 'PHPUnit/Util/Log/Metrics.php'; + + $writer = new PHPUnit_Util_Log_Metrics( + $arguments['metricsXML'] + ); + + $writer->process($result); + $this->printer->write("\n"); + } + + if (isset($arguments['pmdXML'])) { + require_once 'PHPUnit/Util/Log/PMD.php'; + + $writer = new PHPUnit_Util_Log_PMD( + $arguments['pmdXML'], $arguments['pmd'] + ); + + $this->printer->write( + "\nWriting violations report XML file, " . + 'this may take a moment.' + ); + + $writer->process($result); + + require_once 'PHPUnit/Util/Log/CPD.php'; + + $writer = new PHPUnit_Util_Log_CPD( + str_replace('.xml', '-cpd.xml', $arguments['pmdXML']) + ); + + $writer->process( + $result, + $arguments['cpdMinLines'], + $arguments['cpdMinMatches'] + ); + + $this->printer->write("\n"); + } + + if (isset($arguments['reportDirectory'])) { + $this->printer->write( + "\nGenerating code coverage report, this may take a moment." + ); + + $title = ''; + + if (isset($arguments['configuration'])) { + $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration(); + + if (isset($loggingConfiguration['title'])) { + $title = $loggingConfiguration['title']; + } + } + + PHPUnit_Util_Report::render( + $result, + $arguments['reportDirectory'], + $title, + $arguments['reportCharset'], + $arguments['reportYUI'], + $arguments['reportHighlight'], + $arguments['reportLowUpperBound'], + $arguments['reportHighLowerBound'] + ); + + $this->printer->write("\n"); + } + } + + $this->pause($arguments['wait']); + + return $result; + } + + /** + * @param boolean $wait + */ + protected function pause($wait) + { + if (!$wait) { + return; + } + + if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) { + $this->printer->printWaitPrompt(); + } + + fgets(STDIN); + } + + /** + * @param PHPUnit_TextUI_ResultPrinter $resultPrinter + */ + public function setPrinter(PHPUnit_TextUI_ResultPrinter $resultPrinter) + { + $this->printer = $resultPrinter; + } + + /** + * Override to define how to handle a failed loading of + * a test suite. + * + * @param string $message + */ + protected function runFailed($message) + { + self::printVersionString(); + self::write($message); + exit(self::FAILURE_EXIT); + } + + /** + * @param string $buffer + * @since Method available since Release 3.1.0 + */ + protected static function write($buffer) + { + if (PHP_SAPI != 'cli') { + $buffer = htmlspecialchars($buffer); + } + + print $buffer; + } + + /** + * Returns the loader to be used. + * + * @return PHPUnit_Runner_TestSuiteLoader + * @since Method available since Release 2.2.0 + */ + public function getLoader() + { + if ($this->loader === NULL) { + $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader; + } + + return $this->loader; + } + + /** + */ + public static function showError($message) + { + self::printVersionString(); + self::write($message . "\n"); + + exit(self::FAILURE_EXIT); + } + + /** + */ + public static function printVersionString() + { + if (!self::$versionStringPrinted) { + self::write(PHPUnit_Runner_Version::getVersionString() . "\n\n"); + self::$versionStringPrinted = TRUE; + } + } + + /** + * @param array $arguments + * @since Method available since Release 3.2.1 + */ + protected function handleConfiguration(array &$arguments) + { + if (isset($arguments['configuration']) && + !$arguments['configuration'] instanceof PHPUnit_Util_Configuration) { + $arguments['configuration'] = PHPUnit_Util_Configuration::getInstance( + $arguments['configuration'] + ); + + $arguments['pmd'] = $arguments['configuration']->getPMDConfiguration(); + } else { + $arguments['pmd'] = array(); + } + + $arguments['debug'] = isset($arguments['debug']) ? $arguments['debug'] : FALSE; + $arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : FALSE; + $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); + $arguments['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : FALSE; + $arguments['testDatabasePrefix'] = isset($arguments['testDatabasePrefix']) ? $arguments['testDatabasePrefix'] : ''; + $arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : FALSE; + $arguments['wait'] = isset($arguments['wait']) ? $arguments['wait'] : FALSE; + + if (isset($arguments['configuration'])) { + $arguments['configuration']->handlePHPConfiguration(); + + $filterConfiguration = $arguments['configuration']->getFilterConfiguration(); + + PHPUnit_Util_Filter::$addUncoveredFilesFromWhitelist = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist']; + + foreach ($filterConfiguration['blacklist']['include']['directory'] as $dir) { + PHPUnit_Util_Filter::addDirectoryToFilter( + $dir['path'], $dir['suffix'], $dir['group'], $dir['prefix'] + ); + } + + foreach ($filterConfiguration['blacklist']['include']['file'] as $file) { + PHPUnit_Util_Filter::addFileToFilter($file); + } + + foreach ($filterConfiguration['blacklist']['exclude']['directory'] as $dir) { + PHPUnit_Util_Filter::removeDirectoryFromFilter( + $dir['path'], $dir['suffix'], $dir['group'], $dir['prefix'] + ); + } + + foreach ($filterConfiguration['blacklist']['exclude']['file'] as $file) { + PHPUnit_Util_Filter::removeFileFromFilter($file); + } + + foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) { + PHPUnit_Util_Filter::addDirectoryToWhitelist( + $dir['path'], $dir['suffix'], $dir['prefix'] + ); + } + + foreach ($filterConfiguration['whitelist']['include']['file'] as $file) { + PHPUnit_Util_Filter::addFileToWhitelist($file); + } + + foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) { + PHPUnit_Util_Filter::removeDirectoryFromWhitelist( + $dir['path'], $dir['suffix'], $dir['prefix'] + ); + } + + foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) { + PHPUnit_Util_Filter::removeFileFromWhitelist($file); + } + + $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration(); + + if (isset($phpunitConfiguration['backupGlobals']) && + !isset($arguments['backupGlobals'])) { + $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals']; + } + + if (isset($phpunitConfiguration['backupStaticAttributes']) && + !isset($arguments['backupStaticAttributes'])) { + $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes']; + } + + if (isset($phpunitConfiguration['bootstrap']) && + !isset($arguments['bootstrap'])) { + $arguments['bootstrap'] = $phpunitConfiguration['bootstrap']; + } + + if (isset($phpunitConfiguration['colors']) && + !isset($arguments['colors'])) { + $arguments['colors'] = $phpunitConfiguration['colors']; + } + + if (isset($phpunitConfiguration['convertErrorsToExceptions']) && + !isset($arguments['convertErrorsToExceptions'])) { + $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions']; + } + + if (isset($phpunitConfiguration['convertNoticesToExceptions']) && + !isset($arguments['convertNoticesToExceptions'])) { + $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions']; + } + + if (isset($phpunitConfiguration['convertWarningsToExceptions']) && + !isset($arguments['convertWarningsToExceptions'])) { + $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions']; + } + + if (isset($phpunitConfiguration['processIsolation']) && + !isset($arguments['processIsolation'])) { + $arguments['processIsolation'] = $phpunitConfiguration['processIsolation']; + } + + if (isset($phpunitConfiguration['stopOnFailure']) && + !isset($arguments['stopOnFailure'])) { + $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure']; + } + + $groupConfiguration = $arguments['configuration']->getGroupConfiguration(); + + if (!empty($groupConfiguration['include']) && + !isset($arguments['groups'])) { + $arguments['groups'] = $groupConfiguration['include']; + } + + if (!empty($groupConfiguration['exclude']) && + !isset($arguments['excludeGroups'])) { + $arguments['excludeGroups'] = $groupConfiguration['exclude']; + } + + foreach ($arguments['configuration']->getListenerConfiguration() as $listener) { + if (!class_exists($listener['class'], FALSE) && + $listener['file'] !== '') { + $file = PHPUnit_Util_Filesystem::fileExistsInIncludePath( + $listener['file'] + ); + + if ($file !== FALSE) { + require $file; + } + } + + if (class_exists($listener['class'], FALSE)) { + if (count($listener['arguments']) == 0) { + $listener = new $listener['class']; + } else { + $listenerClass = new ReflectionClass( + $listener['class'] + ); + $listener = $listenerClass->newInstanceArgs( + $listener['arguments'] + ); + } + + if ($listener instanceof PHPUnit_Framework_TestListener) { + $arguments['listeners'][] = $listener; + } + } + } + + $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration(); + + if (isset($loggingConfiguration['coverage-html']) && + !isset($arguments['reportDirectory'])) { + if (isset($loggingConfiguration['charset']) && + !isset($arguments['reportCharset'])) { + $arguments['reportCharset'] = $loggingConfiguration['charset']; + } + + if (isset($loggingConfiguration['yui']) && + !isset($arguments['reportYUI'])) { + $arguments['reportYUI'] = $loggingConfiguration['yui']; + } + + if (isset($loggingConfiguration['highlight']) && + !isset($arguments['reportHighlight'])) { + $arguments['reportHighlight'] = $loggingConfiguration['highlight']; + } + + if (isset($loggingConfiguration['lowUpperBound']) && + !isset($arguments['reportLowUpperBound'])) { + $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound']; + } + + if (isset($loggingConfiguration['highLowerBound']) && + !isset($arguments['reportHighLowerBound'])) { + $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound']; + } + + $arguments['reportDirectory'] = $loggingConfiguration['coverage-html']; + } + + if (isset($loggingConfiguration['coverage-clover']) && + !isset($arguments['coverageClover'])) { + $arguments['coverageClover'] = $loggingConfiguration['coverage-clover']; + } + + if (isset($loggingConfiguration['coverage-xml']) && + !isset($arguments['coverageClover'])) { + $arguments['coverageClover'] = $loggingConfiguration['coverage-xml']; + } + + if (isset($loggingConfiguration['coverage-source']) && + !isset($arguments['coverageSource'])) { + $arguments['coverageSource'] = $loggingConfiguration['coverage-source']; + } + + if (isset($loggingConfiguration['graphviz']) && + !isset($arguments['graphvizLogfile'])) { + $arguments['graphvizLogfile'] = $loggingConfiguration['graphviz']; + } + + if (isset($loggingConfiguration['json']) && + !isset($arguments['jsonLogfile'])) { + $arguments['jsonLogfile'] = $loggingConfiguration['json']; + } + + if (isset($loggingConfiguration['metrics-xml']) && + !isset($arguments['metricsXML'])) { + $arguments['metricsXML'] = $loggingConfiguration['metrics-xml']; + } + + if (isset($loggingConfiguration['plain'])) { + $arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter($loggingConfiguration['plain'], TRUE); + } + + if (isset($loggingConfiguration['pmd-xml']) && + !isset($arguments['pmdXML'])) { + if (isset($loggingConfiguration['cpdMinLines']) && + !isset($arguments['cpdMinLines'])) { + $arguments['cpdMinLines'] = $loggingConfiguration['cpdMinLines']; + } + + if (isset($loggingConfiguration['cpdMinMatches']) && + !isset($arguments['cpdMinMatches'])) { + $arguments['cpdMinMatches'] = $loggingConfiguration['cpdMinMatches']; + } + + $arguments['pmdXML'] = $loggingConfiguration['pmd-xml']; + } + + if (isset($loggingConfiguration['tap']) && + !isset($arguments['tapLogfile'])) { + $arguments['tapLogfile'] = $loggingConfiguration['tap']; + } + + if (isset($loggingConfiguration['junit']) && + !isset($arguments['junitLogfile'])) { + $arguments['junitLogfile'] = $loggingConfiguration['junit']; + + if (isset($loggingConfiguration['logIncompleteSkipped']) && !isset($arguments['logIncompleteSkipped'])) { + $arguments['logIncompleteSkipped'] = $loggingConfiguration['logIncompleteSkipped']; + } + } + + if (isset($loggingConfiguration['story-html']) && + !isset($arguments['storyHTMLFile'])) { + $arguments['storyHTMLFile'] = $loggingConfiguration['story-html']; + } + + if (isset($loggingConfiguration['story-text']) && + !isset($arguments['storyTextFile'])) { + $arguments['storsTextFile'] = $loggingConfiguration['story-text']; + } + + if (isset($loggingConfiguration['testdox-html']) && + !isset($arguments['testdoxHTMLFile'])) { + $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html']; + } + + if (isset($loggingConfiguration['testdox-text']) && + !isset($arguments['testdoxTextFile'])) { + $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text']; + } + } + + $arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : NULL; + $arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : NULL; + $arguments['cpdMinLines'] = isset($arguments['cpdMinLines']) ? $arguments['cpdMinLines'] : 5; + $arguments['cpdMinMatches'] = isset($arguments['cpdMinMatches']) ? $arguments['cpdMinMatches'] : 70; + $arguments['colors'] = isset($arguments['colors']) ? $arguments['colors'] : FALSE; + $arguments['convertErrorsToExceptions'] = isset($arguments['convertErrorsToExceptions']) ? $arguments['convertErrorsToExceptions'] : TRUE; + $arguments['convertNoticesToExceptions'] = isset($arguments['convertNoticesToExceptions']) ? $arguments['convertNoticesToExceptions'] : TRUE; + $arguments['convertWarningsToExceptions'] = isset($arguments['convertWarningsToExceptions']) ? $arguments['convertWarningsToExceptions'] : TRUE; + $arguments['excludeGroups'] = isset($arguments['excludeGroups']) ? $arguments['excludeGroups'] : array(); + $arguments['groups'] = isset($arguments['groups']) ? $arguments['groups'] : array(); + $arguments['logIncompleteSkipped'] = isset($arguments['logIncompleteSkipped']) ? $arguments['logIncompleteSkipped'] : FALSE; + $arguments['processIsolation'] = isset($arguments['processIsolation']) ? $arguments['processIsolation'] : FALSE; + $arguments['reportCharset'] = isset($arguments['reportCharset']) ? $arguments['reportCharset'] : 'ISO-8859-1'; + $arguments['reportHighlight'] = isset($arguments['reportHighlight']) ? $arguments['reportHighlight'] : FALSE; + $arguments['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 70; + $arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 35; + $arguments['reportYUI'] = isset($arguments['reportYUI']) ? $arguments['reportYUI'] : TRUE; + $arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : FALSE; + + if ($arguments['filter'] !== FALSE && + preg_match('/^[a-zA-Z0-9_]/', $arguments['filter'])) { + $arguments['filter'] = '/' . $arguments['filter'] . '/'; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Class.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Class.php new file mode 100644 index 00000000..7164a02e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Class.php @@ -0,0 +1,481 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +if (!defined('T_NAMESPACE')) { + define('T_NAMESPACE', 377); +} + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Class helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Util_Class +{ + protected static $buffer = array(); + + /** + * Starts the collection of loaded classes. + * + */ + public static function collectStart() + { + self::$buffer = get_declared_classes(); + } + + /** + * Stops the collection of loaded classes and + * returns the names of the loaded classes. + * + * @return array + */ + public static function collectEnd() + { + return array_values( + array_diff(get_declared_classes(), self::$buffer) + ); + } + + /** + * Stops the collection of loaded classes and + * returns the names of the files that declare the loaded classes. + * + * @return array + */ + public static function collectEndAsFiles() + { + $result = self::collectEnd(); + $count = count($result); + + for ($i = 0; $i < $count; $i++) { + $class = new ReflectionClass($result[$i]); + + if ($class->isUserDefined()) { + $file = $class->getFileName(); + + if (file_exists($file)) { + $result[$i] = $file; + } else { + unset($result[$i]); + } + } + } + + return $result; + } + + /** + * Returns the class hierarchy for a given class. + * + * @param string $className + * @param boolean $asReflectionObjects + * @return array + */ + public static function getHierarchy($className, $asReflectionObjects = FALSE) + { + if ($asReflectionObjects) { + $classes = array(new ReflectionClass($className)); + } else { + $classes = array($className); + } + + $done = FALSE; + + while (!$done) { + if ($asReflectionObjects) { + $class = new ReflectionClass( + $classes[count($classes)-1]->getName() + ); + } else { + $class = new ReflectionClass($classes[count($classes)-1]); + } + + $parent = $class->getParentClass(); + + if ($parent !== FALSE) { + if ($asReflectionObjects) { + $classes[] = $parent; + } else { + $classes[] = $parent->getName(); + } + } else { + $done = TRUE; + } + } + + return $classes; + } + + /** + * Returns the parameters of a function or method. + * + * @param ReflectionFunction|ReflectionMethod $method + * @return string + * @since Method available since Release 3.2.0 + */ + public static function getMethodParameters($method) + { + $parameters = array(); + + foreach ($method->getParameters() as $i => $parameter) { + $name = '$' . $parameter->getName(); + + if ($name === '$') { + $name .= 'arg' . $i; + } + + $typeHint = ''; + + if ($parameter->isArray()) { + $typeHint = 'array '; + } else { + try { + $class = $parameter->getClass(); + } + + catch (ReflectionException $e) { + $class = FALSE; + } + + if ($class) { + $typeHint = $class->getName() . ' '; + } + } + + $default = ''; + + if ($parameter->isDefaultValueAvailable()) { + $value = $parameter->getDefaultValue(); + $default = ' = ' . var_export($value, TRUE); + } + + else if ($parameter->isOptional()) { + $default = ' = null'; + } + + $ref = ''; + + if ($parameter->isPassedByReference()) { + $ref = '&'; + } + + $parameters[] = $typeHint . $ref . $name . $default; + } + + return join(', ', $parameters); + } + + /** + * Returns the sourcecode of a user-defined class. + * + * @param string $className + * @param string $methodName + * @return mixed + */ + public static function getMethodSource($className, $methodName) + { + if ($className != 'global') { + $function = new ReflectionMethod($className, $methodName); + } else { + $function = new ReflectionFunction($methodName); + } + + $filename = $function->getFileName(); + + if (file_exists($filename)) { + $file = file($filename); + $result = ''; + $start = $function->getStartLine() - 1; + $end = $function->getEndLine() - 1; + + for ($line = $start; $line <= $end; $line++) { + $result .= $file[$line]; + } + + return $result; + } else { + return FALSE; + } + } + + /** + * Returns the package information of a user-defined class. + * + * @param string $className + * @param string $docComment + * @return array + */ + public static function getPackageInformation($className, $docComment) + { + $result = array( + 'namespace' => '', + 'fullPackage' => '', + 'category' => '', + 'package' => '', + 'subpackage' => '' + ); + + if (strpos($className, '\\') !== FALSE) { + $result['namespace'] = self::arrayToName( + explode('\\', $className) + ); + } + + if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['category'] = $matches[1]; + } + + if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['package'] = $matches[1]; + $result['fullPackage'] = $matches[1]; + } + + if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['subpackage'] = $matches[1]; + $result['fullPackage'] .= '.' . $matches[1]; + } + + if (empty($result['fullPackage'])) { + $result['fullPackage'] = self::arrayToName( + explode('_', str_replace('\\', '_', $className)), '.' + ); + } + + return $result; + } + + /** + * Returns the value of a static attribute. + * This also works for attributes that are declared protected or private. + * + * @param string $className + * @param string $attributeName + * @return mixed + * @throws InvalidArgumentException + * @since Method available since Release 3.4.0 + */ + public static function getStaticAttribute($className, $attributeName) + { + if (!is_string($className)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!class_exists($className)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name'); + } + + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $class = new ReflectionClass($className); + + while ($class) { + $attributes = $class->getStaticProperties(); + + if (array_key_exists($attributeName, $attributes)) { + return $attributes[$attributeName]; + } + + $class = $class->getParentClass(); + } + + throw new PHPUnit_Framework_Exception( + sprintf( + 'Attribute "%s" not found in class.', + + $attributeName + ) + ); + } + + /** + * Returns the value of an object's attribute. + * This also works for attributes that are declared protected or private. + * + * @param object $object + * @param string $attributeName + * @return mixed + * @throws InvalidArgumentException + * @since Method available since Release 3.4.0 + */ + public static function getObjectAttribute($object, $attributeName) + { + if (!is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'object'); + } + + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + PHPUnit_Framework_Assert::assertObjectHasAttribute( + $attributeName, $object + ); + + try { + $attribute = new ReflectionProperty($object, $attributeName); + } + + catch (ReflectionException $e) { + // Workaround for http://bugs.php.net/46064 + if (version_compare(PHP_VERSION, '5.2.7', '<')) { + $reflector = new ReflectionObject($object); + $attributes = $reflector->getProperties(); + + foreach ($attributes as $_attribute) { + if ($_attribute->getName() == $attributeName) { + $attribute = $_attribute; + break; + } + } + } + + $reflector = new ReflectionObject($object); + + while ($reflector = $reflector->getParentClass()) { + try { + $attribute = $reflector->getProperty($attributeName); + break; + } + + catch(ReflectionException $e) { + } + } + } + + if ($attribute->isPublic()) { + return $object->$attributeName; + } else { + $array = (array)$object; + $protectedName = "\0*\0" . $attributeName; + + if (array_key_exists($protectedName, $array)) { + return $array[$protectedName]; + } else { + $classes = self::getHierarchy(get_class($object)); + + foreach ($classes as $class) { + $privateName = sprintf( + "\0%s\0%s", + + $class, + $attributeName + ); + + if (array_key_exists($privateName, $array)) { + return $array[$privateName]; + } + } + } + } + + throw new PHPUnit_Framework_Exception( + sprintf( + 'Attribute "%s" not found in object.', + + $attributeName + ) + ); + } + + /** + * + * + * @param string $className + * @return array + * @since Method available since Release 3.4.0 + */ + public static function parseFullyQualifiedClassName($className) + { + $result = array( + 'namespace' => '', + 'className' => $className, + 'fullyQualifiedClassName' => $className + ); + + if (strpos($className, '\\') !== FALSE) { + $tmp = explode('\\', $className); + $result['className'] = $tmp[count($tmp)-1]; + $result['namespace'] = self::arrayToName($tmp); + } + + return $result; + } + + /** + * Returns the package information of a user-defined class. + * + * @param array $parts + * @param string $join + * @return string + * @since Method available since Release 3.2.12 + */ + protected static function arrayToName(array $parts, $join = '\\') + { + $result = ''; + + if (count($parts) > 1) { + array_pop($parts); + + $result = join($join, $parts); + } + + return $result; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/CodeCoverage.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/CodeCoverage.php new file mode 100644 index 00000000..3c25bd2f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/CodeCoverage.php @@ -0,0 +1,344 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Code Coverage helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + * @abstract + */ +abstract class PHPUnit_Util_CodeCoverage +{ + /** + * @var array + */ + protected static $lineToTestMap = array(); + + /** + * @var array + */ + protected static $summary = array(); + + /** + * Returns only the executed lines. + * + * @param array $data + * @return array + * @since Method available since Release 3.3.15 + */ + public static function getExecutedLines(array $data) + { + return self::getLinesByStatus($data, 1); + } + + /** + * Returns only the executable lines. + * + * @param array $data + * @return array + * @since Method available since Release 3.3.15 + */ + public static function getExecutableLines(array $data) + { + return self::getLinesByStatus($data, array(-1, 1)); + } + + /** + * Returns only the lines that were not executed. + * + * @param array $data + * @return array + * @since Method available since Release 3.3.15 + */ + public static function getNotExecutedLines(array $data) + { + return self::getLinesByStatus($data, -1); + } + + /** + * Returns only the dead code lines. + * + * @param array $data + * @return array + * @since Method available since Release 3.3.15 + */ + public static function getDeadLines(array $data) + { + return self::getLinesByStatus($data, -2); + } + + /** + * Filters lines by status. + * + * @param array $data + * @param array|integer $status + * @return array + * @since Method available since Release 3.3.15 + */ + protected static function getLinesByStatus(array $data, $status) + { + if (!is_array($status)) { + $status = array($status); + } + + $isFileCache = array(); + $result = array(); + + foreach ($data as $file => $coverage) { + if (!isset($isFileCache[$file])) { + $isFileCache[$file] = self::isFile($file); + } + + if (!$isFileCache[$file]) { + continue; + } + + $result[$file] = array(); + + foreach ($coverage as $line => $_status) { + if (in_array($_status, $status)) { + $result[$file][$line] = $_status; + } + } + } + + return $result; + } + + /** + * Returns the tests that cover a given line. + * + * @param array $data + * @param string $file + * @param string $line + * @param boolean $clear + * @return array + */ + public static function getCoveringTests(array &$data, $file, $line, $clear = FALSE) + { + if (empty(self::$lineToTestMap) || $clear) { + foreach ($data as $test) { + foreach ($test['files'] as $_file => $lines) { + foreach ($lines as $_line => $flag) { + if ($flag > 0) { + if (!isset(self::$lineToTestMap[$_file][$_line])) { + self::$lineToTestMap[$_file][$_line] = array( + $test['test'] + ); + } else { + self::$lineToTestMap[$_file][$_line][] = $test['test']; + } + } + } + } + } + } + + if (isset(self::$lineToTestMap[$file][$line])) { + return self::$lineToTestMap[$file][$line]; + } else { + return FALSE; + } + } + + /** + * Returns summarized code coverage data. + * + * Format of the result array: + * + * + * array( + * "/tested/code.php" => array( + * linenumber => array(tests that executed the line) + * ) + * ) + * + * + * @param array $data + * @param boolean $clear + * @return array + */ + public static function getSummary(array &$data, $clear = FALSE) + { + if (empty(self::$summary) || $clear) { + foreach ($data as $test) { + foreach ($test['files'] as $file => $lines) { + foreach ($lines as $line => $flag) { + if ($flag == 1) { + if (isset(self::$summary[$file][$line][0])) { + self::$summary[$file][$line][] = $test['test']; + } else { + self::$summary[$file][$line] = array( + $test['test'] + ); + } + } + + else if (!isset(self::$summary[$file][$line])) { + self::$summary[$file][$line] = $flag; + } + } + } + + if (isset($test['executable'])) { + foreach ($test['executable'] as $file => $lines) { + foreach ($lines as $line => $flag) { + if ($flag == 1 && + !isset(self::$summary[$file][$line][0])) { + self::$summary[$file][$line] = -1; + } + + else if (!isset(self::$summary[$file][$line])) { + self::$summary[$file][$line] = $flag; + } + } + } + } + + if (isset($test['dead'])) { + foreach ($test['dead'] as $file => $lines) { + foreach ($lines as $line => $flag) { + if ($flag == -2 && + !isset(self::$summary[$file][$line][0])) { + self::$summary[$file][$line] = -2; + } + } + } + } + } + } + + return self::$summary; + } + + /** + * Returns the coverage statistics for a section of a file. + * + * @param array $data + * @param string $filename + * @param integer $startLine + * @param integer $endLine + * @return array + * @since Method available since Release 3.2.0 + */ + public static function getStatistics(array &$data, $filename, $startLine = 1, $endLine = FALSE) + { + $coverage = 0; + $locExecutable = 0; + $locExecuted = 0; + + if (isset($data[$filename])) { + if ($endLine == FALSE) { + $endLine = count(file($filename)); + } + + foreach ($data[$filename] as $line => $_data) { + if ($line >= $startLine && $line < $endLine) { + if (is_array($_data)) { + $locExecutable++; + $locExecuted++; + } + + else if ($_data == -1) { + $locExecutable++; + } + } + } + + if ($locExecutable > 0) { + $coverage = ($locExecuted / $locExecutable) * 100; + } else { + $coverage = 100; + } + } + + return array( + 'coverage' => $coverage, + 'loc' => $endLine - $startLine + 1, + 'locExecutable' => $locExecutable, + 'locExecuted' => $locExecuted + ); + } + + /** + * Checks whether a file (as seen by Xdebug) is actually a file. + * + * @param string $file + * @return boolean + */ + public static function isFile($file) + { + if (strpos($file, 'eval()\'d code') || + strpos($file, 'runtime-created function') || + strpos($file, 'assert code') || + strpos($file, 'regexp code')) { + return FALSE; + } + + return TRUE; + } + + /** + * Clears the cached summary information. + * + * @since Method available since Release 3.3.0 + */ + public static function clearSummary() + { + self::$summary = array(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Configuration.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Configuration.php new file mode 100644 index 00000000..20c2c091 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Configuration.php @@ -0,0 +1,837 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Runner/IncludePathTestCollector.php'; +require_once 'PHPUnit/Util/XML.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Wrapper for the PHPUnit XML configuration file. + * + * Example XML configuration file: + * + * + * + * + * + * + * /path/to/files + * /path/to/MyTest.php + * + * + * + * + * + * name + * + * + * name + * + * + * + * + * + * /path/to/files + * /path/to/file + * + * /path/to/files + * /path/to/file + * + * + * + * /path/to/files + * /path/to/file + * + * /path/to/files + * /path/to/file + * + * + * + * + * + * + * + * + * + * Sebastian + * + * + * 22 + * April + * 19.78 + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Configuration +{ + private static $instances = array(); + + protected $document; + protected $xpath; + + /** + * Loads a PHPUnit configuration file. + * + * @param string $filename + */ + protected function __construct($filename) + { + $this->document = PHPUnit_Util_XML::loadFile($filename); + $this->xpath = new DOMXPath($this->document); + } + + /** + * @since Method available since Release 3.4.0 + */ + private final function __clone() + { + } + + /** + * Returns a PHPUnit configuration object. + * + * @param string $filename + * @return PHPUnit_Util_Configuration + * @since Method available since Release 3.4.0 + */ + public static function getInstance($filename) { + $realpath = realpath($filename); + + if ($realpath === FALSE) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not read "%s".', + $filename + ) + ); + } + + if (!isset(self::$instances[$realpath])) { + self::$instances[$realpath] = new PHPUnit_Util_Configuration($realpath); + } + + return self::$instances[$realpath]; + } + + /** + * Returns the configuration for SUT filtering. + * + * @return array + * @since Method available since Release 3.2.1 + */ + public function getFilterConfiguration() + { + $addUncoveredFilesFromWhitelist = TRUE; + + $tmp = $this->xpath->query('filter/whitelist'); + + if ($tmp->length == 1 && + $tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) { + $addUncoveredFilesFromWhitelist = $this->getBoolean( + (string)$tmp->item(0)->getAttribute('addUncoveredFilesFromWhitelist'), + TRUE + ); + } + + return array( + 'blacklist' => array( + 'include' => array( + 'directory' => $this->readFilterDirectories( + 'filter/blacklist/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/blacklist/file' + ) + ), + 'exclude' => array( + 'directory' => $this->readFilterDirectories( + 'filter/blacklist/exclude/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/blacklist/exclude/file' + ) + ) + ), + 'whitelist' => array( + 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist, + 'include' => array( + 'directory' => $this->readFilterDirectories( + 'filter/whitelist/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/whitelist/file' + ) + ), + 'exclude' => array( + 'directory' => $this->readFilterDirectories( + 'filter/whitelist/exclude/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/whitelist/exclude/file' + ) + ) + ) + ); + } + + /** + * Returns the configuration for groups. + * + * @return array + * @since Method available since Release 3.2.1 + */ + public function getGroupConfiguration() + { + $groups = array( + 'include' => array(), + 'exclude' => array() + ); + + foreach ($this->xpath->query('groups/include/group') as $group) { + $groups['include'][] = (string)$group->nodeValue; + } + + foreach ($this->xpath->query('groups/exclude/group') as $group) { + $groups['exclude'][] = (string)$group->nodeValue; + } + + return $groups; + } + + /** + * Returns the configuration for listeners. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function getListenerConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('listeners/listener') as $listener) { + $class = (string)$listener->getAttribute('class'); + $file = ''; + $arguments = array(); + + if ($listener->hasAttribute('file')) { + $file = (string)$listener->getAttribute('file'); + } + + if ($listener->childNodes->item(1) instanceof DOMElement && + $listener->childNodes->item(1)->tagName == 'arguments') { + foreach ($listener->childNodes->item(1)->childNodes as $argument) { + if ($argument instanceof DOMElement) { + $arguments[] = PHPUnit_Util_XML::xmlToVariable($argument); + } + } + } + + $result[] = array( + 'class' => $class, + 'file' => $file, + 'arguments' => $arguments + ); + } + + return $result; + } + + /** + * Returns the logging configuration. + * + * @return array + */ + public function getLoggingConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('logging/log') as $log) { + $type = (string)$log->getAttribute('type'); + $target = (string)$log->getAttribute('target'); + + if ($type == 'coverage-html') { + if ($log->hasAttribute('title')) { + $result['title'] = (string)$log->getAttribute('title'); + } + + if ($log->hasAttribute('charset')) { + $result['charset'] = (string)$log->getAttribute('charset'); + } + + if ($log->hasAttribute('lowUpperBound')) { + $result['lowUpperBound'] = (string)$log->getAttribute('lowUpperBound'); + } + + if ($log->hasAttribute('highLowerBound')) { + $result['highLowerBound'] = (string)$log->getAttribute('highLowerBound'); + } + + if ($log->hasAttribute('yui')) { + $result['yui'] = $this->getBoolean( + (string)$log->getAttribute('yui'), + FALSE + ); + } + + if ($log->hasAttribute('highlight')) { + $result['highlight'] = $this->getBoolean( + (string)$log->getAttribute('highlight'), + FALSE + ); + } + } + + else if ($type == 'pmd-xml') { + if ($log->hasAttribute('cpdMinLines')) { + $result['cpdMinLines'] = (string)$log->getAttribute('cpdMinLines'); + } + + if ($log->hasAttribute('cpdMinMatches')) { + $result['cpdMinMatches'] = (string)$log->getAttribute('cpdMinMatches'); + } + } + + else if ($type == 'junit' || $type == 'test-xml') { + if ($log->hasAttribute('logIncompleteSkipped')) { + $result['logIncompleteSkipped'] = $this->getBoolean( + (string)$log->getAttribute('logIncompleteSkipped'), + FALSE + ); + } + } + + $result[$type] = $target; + } + + return $result; + } + + /** + * Returns the PHP configuration. + * + * @return array + * @since Method available since Release 3.2.1 + */ + public function getPHPConfiguration() + { + $result = array( + 'ini' => array(), + 'const' => array(), + 'var' => array() + ); + + foreach ($this->xpath->query('php/ini') as $ini) { + $name = (string)$ini->getAttribute('name'); + $value = (string)$ini->getAttribute('value'); + + $result['ini'][$name] = $value; + } + + foreach ($this->xpath->query('php/const') as $const) { + $name = (string)$const->getAttribute('name'); + $value = (string)$const->getAttribute('value'); + + if (strtolower($value) == 'false') { + $value = FALSE; + } + + else if (strtolower($value) == 'true') { + $value = TRUE; + } + + $result['const'][$name] = $value; + } + + foreach ($this->xpath->query('php/var') as $var) { + $name = (string)$var->getAttribute('name'); + $value = (string)$var->getAttribute('value'); + + if (strtolower($value) == 'false') { + $value = FALSE; + } + + else if (strtolower($value) == 'true') { + $value = TRUE; + } + + $result['var'][$name] = $value; + } + + return $result; + } + + /** + * Handles the PHP configuration. + * + * @since Method available since Release 3.2.20 + */ + public function handlePHPConfiguration() + { + $configuration = $this->getPHPConfiguration(); + + foreach ($configuration['ini'] as $name => $value) { + if (defined($value)) { + $value = constant($value); + } + + ini_set($name, $value); + } + + foreach ($configuration['const'] as $name => $value) { + if (!defined($name)) { + define($name, $value); + } + } + + foreach ($configuration['var'] as $name => $value) { + $GLOBALS[$name] = $value; + } + } + + /** + * Returns the PHPUnit configuration. + * + * @return array + * @since Method available since Release 3.2.14 + */ + public function getPHPUnitConfiguration() + { + $result = array(); + + if ($this->document->documentElement->hasAttribute('colors')) { + $result['colors'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('colors'), + FALSE + ); + } + + else if ($this->document->documentElement->hasAttribute('ansi')) { + $result['colors'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('ansi'), + FALSE + ); + } + + if ($this->document->documentElement->hasAttribute('backupGlobals')) { + $result['backupGlobals'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('backupGlobals'), + TRUE + ); + } + + if ($this->document->documentElement->hasAttribute('backupStaticAttributes')) { + $result['backupStaticAttributes'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('backupStaticAttributes'), + FALSE + ); + } + + if ($this->document->documentElement->hasAttribute('bootstrap')) { + $result['bootstrap'] = (string)$this->document->documentElement->getAttribute('bootstrap'); + } + + if ($this->document->documentElement->hasAttribute('convertErrorsToExceptions')) { + $result['convertErrorsToExceptions'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('convertErrorsToExceptions'), + TRUE + ); + } + + if ($this->document->documentElement->hasAttribute('convertNoticesToExceptions')) { + $result['convertNoticesToExceptions'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('convertNoticesToExceptions'), + TRUE + ); + } + + if ($this->document->documentElement->hasAttribute('convertWarningsToExceptions')) { + $result['convertWarningsToExceptions'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('convertWarningsToExceptions'), + TRUE + ); + } + + if ($this->document->documentElement->hasAttribute('processIsolation')) { + $result['processIsolation'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('processIsolation'), + FALSE + ); + } + + if ($this->document->documentElement->hasAttribute('stopOnFailure')) { + $result['stopOnFailure'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('stopOnFailure'), + FALSE + ); + } + + if ($this->document->documentElement->hasAttribute('syntaxCheck')) { + $result['syntaxCheck'] = $this->getBoolean( + (string)$this->document->documentElement->getAttribute('syntaxCheck'), + FALSE + ); + } + + if ($this->document->documentElement->hasAttribute('testSuiteLoaderClass')) { + $result['testSuiteLoaderClass'] = (string)$this->document->documentElement->getAttribute('testSuiteLoaderClass'); + } + + if ($this->document->documentElement->hasAttribute('testSuiteLoaderFile')) { + $result['testSuiteLoaderFile'] = (string)$this->document->documentElement->getAttribute('testSuiteLoaderFile'); + } + + return $result; + } + + /** + * Returns the configuration for PMD rules. + * + * @return array + */ + public function getPMDConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('logging/pmd/rule') as $rule) { + $class = (string)$rule->getAttribute('class'); + + $threshold = (string)$rule->getAttribute('threshold'); + $threshold = explode(',', $threshold); + + if (count($threshold) == 1) { + $threshold = $threshold[0]; + } + + $priority = (int)$rule->getAttribute('priority'); + + $result[$class] = array( + 'threshold' => $threshold, + 'priority' => $priority + ); + } + + return $result; + } + + /** + * Returns the SeleniumTestCase browser configuration. + * + * @return array + * @since Method available since Release 3.2.9 + */ + public function getSeleniumBrowserConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('selenium/browser') as $config) { + $name = (string)$config->getAttribute('name'); + $browser = (string)$config->getAttribute('browser'); + + if ($config->hasAttribute('host')) { + $host = (string)$config->getAttribute('host'); + } else { + $host = 'localhost'; + } + + if ($config->hasAttribute('port')) { + $port = (int)$config->getAttribute('port'); + } else { + $port = 4444; + } + + if ($config->hasAttribute('timeout')) { + $timeout = (int)$config->getAttribute('timeout'); + } else { + $timeout = 30000; + } + + $result[] = array( + 'name' => $name, + 'browser' => $browser, + 'host' => $host, + 'port' => $port, + 'timeout' => $timeout + ); + } + + return $result; + } + + /** + * Returns the test suite configuration. + * + * @param boolean $syntaxCheck + * @return PHPUnit_Framework_TestSuite + * @since Method available since Release 3.2.1 + */ + public function getTestSuiteConfiguration($syntaxCheck = FALSE) + { + $testSuiteNodes = $this->xpath->query('testsuites/testsuite'); + + if ($testSuiteNodes->length == 0) { + $testSuiteNodes = $this->xpath->query('testsuite'); + } + + if ($testSuiteNodes->length == 1) { + return $this->getTestSuite($testSuiteNodes->item(0), $syntaxCheck); + } + + if ($testSuiteNodes->length > 1) { + $suite = new PHPUnit_Framework_TestSuite; + + foreach ($testSuiteNodes as $testSuiteNode) { + $suite->addTestSuite( + $this->getTestSuite($testSuiteNode, $syntaxCheck) + ); + } + + return $suite; + } + } + + /** + * @param DOMElement $testSuiteNode + * @param boolean $syntaxCheck + * @return PHPUnit_Framework_TestSuite + * @since Method available since Release 3.4.0 + */ + protected function getTestSuite(DOMElement $testSuiteNode, $syntaxCheck) + { + if ($testSuiteNode->hasAttribute('name')) { + $suite = new PHPUnit_Framework_TestSuite( + (string)$testSuiteNode->getAttribute('name') + ); + } else { + $suite = new PHPUnit_Framework_TestSuite; + } + + foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) { + if ($directoryNode->hasAttribute('prefix')) { + $prefix = (string)$directoryNode->getAttribute('prefix'); + } else { + $prefix = ''; + } + + if ($directoryNode->hasAttribute('suffix')) { + $suffix = (string)$directoryNode->getAttribute('suffix'); + } else { + $suffix = 'Test.php'; + } + + $testCollector = new PHPUnit_Runner_IncludePathTestCollector( + array((string)$directoryNode->nodeValue), $suffix, $prefix + ); + + $suite->addTestFiles($testCollector->collectTests(), $syntaxCheck); + } + + foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) { + $suite->addTestFile((string)$fileNode->nodeValue, $syntaxCheck); + } + + return $suite; + } + + /** + * @param string $value + * @param boolean $default + * @return boolean + * @since Method available since Release 3.2.3 + */ + protected function getBoolean($value, $default) + { + if (strtolower($value) == 'false') { + return FALSE; + } + + else if (strtolower($value) == 'true') { + return TRUE; + } + + return $default; + } + + /** + * @param string $query + * @return array + * @since Method available since Release 3.2.3 + */ + protected function readFilterDirectories($query) + { + $directories = array(); + + foreach ($this->xpath->query($query) as $directory) { + if ($directory->hasAttribute('prefix')) { + $prefix = (string)$directory->getAttribute('prefix'); + } else { + $prefix = ''; + } + + if ($directory->hasAttribute('suffix')) { + $suffix = (string)$directory->getAttribute('suffix'); + } else { + $suffix = '.php'; + } + + if ($directory->hasAttribute('group')) { + $group = (string)$directory->getAttribute('group'); + } else { + $group = 'DEFAULT'; + } + + $directories[] = array( + 'path' => (string)$directory->nodeValue, + 'prefix' => $prefix, + 'suffix' => $suffix, + 'group' => $group + ); + } + + return $directories; + } + + /** + * @param string $query + * @return array + * @since Method available since Release 3.2.3 + */ + protected function readFilterFiles($query) + { + $files = array(); + + foreach ($this->xpath->query($query) as $file) { + $files[] = (string)$file->nodeValue; + } + + return $files; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Diff.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Diff.php new file mode 100644 index 00000000..0b72d9dd --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Diff.php @@ -0,0 +1,268 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Diff implementation. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_Diff +{ + /** + * Returns the diff between two arrays or strings. + * + * @param array|string $from + * @param array|string $to + * @return string + */ + public static function diff($from, $to) + { + if (is_string($from)) { + $from = preg_split('(\r\n|\r|\n)', $from); + } + + if (is_string($to)) { + $to = preg_split('(\r\n|\r|\n)', $to); + } + + $buffer = "--- Expected\n+++ Actual\n"; + $start = array(); + $end = array(); + $fromLength = count($from); + $toLength = count($to); + $length = min($fromLength, $toLength); + + for ($i = 0; $i < $length; ++$i) { + if ($from[$i] === $to[$i]) { + $start[] = $from[$i]; + unset($from[$i], $to[$i]); + } else { + break; + } + } + + $length -= $i; + + for ($i = 1; $i < $length; ++$i) { + if ($from[$fromLength - $i] === $to[$toLength - $i]) { + array_unshift($end, $from[$fromLength - $i]); + unset($from[$fromLength - $i], $to[$toLength - $i]); + } else { + break; + } + } + + $common = self::longestCommonSubsequence( + array_values($from), array_values($to) + ); + + $diff = array(); + $line = 0; + + foreach ($start as $token) { + $diff[] = array($token, 0 /* OLD */); + } + + reset($from); + reset($to); + + foreach ($common as $token) { + while ((($fromToken = reset($from)) !== $token)) { + $diff[] = array(array_shift($from), 2 /* REMOVED */); + } + + while ((($toToken = reset($to)) !== $token)) { + $diff[] = array(array_shift($to), 1 /* ADDED */); + } + + $diff[] = array($token, 0 /* OLD */); + + array_shift($from); + array_shift($to); + } + + while (($token = array_shift($from)) !== NULL) { + $diff[] = array($token, 2 /* REMOVED */); + } + + while (($token = array_shift($to)) !== NULL) { + $diff[] = array($token, 1 /* ADDED */); + } + + foreach ($end as $token) { + $diff[] = array($token, 0 /* OLD */); + } + + $inOld = FALSE; + $i = 0; + $old = array(); + + foreach ($diff as $line) { + if ($line[1] === 0 /* OLD */) { + if ($inOld === FALSE) { + $inOld = $i; + } + } + + else if ($inOld !== FALSE) { + if (($i - $inOld) > 5) { + $old[$inOld] = $i - 1; + } + + $inOld = FALSE; + } + + ++$i; + } + + $start = isset($old[0]) ? $old[0] : 0; + $end = count($diff); + $i = 0; + + if ($tmp = array_search($end, $old)) { + $end = $tmp; + } + + $newChunk = TRUE; + + for ($i = $start; $i < $end; $i++) { + if (isset($old[$i])) { + $buffer .= "\n"; + $newChunk = TRUE; + $i = $old[$i]; + } + + if ($newChunk) { + // TODO: Implement chunk range information. + $buffer .= "@@ @@\n"; + $newChunk = FALSE; + } + + if ($diff[$i][1] === 1 /* ADDED */) { + $buffer .= '+' . $diff[$i][0] . "\n"; + } + + else if ($diff[$i][1] === 2 /* REMOVED */) { + $buffer .= '-' . $diff[$i][0] . "\n"; + } + + else { + $buffer .= ' ' . $diff[$i][0] . "\n"; + } + } + + return $buffer; + } + + /** + * Calculates the longest common subsequence of two arrays. + * + * @param array $from + * @param array $to + * @return array + */ + protected static function longestCommonSubsequence(array $from, array $to) + { + $common = array(); + $longest = 0; + $matrix = array(); + $fromLength = count($from); + $toLength = count($to); + + for ($i = 0; $i <= $fromLength; ++$i) { + $matrix[$i][0] = 0; + } + + for ($j = 0; $j <= $toLength; ++$j) { + $matrix[0][$j] = 0; + } + + for ($i = 1; $i <= $fromLength; ++$i) { + for ($j = 1; $j <= $toLength; ++$j) { + $matrix[$i][$j] = max( + $matrix[$i-1][$j], + $matrix[$i][$j-1], + $from[$i-1] === $to[$j-1] ? $matrix[$i-1][$j-1] + 1 : 0 + ); + } + } + + $i = $fromLength; + $j = $toLength; + + while ($i > 0 && $j > 0) { + if ($from[$i-1] === $to[$j-1]) { + array_unshift($common, $from[$i-1]); + --$i; + --$j; + } + + else if ($matrix[$i][$j-1] > $matrix[$i-1][$j]) { + --$j; + } + + else { + --$i; + } + } + + return $common; + } +} +?> \ No newline at end of file diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/ErrorHandler.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/ErrorHandler.php new file mode 100644 index 00000000..ec75d377 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/ErrorHandler.php @@ -0,0 +1,129 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Error handler that converts PHP errors and warnings to exceptions. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Util_ErrorHandler +{ + protected static $errorStack = array(); + + /** + * Returns the error stack. + * + * @return array + */ + public static function getErrorStack() + { + return self::$errorStack; + } + + /** + * @param integer $errno + * @param string $errstr + * @param string $errfile + * @param integer $errline + * @throws PHPUnit_Framework_Error + */ + public static function handleError($errno, $errstr, $errfile, $errline) + { + if (!($errno & error_reporting())) { + return FALSE; + } + + self::$errorStack[] = array($errno, $errstr, $errfile, $errline); + + if (version_compare(PHP_VERSION, '5.2.5', '>=')) { + $trace = debug_backtrace(FALSE); + } else { + $trace = debug_backtrace(); + } + + array_shift($trace); + + foreach ($trace as $frame) { + if ($frame['function'] == '__toString') { + return FALSE; + } + } + + if ($errno == E_NOTICE || $errno == E_STRICT) { + if (PHPUnit_Framework_Error_Notice::$enabled !== TRUE) { + return FALSE; + } + + $exception = 'PHPUnit_Framework_Error_Notice'; + } + + else if ($errno == E_WARNING) { + if (PHPUnit_Framework_Error_Warning::$enabled !== TRUE) { + return FALSE; + } + + $exception = 'PHPUnit_Framework_Error_Warning'; + } + + else { + $exception = 'PHPUnit_Framework_Error'; + } + + throw new $exception($errstr, $errno, $errfile, $errline, $trace); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/File.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/File.php new file mode 100644 index 00000000..b820d02f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/File.php @@ -0,0 +1,364 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +if (!defined('T_NAMESPACE')) { + define('T_NAMESPACE', 377); +} + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * File helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_File +{ + /** + * @var array + */ + protected static $countCache = array(); + + /** + * @var array + */ + protected static $classesFunctionsCache = array(); + + /** + * Counts LOC, CLOC, and NCLOC for a file. + * + * @param string $filename + * @return array + */ + public static function countLines($filename) + { + if (!isset(self::$countCache[$filename])) { + $buffer = file_get_contents($filename); + $loc = substr_count($buffer, "\n"); + $cloc = 0; + + foreach (token_get_all($buffer) as $i => $token) { + if (is_string($token)) { + continue; + } + + list ($token, $value) = $token; + + if ($token == T_COMMENT || $token == T_DOC_COMMENT) { + $cloc += substr_count($value, "\n") + 1; + } + } + + self::$countCache[$filename] = array( + 'loc' => $loc, 'cloc' => $cloc, 'ncloc' => $loc - $cloc + ); + } + + return self::$countCache[$filename]; + } + + /** + * Returns information on the classes declared in a sourcefile. + * + * @param string $filename + * @return array + */ + public static function getClassesInFile($filename) + { + if (!isset(self::$classesFunctionsCache[$filename])) { + self::parseFile($filename); + } + + return self::$classesFunctionsCache[$filename]['classes']; + } + + /** + * Returns information on the functions declared in a sourcefile. + * + * @param string $filename + * @return array + */ + public static function getFunctionsInFile($filename) + { + if (!isset(self::$classesFunctionsCache[$filename])) { + self::parseFile($filename); + } + + return self::$classesFunctionsCache[$filename]['functions']; + } + + /** + * Parses a file for class, method, and function information. + * + * @param string $filename + */ + protected static function parseFile($filename) + { + self::$classesFunctionsCache[$filename] = array( + 'classes' => array(), 'functions' => array() + ); + + $tokens = token_get_all( + file_get_contents($filename) + ); + $numTokens = count($tokens); + $blocks = array(); + $line = 1; + $currentBlock = FALSE; + $currentNamespace = FALSE; + $currentClass = FALSE; + $currentFunction = FALSE; + $currentFunctionStartLine = FALSE; + $currentFunctionTokens = array(); + $currentDocComment = FALSE; + $currentSignature = FALSE; + $currentSignatureStartToken = FALSE; + + for ($i = 0; $i < $numTokens; $i++) { + if ($currentFunction !== FALSE) { + $currentFunctionTokens[] = $tokens[$i]; + } + + if (is_string($tokens[$i])) { + if ($tokens[$i] == '{') { + if ($currentBlock == T_CLASS) { + $block = $currentClass; + } + + else if ($currentBlock == T_FUNCTION) { + $currentSignature = ''; + + for ($j = $currentSignatureStartToken; $j < $i; $j++) { + if (is_string($tokens[$j])) { + $currentSignature .= $tokens[$j]; + } else { + $currentSignature .= $tokens[$j][1]; + } + } + + $currentSignature = trim($currentSignature); + + $block = $currentFunction; + $currentSignatureStartToken = FALSE; + } + + else { + $block = FALSE; + } + + array_push($blocks, $block); + + $currentBlock = FALSE; + } + + else if ($tokens[$i] == '}') { + $block = array_pop($blocks); + + if ($block !== FALSE && $block !== NULL) { + if ($block == $currentFunction) { + if ($currentDocComment !== FALSE) { + $docComment = $currentDocComment; + $currentDocComment = FALSE; + } else { + $docComment = ''; + } + + $tmp = array( + 'docComment' => $docComment, + 'signature' => $currentSignature, + 'startLine' => $currentFunctionStartLine, + 'endLine' => $line, + 'tokens' => $currentFunctionTokens + ); + + if ($currentClass === FALSE) { + self::$classesFunctionsCache[$filename]['functions'][$currentFunction] = $tmp; + } else { + self::$classesFunctionsCache[$filename]['classes'][$currentClass]['methods'][$currentFunction] = $tmp; + } + + $currentFunction = FALSE; + $currentFunctionStartLine = FALSE; + $currentFunctionTokens = array(); + $currentSignature = FALSE; + } + + else if ($block == $currentClass) { + self::$classesFunctionsCache[$filename]['classes'][$currentClass]['endLine'] = $line; + + $currentClass = FALSE; + $currentClassStartLine = FALSE; + } + } + } + + continue; + } + + switch ($tokens[$i][0]) { + case T_NAMESPACE: { + $currentNamespace = $tokens[$i+2][1]; + + for ($j = $i+3; $j < $numTokens; $j += 2) { + if ($tokens[$j][0] == T_NS_SEPARATOR) { + $currentNamespace .= '\\' . $tokens[$j+1][1]; + } else { + break; + } + } + } + break; + + case T_CURLY_OPEN: { + $currentBlock = T_CURLY_OPEN; + array_push($blocks, $currentBlock); + } + break; + + case T_DOLLAR_OPEN_CURLY_BRACES: { + $currentBlock = T_DOLLAR_OPEN_CURLY_BRACES; + array_push($blocks, $currentBlock); + } + break; + + case T_CLASS: { + $currentBlock = T_CLASS; + + if ($currentNamespace === FALSE) { + $currentClass = $tokens[$i+2][1]; + } else { + $currentClass = $currentNamespace . '\\' . + $tokens[$i+2][1]; + } + + if ($currentDocComment !== FALSE) { + $docComment = $currentDocComment; + $currentDocComment = FALSE; + } else { + $docComment = ''; + } + + self::$classesFunctionsCache[$filename]['classes'][$currentClass] = array( + 'methods' => array(), + 'docComment' => $docComment, + 'startLine' => $line + ); + } + break; + + case T_FUNCTION: { + if (!((is_array($tokens[$i+2]) && + $tokens[$i+2][0] == T_STRING) || + (is_string($tokens[$i+2]) && + $tokens[$i+2] == '&' && + is_array($tokens[$i+3]) && + $tokens[$i+3][0] == T_STRING))) { + continue; + } + + $currentBlock = T_FUNCTION; + $currentFunctionStartLine = $line; + + $done = FALSE; + $currentSignatureStartToken = $i - 1; + + do { + switch ($tokens[$currentSignatureStartToken][0]) { + case T_ABSTRACT: + case T_FINAL: + case T_PRIVATE: + case T_PUBLIC: + case T_PROTECTED: + case T_STATIC: + case T_WHITESPACE: { + $currentSignatureStartToken--; + } + break; + + default: { + $currentSignatureStartToken++; + $done = TRUE; + } + } + } + while (!$done); + + if (isset($tokens[$i+2][1])) { + $functionName = $tokens[$i+2][1]; + } + + else if (isset($tokens[$i+3][1])) { + $functionName = $tokens[$i+3][1]; + } + + if ($currentNamespace === FALSE) { + $currentFunction = $functionName; + } else { + $currentFunction = $currentNamespace . '\\' . + $functionName; + } + } + break; + + case T_DOC_COMMENT: { + $currentDocComment = $tokens[$i][1]; + } + break; + } + + $line += substr_count($tokens[$i][1], "\n"); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Fileloader.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Fileloader.php new file mode 100644 index 00000000..805c9909 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Fileloader.php @@ -0,0 +1,149 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Util/InvalidArgumentHelper.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/PHP.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Utility methods to load PHP sourcefiles. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class PHPUnit_Util_Fileloader +{ + /** + * Checks if a PHP sourcefile is readable and is optionally checked for + * syntax errors through the syntaxCheck() method. The sourcefile is + * loaded through the load() method. + * + * @param string $filename + * @param boolean $syntaxCheck + * @throws RuntimeException + */ + public static function checkAndLoad($filename, $syntaxCheck = FALSE) + { + if (!is_readable($filename)) { + $filename = './' . $filename; + } + + if (!is_readable($filename)) { + throw new RuntimeException( + sprintf('Cannot open file "%s".' . "\n", $filename) + ); + } + + if ($syntaxCheck) { + self::syntaxCheck($filename); + } + + self::load($filename); + } + + /** + * Loads a PHP sourcefile. + * + * @param string $filename + * @return mixed + * @since Method available since Release 3.0.0 + */ + public static function load($filename) + { + $filename = PHPUnit_Util_Filesystem::fileExistsInIncludePath( + $filename + ); + + $oldVariableNames = array_keys(get_defined_vars()); + + include_once $filename; + + $newVariables = get_defined_vars(); + $newVariableNames = array_diff( + array_keys($newVariables), $oldVariableNames + ); + + foreach ($newVariableNames as $variableName) { + if ($variableName != 'oldVariableNames') { + $GLOBALS[$variableName] = $newVariables[$variableName]; + } + } + + return $filename; + } + + /** + * Uses a separate process to perform a syntax check on a PHP sourcefile. + * + * @param string $filename + * @throws RuntimeException + * @since Method available since Release 3.0.0 + */ + protected static function syntaxCheck($filename) + { + $command = PHPUnit_Util_PHP::getPhpBinary(); + + if (DIRECTORY_SEPARATOR == '\\') { + $command = escapeshellarg($command); + } + + $command .= ' -l ' . escapeshellarg($filename); + $output = shell_exec($command); + + if (strpos($output, 'Errors parsing') !== FALSE) { + throw new RuntimeException($output); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Filesystem.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Filesystem.php new file mode 100644 index 00000000..d2755b2b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Filesystem.php @@ -0,0 +1,412 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Filesystem helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + * @abstract + */ +class PHPUnit_Util_Filesystem +{ + /** + * @var array + */ + protected static $buffer = array(); + + /** + * @var array + */ + protected static $hasBinary = array(); + + /** + * Maps class names to source file names: + * - PEAR CS: Foo_Bar_Baz -> Foo/Bar/Baz.php + * - Namespace: Foo\Bar\Baz -> Foo/Bar/Baz.php + * + * @param string $className + * @return string + * @since Method available since Release 3.4.0 + */ + public static function classNameToFilename($className) + { + return str_replace( + array('_', '\\'), + DIRECTORY_SEPARATOR, + $className + ) . '.php'; + } + + /** + * Starts the collection of loaded files. + * + * @since Method available since Release 3.3.0 + */ + public static function collectStart() + { + self::$buffer = get_included_files(); + } + + /** + * Stops the collection of loaded files and + * returns the names of the loaded files. + * + * @return array + * @since Method available since Release 3.3.0 + */ + public static function collectEnd() + { + return array_values( + array_diff(get_included_files(), self::$buffer) + ); + } + + /** + * Stops the collection of loaded files and adds + * the names of the loaded files to the blacklist. + * + * @return array + * @since Method available since Release 3.4.6 + */ + public static function collectEndAndAddToBlacklist() + { + foreach (self::collectEnd() as $blacklistedFile) { + PHPUnit_Util_Filter::addFileToFilter($blacklistedFile, 'PHPUNIT'); + } + } + + /** + * Wrapper for file_exists() that searches the include_path. + * + * @param string $file + * @return mixed + * @author Mattis Stordalen Flister + * @since Method available since Release 3.2.9 + */ + public static function fileExistsInIncludePath($file) + { + if (file_exists($file)) { + return realpath($file); + } + + $paths = explode(PATH_SEPARATOR, get_include_path()); + + foreach ($paths as $path) { + $fullpath = $path . DIRECTORY_SEPARATOR . $file; + + if (file_exists($fullpath)) { + return realpath($fullpath); + } + } + + return FALSE; + } + + /** + * Returns the common path of a set of files. + * + * @param array $paths + * @return string + * @since Method available since Release 3.1.0 + */ + public static function getCommonPath(array $paths) + { + $count = count($paths); + + if ($count == 1) { + return dirname($paths[0]) . DIRECTORY_SEPARATOR; + } + + $_paths = array(); + + for ($i = 0; $i < $count; $i++) { + $_paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]); + + if (empty($_paths[$i][0])) { + $_paths[$i][0] = DIRECTORY_SEPARATOR; + } + } + + $common = ''; + $done = FALSE; + $j = 0; + $count--; + + while (!$done) { + for ($i = 0; $i < $count; $i++) { + if ($_paths[$i][$j] != $_paths[$i+1][$j]) { + $done = TRUE; + break; + } + } + + if (!$done) { + $common .= $_paths[0][$j]; + + if ($j > 0) { + $common .= DIRECTORY_SEPARATOR; + } + } + + $j++; + } + + return $common; + } + + /** + * @param string $directory + * @return string + * @throws RuntimeException + * @since Method available since Release 3.3.0 + */ + public static function getDirectory($directory) + { + if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) { + $directory .= DIRECTORY_SEPARATOR; + } + + if (is_dir($directory) || mkdir($directory, 0777, TRUE)) { + return $directory; + } else { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Directory "%s" does not exist.', + $directory + ) + ); + } + } + + /** + * Returns a filesystem safe version of the passed filename. + * This function does not operate on full paths, just filenames. + * + * @param string $filename + * @return string + * @author Michael Lively Jr. + */ + public static function getSafeFilename($filename) + { + /* characters allowed: A-Z, a-z, 0-9, _ and . */ + return preg_replace('#[^\w.]#', '_', $filename); + } + + /** + * @param string $binary + * @return boolean + * @since Method available since Release 3.4.0 + */ + public static function hasBinary($binary) + { + if (!isset(self::$hasBinary[$binary])) { + if (substr(php_uname('s'), 0, 7) == 'Windows') { + $binary .= '.exe'; + } + + self::$hasBinary[$binary] = FALSE; + + $openBaseDir = ini_get('open_basedir'); + + if (is_string($openBaseDir) && !empty($openBaseDir)) { + $safeModeExecDir = ini_get('safe_mode_exec_dir'); + $var = $openBaseDir; + + if (is_string($safeModeExecDir) && !empty($safeModeExecDir)) { + $var .= PATH_SEPARATOR . $safeModeExecDir; + } + } else { + if (isset($_ENV['PATH'])) { + $var = $_ENV['PATH']; + } + + else if (isset($_ENV['Path'])) { + $var = $_ENV['Path']; + } + + else if (isset($_SERVER['PATH'])) { + $var = $_SERVER['PATH']; + } + + else if (isset($_SERVER['Path'])) { + $var = $_SERVER['Path']; + } + } + + if (isset($var)) { + $paths = explode(PATH_SEPARATOR, $var); + } else { + $paths = array(); + } + + foreach ($paths as $path) { + $_path = $path . DIRECTORY_SEPARATOR . $binary; + + if (file_exists($_path) && is_executable($_path)) { + self::$hasBinary[$binary] = TRUE; + break; + } + } + } + + return self::$hasBinary[$binary]; + } + + /** + * Reduces the paths by cutting the longest common start path. + * + * For instance, + * + * + * Array + * ( + * [/home/sb/PHPUnit/Samples/Money/Money.php] => Array + * ( + * ... + * ) + * + * [/home/sb/PHPUnit/Samples/Money/MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is reduced to + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * @param array $files + * @return string + * @since Method available since Release 3.3.0 + */ + public static function reducePaths(&$files) + { + if (empty($files)) { + return '.'; + } + + $commonPath = ''; + $paths = array_keys($files); + + if (count($files) == 1) { + $commonPath = dirname($paths[0]); + $files[basename($paths[0])] = $files[$paths[0]]; + + unset($files[$paths[0]]); + + return $commonPath; + } + + $max = count($paths); + + for ($i = 0; $i < $max; $i++) { + $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]); + + if (empty($paths[$i][0])) { + $paths[$i][0] = DIRECTORY_SEPARATOR; + } + } + + $done = FALSE; + $max = count($paths); + + while (!$done) { + for ($i = 0; $i < $max - 1; $i++) { + if (!isset($paths[$i][0]) || + !isset($paths[$i+1][0]) || + $paths[$i][0] != $paths[$i+1][0]) { + $done = TRUE; + break; + } + } + + if (!$done) { + $commonPath .= $paths[0][0] . (($paths[0][0] != DIRECTORY_SEPARATOR) ? DIRECTORY_SEPARATOR : ''); + + for ($i = 0; $i < $max; $i++) { + array_shift($paths[$i]); + } + } + } + + $original = array_keys($files); + $max = count($original); + + for ($i = 0; $i < $max; $i++) { + $files[join('/', $paths[$i])] = $files[$original[$i]]; + unset($files[$original[$i]]); + } + + ksort($files); + + return $commonPath; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Filter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Filter.php new file mode 100644 index 00000000..bdba87e5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Filter.php @@ -0,0 +1,587 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Util/FilterIterator.php'; + +/** + * Utility class for code filtering. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Util_Filter +{ + /** + * @var boolean + */ + public static $addUncoveredFilesFromWhitelist = TRUE; + + /** + * @var boolean + */ + public static $filterPHPUnit = TRUE; + + /** + * @var boolean + */ + protected static $filter = TRUE; + + /** + * Source files that are blacklisted. + * + * @var array + */ + protected static $blacklistedFiles = array( + 'DEFAULT' => array(), + 'PHPUNIT' => array(), + 'TESTS' => array() + ); + + /** + * Source files that are whitelisted. + * + * @var array + */ + protected static $whitelistedFiles = array(); + + /** + * List of covered files. + * + * @var array + */ + protected static $coveredFiles = array(); + + /** + * Adds a directory to the blacklist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $group + * @param string $prefix + * @throws RuntimeException + * @since Method available since Release 3.1.5 + */ + public static function addDirectoryToFilter($directory, $suffix = '.php', $group = 'DEFAULT', $prefix = '') + { + if (file_exists($directory)) { + foreach (self::getIterator($directory, $suffix, $prefix) as $file) { + self::addFileToFilter($file->getPathName(), $group); + } + } else { + throw new PHPUnit_Framework_Exception( + $directory . ' does not exist' + ); + } + } + + /** + * Adds a new file to be filtered (blacklist). + * + * @param string $filename + * @param string $group + * @throws RuntimeException + * @since Method available since Release 2.1.0 + */ + public static function addFileToFilter($filename, $group = 'DEFAULT') + { + if (file_exists($filename)) { + $filename = realpath($filename); + + if (!isset(self::$blacklistedFiles[$group])) { + self::$blacklistedFiles[$group] = array($filename); + } + + else if (!in_array($filename, self::$blacklistedFiles[$group])) { + self::$blacklistedFiles[$group][] = $filename; + } + } else { + throw new PHPUnit_Framework_Exception( + $filename . ' does not exist' + ); + } + } + + /** + * Removes a directory from the blacklist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $group + * @param string $prefix + * @throws RuntimeException + * @since Method available since Release 3.1.5 + */ + public static function removeDirectoryFromFilter($directory, $suffix = '.php', $group = 'DEFAULT', $prefix = '') + { + if (file_exists($directory)) { + foreach (self::getIterator($directory, $suffix, $prefix) as $file) { + self::removeFileFromFilter($file->getPathName(), $group); + } + } else { + throw new PHPUnit_Framework_Exception( + $directory . ' does not exist' + ); + } + } + + /** + * Removes a file from the filter (blacklist). + * + * @param string $filename + * @param string $group + * @throws RuntimeException + * @since Method available since Release 2.1.0 + */ + public static function removeFileFromFilter($filename, $group = 'DEFAULT') + { + if (file_exists($filename)) { + if (isset(self::$blacklistedFiles[$group])) { + $filename = realpath($filename); + + foreach (self::$blacklistedFiles[$group] as $key => $_filename) { + if ($filename == $_filename) { + unset(self::$blacklistedFiles[$group][$key]); + } + } + } + } else { + throw new PHPUnit_Framework_Exception( + $filename . ' does not exist' + ); + } + } + + /** + * Adds a directory to the whitelist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + * @throws RuntimeException + * @since Method available since Release 3.1.5 + */ + public static function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '') + { + if (file_exists($directory)) { + foreach (self::getIterator($directory, $suffix, $prefix) as $file) { + self::addFileToWhitelist($file->getPathName()); + } + } else { + throw new PHPUnit_Framework_Exception( + $directory . ' does not exist' + ); + } + } + + /** + * Adds a new file to the whitelist. + * + * When the whitelist is empty (default), blacklisting is used. + * When the whitelist is not empty, whitelisting is used. + * + * @param string $filename + * @throws RuntimeException + * @since Method available since Release 3.1.0 + */ + public static function addFileToWhitelist($filename) + { + if (file_exists($filename)) { + $filename = realpath($filename); + + if (!in_array($filename, self::$whitelistedFiles)) { + self::$whitelistedFiles[] = $filename; + } + } else { + throw new PHPUnit_Framework_Exception( + $filename . ' does not exist' + ); + } + } + + /** + * Removes a directory from the whitelist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + * @throws RuntimeException + * @since Method available since Release 3.1.5 + */ + public static function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '') + { + if (file_exists($directory)) { + foreach (self::getIterator($directory, $suffix, $prefix) as $file) { + self::removeFileFromWhitelist($file->getPathName()); + } + } else { + throw new PHPUnit_Framework_Exception( + $directory . ' does not exist' + ); + } + } + + /** + * Removes a file from the whitelist. + * + * @param string $filename + * @throws RuntimeException + * @since Method available since Release 3.1.0 + */ + public static function removeFileFromWhitelist($filename) + { + if (file_exists($filename)) { + $filename = realpath($filename); + + foreach (self::$whitelistedFiles as $key => $_filename) { + if ($filename == $_filename) { + unset(self::$whitelistedFiles[$key]); + } + } + } else { + throw new PHPUnit_Framework_Exception( + $filename . ' does not exist' + ); + } + } + + /** + * Returns data about files within code coverage information, specifically + * which ones will be filtered out and which ones may be whitelisted but not + * touched by coverage. + * + * Returns a two-item array. The first item is an array indexed by filenames + * with a boolean payload of whether they should be filtered out. + * + * The second item is an array of filenames which are + * whitelisted but which are absent from the coverage information. + * + * @param array $codeCoverageInformation + * @param boolean $filterTests + * @return array + */ + public static function getFileCodeCoverageDisposition(array $codeCoverageInformation, $filterTests = TRUE) + { + if (!self::$filter) { + return array(array(), array()); + } + + $isFilteredCache = array(); + $coveredFiles = array(); + + foreach ($codeCoverageInformation as $k => $test) { + foreach (array_keys($test['executable']) as $file) { + if (!isset($isFilteredCache[$file])) { + $isFilteredCache[$file] = self::isFiltered( + $file, $filterTests + ); + } + } + } + + $coveredFiles = array_keys($isFilteredCache); + $missedFiles = array_diff(self::$whitelistedFiles, $coveredFiles); + $missedFiles = array_filter($missedFiles, 'file_exists'); + + return array($isFilteredCache, $missedFiles); + } + + /** + * @param array $codeCoverageInformation + * @param boolean $filterTests + * @return array + */ + public static function getFilteredCodeCoverage(array $codeCoverageInformation, $filterTests = TRUE) + { + if (self::$filter) { + list($isFilteredCache, $missedFiles) = self::getFileCodeCoverageDisposition( + $codeCoverageInformation, $filterTests + ); + + foreach ($codeCoverageInformation as $k => $test) { + foreach (array_keys($test['files']) as $file) { + if (isset($isFilteredCache[$file]) && + $isFilteredCache[$file]) { + unset($codeCoverageInformation[$k]['files'][$file]); + } + } + + foreach (array_keys($test['dead']) as $file) { + if (isset($isFilteredCache[$file]) && + $isFilteredCache[$file]) { + unset($codeCoverageInformation[$k]['dead'][$file]); + } + } + + foreach (array_keys($test['executable']) as $file) { + if (isset($isFilteredCache[$file]) && + $isFilteredCache[$file]) { + unset( + $codeCoverageInformation[$k]['executable'][$file] + ); + } + } + } + + if (self::$addUncoveredFilesFromWhitelist) { + foreach (self::$whitelistedFiles as $whitelistedFile) { + if (!isset(self::$coveredFiles[$whitelistedFile]) && + !self::isFiltered($whitelistedFile, $filterTests, TRUE)) { + if (file_exists($whitelistedFile)) { + xdebug_start_code_coverage( + XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE + ); + include_once $whitelistedFile; + $coverage = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + foreach ($coverage as $file => $fileCoverage) { + if (!in_array($file, self::$whitelistedFiles) || + isset(self::$coveredFiles[$file])) { + continue; + } + + foreach ($fileCoverage as $line => $flag) { + if ($flag > 0) { + $fileCoverage[$line] = -1; + } + } + + $codeCoverageInformation[] = array( + 'test' => NULL, + 'files' => array( + $file => $fileCoverage + ) + ); + + self::addCoveredFile($file); + } + } + } + } + } + } + + return $codeCoverageInformation; + } + + /** + * Filters stack frames from PHPUnit classes. + * + * @param Exception $e + * @param boolean $filterTests + * @param boolean $asString + * @return string + */ + public static function getFilteredStacktrace(Exception $e, $filterTests = TRUE, $asString = TRUE) + { + if ($asString === TRUE) { + $filteredStacktrace = ''; + } else { + $filteredStacktrace = array(); + } + + $eTrace = $e->getTrace(); + + if (!self::frameExists($eTrace, $e->getFile(), $e->getLine())) { + array_unshift( + $eTrace, array('file' => $e->getFile(), 'line' => $e->getLine()) + ); + } + + foreach ($eTrace as $frame) { + if (!self::$filter || (isset($frame['file']) && + is_file($frame['file']) && + !self::isFiltered($frame['file'], $filterTests, TRUE))) { + if ($asString === TRUE) { + $filteredStacktrace .= sprintf( + "%s:%s\n", + + $frame['file'], + isset($frame['line']) ? $frame['line'] : '?' + ); + } else { + $filteredStacktrace[] = $frame; + } + } + } + + return $filteredStacktrace; + } + + /** + * Activates or deactivates filtering. + * + * @param boolean $filter + * @throws InvalidArgumentException + * @since Method available since Release 3.0.0 + */ + public static function setFilter($filter) + { + if (is_bool($filter)) { + self::$filter = $filter; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Returns a PHPUnit_Util_FilterIterator that iterates + * over all files in the given directory that have the + * given suffix and prefix. + * + * @param string $directory + * @param string $suffix + * @param string $prefix + * @return Iterator + * @since Method available since Release 3.1.5 + */ + protected static function getIterator($directory, $suffix, $prefix) + { + return new PHPUnit_Util_FilterIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($directory) + ), + $suffix, + $prefix + ); + } + + /** + * @param string $filename + * @param boolean $filterTests + * @param boolean $ignoreWhitelist + * @return boolean + * @since Method available since Release 2.1.3 + */ + public static function isFiltered($filename, $filterTests = TRUE, $ignoreWhitelist = FALSE) + { + $filename = realpath($filename); + + if (!$ignoreWhitelist && !empty(self::$whitelistedFiles)) { + return !in_array($filename, self::$whitelistedFiles); + } + + $blacklistedFiles = self::$blacklistedFiles['DEFAULT']; + + if ($filterTests) { + $blacklistedFiles = array_merge( + $blacklistedFiles, self::$blacklistedFiles['TESTS'] + ); + } + + if (self::$filterPHPUnit) { + $blacklistedFiles = array_merge( + $blacklistedFiles, self::$blacklistedFiles['PHPUNIT'] + ); + } + + if (in_array($filename, $blacklistedFiles)) { + return TRUE; + } + + return FALSE; + } + + /** + * Adds a file to the list of covered files. + * + * @param string $filename + * @since Method available since Release 3.3.0 + */ + public static function addCoveredFile($filename) + { + self::$coveredFiles[$filename] = TRUE; + } + + /** + * Returns the list of covered files. + * + * @return array + * @since Method available since Release 3.3.0 + */ + public static function getCoveredFiles() + { + return self::$coveredFiles; + } + + /** + * Returns the list of blacklisted files. + * + * @return array + * @since Method available since Release 3.4.3 + */ + public static function getBlacklistedFiles() + { + return self::$blacklistedFiles; + } + + /** + * @param array $trace + * @param string $file + * @param int $line + * @return boolean + * @since Method available since Release 3.3.2 + */ + public static function frameExists(array $trace, $file, $line) + { + foreach ($trace as $frame) { + if (isset($frame['file']) && $frame['file'] == $file && + isset($frame['line']) && $frame['line'] == $line) { + return TRUE; + } + } + + return FALSE; + } +} + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/FilterIterator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/FilterIterator.php new file mode 100644 index 00000000..df102dce --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/FilterIterator.php @@ -0,0 +1,163 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ + +class PHPUnit_Util_FilterIterator extends FilterIterator +{ + /** + * @var array + */ + protected $suffixes = array(); + + /** + * @var string + */ + protected $prefixes = array(); + + /** + * @param Iterator $iterator + * @param array $suffixes + * @param array $prefixes + */ + public function __construct(Iterator $iterator, $suffixes = array(), $prefixes = array()) + { + if (is_string($suffixes)) { + if (!empty($suffixes)) { + $suffixes = array($suffixes); + } else { + $suffixes = array(); + } + } + + if (!is_array($suffixes)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'array or string' + ); + } + + $this->suffixes = $suffixes; + + if (is_string($prefixes)) { + if (!empty($prefixes)) { + $prefixes = array($prefixes); + } else { + $prefixes = array(); + } + } + + if (!is_array($prefixes)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 3, 'array or string' + ); + } + + $this->prefixes = $prefixes; + + parent::__construct($iterator); + } + + /** + * @return boolean + */ + public function accept() + { + $current = $this->getInnerIterator()->current(); + $filename = $current->getFilename(); + + if (strpos($filename, '.') === 0 || + preg_match('=/\.[^/]*/=', realpath($current->getPathname()))) { + return FALSE; + } + + if (!empty($this->prefixes)) { + $matched = FALSE; + + foreach ($this->prefixes as $prefix) { + if (strpos($filename, $prefix) === 0) { + $matched = TRUE; + break; + } + } + + if (!$matched) { + return FALSE; + } + } + + if (!empty($this->suffixes)) { + $matched = FALSE; + + foreach ($this->suffixes as $suffix) { + if (substr($filename, -1 * strlen($suffix)) == $suffix) { + $matched = TRUE; + break; + } + } + + if (!$matched) { + return FALSE; + } + } + + return TRUE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Getopt.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Getopt.php new file mode 100644 index 00000000..a20d2447 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Getopt.php @@ -0,0 +1,214 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Command-line options parsing class. + * + * @category Testing + * @package PHPUnit + * @author Andrei Zmievski + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + * @abstract + */ +class PHPUnit_Util_Getopt +{ + public static function getopt(array $args, $short_options, $long_options = NULL) + { + if (empty($args)) { + return array(array(), array()); + } + + $opts = array(); + $non_opts = array(); + + if ($long_options) { + sort($long_options); + } + + if (isset($args[0]{0}) && $args[0]{0} != '-') { + array_shift($args); + } + + reset($args); + array_map('trim', $args); + + while (list($i, $arg) = each($args)) { + if ($arg == '') { + continue; + } + + if ($arg == '--') { + $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); + break; + } + + if ($arg{0} != '-' || + (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; + } + + elseif (strlen($arg) > 1 && $arg{1} == '-') { + self::parseLongOption( + substr($arg, 2), $long_options, $opts, $args + ); + } + + else { + self::parseShortOption( + substr($arg, 1), $short_options, $opts, $args + ); + } + } + + return array($opts, $non_opts); + } + + protected static function parseShortOption($arg, $short_options, &$opts, &$args) + { + $argLen = strlen($arg); + + for ($i = 0; $i < $argLen; $i++) { + $opt = $arg{$i}; + $opt_arg = NULL; + + if (($spec = strstr($short_options, $opt)) === FALSE || + $arg{$i} == ':') { + throw new PHPUnit_Framework_Exception( + "unrecognized option -- $opt" + ); + } + + if (strlen($spec) > 1 && $spec{1} == ':') { + if (strlen($spec) > 2 && $spec{2} == ':') { + if ($i + 1 < $argLen) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } + } else { + if ($i + 1 < $argLen) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } + + else if (list(, $opt_arg) = each($args)) { + } + + else { + throw new PHPUnit_Framework_Exception( + "option requires an argument -- $opt" + ); + } + } + } + + $opts[] = array($opt, $opt_arg); + } + } + + protected static function parseLongOption($arg, $long_options, &$opts, &$args) + { + $count = count($long_options); + $list = explode('=', $arg); + $opt = $list[0]; + $opt_arg = NULL; + + if (count($list) > 1) { + $opt_arg = $list[1]; + } + + $opt_len = strlen($opt); + + for ($i = 0; $i < $count; $i++) { + $long_opt = $long_options[$i]; + $opt_start = substr($long_opt, 0, $opt_len); + + if ($opt_start != $opt) { + continue; + } + + $opt_rest = substr($long_opt, $opt_len); + + if ($opt_rest != '' && $opt{0} != '=' && $i + 1 < $count && + $opt == substr($long_options[$i+1], 0, $opt_len)) { + throw new PHPUnit_Framework_Exception( + "option --$opt is ambiguous" + ); + } + + if (substr($long_opt, -1) == '=') { + if (substr($long_opt, -2) != '==') { + if (!strlen($opt_arg) && + !(list(, $opt_arg) = each($args))) { + throw new PHPUnit_Framework_Exception( + "option --$opt requires an argument" + ); + } + } + } + + else if ($opt_arg) { + throw new PHPUnit_Framework_Exception( + "option --$opt doesn't allow an argument" + ); + } + + $opts[] = array('--' . $opt, $opt_arg); + return; + } + + throw new PHPUnit_Framework_Exception("unrecognized option --$opt"); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/GlobalState.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/GlobalState.php new file mode 100644 index 00000000..4c836fd6 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/GlobalState.php @@ -0,0 +1,341 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_GlobalState +{ + /** + * @var array + */ + protected static $globals = array(); + + /** + * @var array + */ + protected static $staticAttributes = array(); + + /** + * @var array + */ + protected static $superGlobalArrays = array( + '_ENV', + '_POST', + '_GET', + '_COOKIE', + '_SERVER', + '_FILES', + '_REQUEST' + ); + + /** + * @var array + */ + protected static $superGlobalArraysLong = array( + 'HTTP_ENV_VARS', + 'HTTP_POST_VARS', + 'HTTP_GET_VARS', + 'HTTP_COOKIE_VARS', + 'HTTP_SERVER_VARS', + 'HTTP_POST_FILES' + ); + + public static function backupGlobals(array $blacklist) + { + self::$globals = array(); + $superGlobalArrays = self::getSuperGlobalArrays(); + + foreach ($superGlobalArrays as $superGlobalArray) { + if (!in_array($superGlobalArray, $blacklist)) { + self::backupSuperGlobalArray($superGlobalArray); + } + } + + foreach (array_keys($GLOBALS) as $key) { + if ($key != 'GLOBALS' && + !in_array($key, $superGlobalArrays) && + !in_array($key, $blacklist)) { + self::$globals['GLOBALS'][$key] = serialize($GLOBALS[$key]); + } + } + } + + public static function restoreGlobals(array $blacklist) + { + if (ini_get('register_long_arrays') == '1') { + $superGlobalArrays = array_merge( + self::$superGlobalArrays, self::$superGlobalArraysLong + ); + } else { + $superGlobalArrays = self::$superGlobalArrays; + } + + foreach ($superGlobalArrays as $superGlobalArray) { + if (!in_array($superGlobalArray, $blacklist)) { + self::restoreSuperGlobalArray($superGlobalArray); + } + } + + foreach (array_keys($GLOBALS) as $key) { + if ($key != 'GLOBALS' && + !in_array($key, $superGlobalArrays) && + !in_array($key, $blacklist)) { + if (isset(self::$globals['GLOBALS'][$key])) { + $GLOBALS[$key] = unserialize( + self::$globals['GLOBALS'][$key] + ); + } else { + unset($GLOBALS[$key]); + } + } + } + + self::$globals = array(); + } + + protected static function backupSuperGlobalArray($superGlobalArray) + { + self::$globals[$superGlobalArray] = array(); + + if (isset($GLOBALS[$superGlobalArray])) { + foreach ($GLOBALS[$superGlobalArray] as $key => $value) { + self::$globals[$superGlobalArray][$key] = serialize($value); + } + } + } + + protected static function restoreSuperGlobalArray($superGlobalArray) + { + if (isset($GLOBALS[$superGlobalArray])) { + foreach ($GLOBALS[$superGlobalArray] as $key => $value) { + if (isset(self::$globals[$superGlobalArray][$key])) { + $GLOBALS[$superGlobalArray][$key] = unserialize( + self::$globals[$superGlobalArray][$key] + ); + } else { + unset($GLOBALS[$superGlobalArray][$key]); + } + } + } + + self::$globals[$superGlobalArray] = array(); + } + + public static function getIncludedFilesAsString() + { + $blacklist = PHPUnit_Util_Filter::getBlacklistedFiles(); + $blacklist = array_flip($blacklist['PHPUNIT']); + $files = get_included_files(); + $result = ''; + + for ($i = count($files) - 1; $i > 0; $i--) { + if (!isset($blacklist[$files[$i]]) && is_file($files[$i])) { + $result = 'require_once \'' . $files[$i] . "';\n" . $result; + } + } + + return $result; + } + + public static function getConstantsAsString() + { + $constants = get_defined_constants(TRUE); + $result = ''; + + if (isset($constants['user'])) { + foreach ($constants['user'] as $name => $value) { + $result .= sprintf( + 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", + $name, + $name, + self::exportVariable($value) + ); + } + } + + return $result; + } + + public static function getGlobalsAsString() + { + $result = ''; + $superGlobalArrays = self::getSuperGlobalArrays(); + + foreach ($superGlobalArrays as $superGlobalArray) { + if (isset($GLOBALS[$superGlobalArray])) { + foreach ($GLOBALS[$superGlobalArray] as $key => $value) { + $result .= sprintf( + '$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n", + $superGlobalArray, + $key, + self::exportVariable($GLOBALS[$superGlobalArray][$key]) + ); + } + } + } + + $blacklist = $superGlobalArrays; + $blacklist[] = 'GLOBALS'; + $blacklist[] = '_PEAR_Config_instance'; + + foreach (array_keys($GLOBALS) as $key) { + if (!in_array($key, $blacklist)) { + $result .= sprintf( + '$GLOBALS[\'%s\'] = %s;' . "\n", + $key, + self::exportVariable($GLOBALS[$key]) + ); + } + } + + return $result; + } + + protected static function getSuperGlobalArrays() + { + if (ini_get('register_long_arrays') == '1') { + return array_merge( + self::$superGlobalArrays, self::$superGlobalArraysLong + ); + } else { + return self::$superGlobalArrays; + } + } + + public static function backupStaticAttributes(array $blacklist) + { + self::$staticAttributes = array(); + $declaredClasses = get_declared_classes(); + $declaredClassesNum = count($declaredClasses); + + for ($i = $declaredClassesNum - 1; $i >= 0; $i--) { + if (strpos($declaredClasses[$i], 'PHPUnit') !== 0 && + !$declaredClasses[$i] instanceof PHPUnit_Framework_Test) { + $class = new ReflectionClass($declaredClasses[$i]); + + if (!$class->isUserDefined()) { + break; + } + + $backup = array(); + + foreach ($class->getProperties() as $attribute) { + if ($attribute->isStatic()) { + $name = $attribute->getName(); + + if (!isset($blacklist[$declaredClasses[$i]]) || + !in_array($name, $blacklist[$declaredClasses[$i]])) { + $attribute->setAccessible(TRUE); + $backup[$name] = serialize($attribute->getValue()); + } + } + } + + if (!empty($backup)) { + self::$staticAttributes[$declaredClasses[$i]] = $backup; + } + } + } + } + + public static function restoreStaticAttributes() + { + foreach (self::$staticAttributes as $className => $staticAttributes) { + foreach ($staticAttributes as $name => $value) { + $reflector = new ReflectionProperty($className, $name); + $reflector->setAccessible(TRUE); + $reflector->setValue(unserialize($value)); + } + } + + self::$staticAttributes = array(); + } + + protected static function exportVariable($variable) + { + if (is_scalar($variable) || is_null($variable) || + (is_array($variable) && self::arrayOnlyContainsScalars($variable))) { + return var_export($variable, TRUE); + } + + return 'unserialize(\'' . serialize($variable) . '\')'; + } + + protected static function arrayOnlyContainsScalars(array $array) + { + $result = TRUE; + + foreach ($array as $element) { + if (is_array($element)) { + $result = self::arrayOnlyContainsScalars($element); + } + + else if (!is_scalar($element) && !is_null($element)) { + $result = FALSE; + } + + if ($result === FALSE) { + break; + } + } + + return $result; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/InvalidArgumentHelper.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/InvalidArgumentHelper.php new file mode 100644 index 00000000..0adc7a7f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/InvalidArgumentHelper.php @@ -0,0 +1,89 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Factory for InvalidArgumentException objects. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_InvalidArgumentHelper +{ + /** + * @param integer $argument + * @param string $type + * @param mixed $value + */ + public static function factory($argument, $type, $value = NULL) + { + if (version_compare(PHP_VERSION, '5.2.5', '>=')) { + $stack = debug_backtrace(FALSE); + } else { + $stack = debug_backtrace(); + } + + return new InvalidArgumentException( + sprintf( + 'Argument #%d%sof %s:%s() is no %s', + $argument, + $value !== NULL ? ' (' . $value . ')' : ' ', + $stack[1]['class'], + $stack[1]['function'], + $type + ) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CPD.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CPD.php new file mode 100644 index 00000000..a30d10eb --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CPD.php @@ -0,0 +1,129 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Runner/Version.php'; +require_once 'PHPUnit/Util/Metrics/Project.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/XML.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generates an XML logfile with code duplication information. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_CPD extends PHPUnit_Util_Printer +{ + /** + * @param PHPUnit_Framework_TestResult $result + */ + public function process(PHPUnit_Framework_TestResult $result, $minLines = 5, $minMatches = 70) + { + $codeCoverage = $result->getCodeCoverageInformation(); + $summary = PHPUnit_Util_CodeCoverage::getSummary($codeCoverage); + $files = array_keys($summary); + $metrics = new PHPUnit_Util_Metrics_Project($files, $summary, TRUE, $minLines, $minMatches); + + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = TRUE; + + $cpd = $document->createElement('pmd-cpd'); + $cpd->setAttribute('version', 'PHPUnit ' . PHPUnit_Runner_Version::id()); + $document->appendChild($cpd); + + foreach ($metrics->getDuplicates() as $duplicate) { + $xmlDuplication = $cpd->appendChild( + $document->createElement('duplication') + ); + + $xmlDuplication->setAttribute('lines', $duplicate['numLines']); + $xmlDuplication->setAttribute('tokens', $duplicate['numTokens']); + + $xmlFile = $xmlDuplication->appendChild( + $document->createElement('file') + ); + + $xmlFile->setAttribute('path', $duplicate['fileA']->getPath()); + $xmlFile->setAttribute('line', $duplicate['firstLineA']); + + $xmlFile = $xmlDuplication->appendChild( + $document->createElement('file') + ); + + $xmlFile->setAttribute('path', $duplicate['fileB']->getPath()); + $xmlFile->setAttribute('line', $duplicate['firstLineB']); + + $xmlDuplication->appendChild( + $document->createElement( + 'codefragment', + PHPUnit_Util_XML::prepareString( + join( + '', + array_slice( + $duplicate['fileA']->getLines(), + $duplicate['firstLineA'] - 1, + $duplicate['numLines'] + ) + ) + ) + ) + ); + } + + $this->write($document->saveXML()); + $this->flush(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/Database.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/Database.php new file mode 100644 index 00000000..cbe164c7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/Database.php @@ -0,0 +1,596 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.4 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Metrics/Project.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Util_Log_CodeCoverage_Database +{ + /** + * @var PDO + */ + protected $dbh; + + /** + * Constructor. + * + * @param PDO $dbh + * @throws PDOException + */ + public function __construct(PDO $dbh) + { + $this->dbh = $dbh; + } + + /** + * Stores code coverage information. + * + * @param PHPUnit_Framework_TestResult $result + * @param integer $runId + * @param integer $revision + * @param string $commonPath + */ + public function storeCodeCoverage(PHPUnit_Framework_TestResult $result, $runId, $revision, $commonPath = '') + { + $codeCoverage = $result->getCodeCoverageInformation(FALSE); + $summary = PHPUnit_Util_CodeCoverage::getSummary($codeCoverage); + $files = array_keys($summary); + $projectMetrics = new PHPUnit_Util_Metrics_Project($files, $summary); + $storedClasses = array(); + + if (empty($commonPath)) { + $commonPath = PHPUnit_Util_Filesystem::getCommonPath($files); + } + + $this->dbh->beginTransaction(); + + foreach ($files as $fileName) { + $shortenedFileName = str_replace($commonPath, '', $fileName); + $fileId = FALSE; + $fileMetrics = $projectMetrics->getFile($fileName); + $lines = $fileMetrics->getLines(); + $hash = md5_file($fileName); + + $stmt = $this->dbh->prepare( + 'SELECT code_file_id + FROM code_file + WHERE code_file_name = :shortenedFileName + AND revision = :revision;' + ); + + $stmt->bindParam(':shortenedFileName', $shortenedFileName, PDO::PARAM_STR); + $stmt->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmt->execute(); + + if ($stmt) { + $fileId = (int)$stmt->fetchColumn(); + } + + unset($stmt); + + if ($fileId == 0) { + $stmt = $this->dbh->prepare( + 'INSERT INTO code_file + (code_file_name, code_full_file_name, + code_file_md5, revision) + VALUES(:shortenedFileName, :fullFileName, + :hash, :revision);' + ); + + $stmt->bindParam(':shortenedFileName', $shortenedFileName, PDO::PARAM_STR); + $stmt->bindParam(':fullFileName', $fileName, PDO::PARAM_STR); + $stmt->bindParam(':hash', $hash, PDO::PARAM_STR); + $stmt->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmt->execute(); + + $fileId = $this->dbh->lastInsertId(); + + $stmt = $this->dbh->prepare( + 'INSERT INTO code_class + (code_file_id, code_class_name, + code_class_start_line, code_class_end_line) + VALUES(:fileId, :className, :startLine, :endLine);' + ); + + foreach ($fileMetrics->getClasses() as $classMetrics) { + $className = $classMetrics->getClass()->getName(); + $classStartLine = $classMetrics->getClass()->getStartLine(); + $classEndLine = $classMetrics->getClass()->getEndLine(); + + $stmt->bindParam(':fileId', $fileId, PDO::PARAM_INT); + $stmt->bindParam(':className', $className, PDO::PARAM_STR); + $stmt->bindParam(':startLine', $classStartLine, PDO::PARAM_INT); + $stmt->bindParam(':endLine', $classEndLine, PDO::PARAM_INT); + $stmt->execute(); + + $classId = $this->dbh->lastInsertId(); + $storedClasses[$className] = $classId; + + $stmt2 = $this->dbh->prepare( + 'INSERT INTO code_method + (code_class_id, code_method_name, + code_method_start_line, code_method_end_line) + VALUES(:classId, :methodName, :startLine, :endLine);' + ); + + foreach ($classMetrics->getMethods() as $methodMetrics) { + $methodName = $methodMetrics->getMethod()->getName(); + $methodStartLine = $methodMetrics->getMethod()->getStartLine(); + $methodEndLine = $methodMetrics->getMethod()->getEndLine(); + + $stmt2->bindParam(':classId', $classId, PDO::PARAM_INT); + $stmt2->bindParam(':methodName', $methodName, PDO::PARAM_STR); + $stmt2->bindParam(':startLine', $methodStartLine, PDO::PARAM_INT); + $stmt2->bindParam(':endLine', $methodEndLine, PDO::PARAM_INT); + $stmt2->execute(); + } + + unset($stmt2); + } + + $stmt = $this->dbh->prepare( + 'INSERT INTO code_line + (code_file_id, code_line_number, code_line, + code_line_covered) + VALUES(:fileId, :lineNumber, :line, :covered);' + ); + + $i = 1; + + foreach ($lines as $line) { + $covered = 0; + + if (isset($summary[$fileName][$i])) { + if (is_int($summary[$fileName][$i])) { + $covered = $summary[$fileName][$i]; + } else { + $covered = 1; + } + } + + $stmt->bindParam(':fileId', $fileId, PDO::PARAM_INT); + $stmt->bindParam(':lineNumber', $i, PDO::PARAM_INT); + $stmt->bindParam(':line', $line, PDO::PARAM_STR); + $stmt->bindParam(':covered', $covered, PDO::PARAM_INT); + $stmt->execute(); + + $i++; + } + } + + $stmt = $this->dbh->prepare( + 'INSERT INTO metrics_file + (run_id, code_file_id, metrics_file_coverage, + metrics_file_loc, metrics_file_cloc, metrics_file_ncloc, + metrics_file_loc_executable, metrics_file_loc_executed) + VALUES(:runId, :fileId, :coverage, :loc, :cloc, :ncloc, + :locExecutable, :locExecuted);' + ); + + $fileCoverage = $fileMetrics->getCoverage(); + $fileLoc = $fileMetrics->getLoc(); + $fileCloc = $fileMetrics->getCloc(); + $fileNcloc = $fileMetrics->getNcloc(); + $fileLocExecutable = $fileMetrics->getLocExecutable(); + $fileLocExecuted = $fileMetrics->getLocExecuted(); + + $stmt->bindParam(':runId', $runId, PDO::PARAM_INT); + $stmt->bindParam(':fileId', $fileId, PDO::PARAM_INT); + $stmt->bindParam(':coverage', $fileCoverage); + $stmt->bindParam(':loc', $fileLoc, PDO::PARAM_INT); + $stmt->bindParam(':cloc', $fileCloc, PDO::PARAM_INT); + $stmt->bindParam(':ncloc', $fileNcloc, PDO::PARAM_INT); + $stmt->bindParam(':locExecutable', $fileLocExecutable, PDO::PARAM_INT); + $stmt->bindParam(':locExecuted', $fileLocExecuted, PDO::PARAM_INT); + $stmt->execute(); + + $stmtSelectFunctionId = $this->dbh->prepare( + 'SELECT code_function_id + FROM code_file, code_function + WHERE code_function.code_file_id = code_file.code_file_id + AND code_file.revision = :revision + AND code_function.code_function_name = :functionName;' + ); + + $stmtInsertFunction = $this->dbh->prepare( + 'INSERT INTO metrics_function + (run_id, code_function_id, metrics_function_coverage, + metrics_function_loc, metrics_function_loc_executable, metrics_function_loc_executed, + metrics_function_ccn, metrics_function_crap, metrics_function_npath) + VALUES(:runId, :functionId, :coverage, :loc, + :locExecutable, :locExecuted, :ccn, :crap, :npath);' + ); + + $stmtSelectClassId = $this->dbh->prepare( + 'SELECT code_class_id + FROM code_file, code_class + WHERE code_class.code_file_id = code_file.code_file_id + AND code_file.revision = :revision + AND code_class.code_class_name = :className;' + ); + + $stmtInsertClass = $this->dbh->prepare( + 'INSERT INTO metrics_class + (run_id, code_class_id, metrics_class_coverage, + metrics_class_loc, metrics_class_loc_executable, metrics_class_loc_executed, + metrics_class_aif, metrics_class_ahf, + metrics_class_cis, metrics_class_csz, metrics_class_dit, + metrics_class_impl, metrics_class_mif, metrics_class_mhf, + metrics_class_noc, metrics_class_pf, metrics_class_vars, + metrics_class_varsnp, metrics_class_varsi, + metrics_class_wmc, metrics_class_wmcnp, metrics_class_wmci) + VALUES(:runId, :classId, :coverage, :loc, :locExecutable, + :locExecuted, :aif, :ahf, :cis, :csz, :dit, :impl, + :mif, :mhf, :noc, :pf, :vars, :varsnp, :varsi, + :wmc, :wmcnp, :wmci);' + ); + + $stmtSelectMethodId = $this->dbh->prepare( + 'SELECT code_method_id + FROM code_file, code_class, code_method + WHERE code_class.code_file_id = code_file.code_file_id + AND code_class.code_class_id = code_method.code_class_id + AND code_file.revision = :revision + AND code_class.code_class_name = :className + AND code_method.code_method_name = :methodName;' + ); + + $stmtInsertMethod = $this->dbh->prepare( + 'INSERT INTO metrics_method + (run_id, code_method_id, metrics_method_coverage, + metrics_method_loc, metrics_method_loc_executable, metrics_method_loc_executed, + metrics_method_ccn, metrics_method_crap, metrics_method_npath) + VALUES(:runId, :methodId, :coverage, :loc, + :locExecutable, :locExecuted, :ccn, :crap, :npath);' + ); + + foreach ($fileMetrics->getFunctions() as $functionMetrics) { + $functionName = $functionMetrics->getFunction()->getName(); + + $stmtSelectFunctionId->bindParam(':functionName', $functionName, PDO::PARAM_STR); + $stmtSelectFunctionId->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmtSelectFunctionId->execute(); + + $functionId = (int)$stmtSelectFunctionId->fetchColumn(); + $stmtSelectFunctionId->closeCursor(); + + $functionCoverage = $functionMetrics->getCoverage(); + $functionLoc = $functionMetrics->getLoc(); + $functionLocExecutable = $functionMetrics->getLocExecutable(); + $functionLocExecuted = $functionMetrics->getLocExecuted(); + $functionCcn = $functionMetrics->getCCN(); + $functionCrap = $functionMetrics->getCrapIndex(); + $functionNpath = $functionMetrics->getNPath(); + + $stmtInsertFunction->bindParam(':runId', $runId, PDO::PARAM_INT); + $stmtInsertFunction->bindParam(':functionId', $functionId, PDO::PARAM_INT); + $stmtInsertFunction->bindParam(':coverage', $functionCoverage); + $stmtInsertFunction->bindParam(':loc', $functionLoc, PDO::PARAM_INT); + $stmtInsertFunction->bindParam(':locExecutable', $functionLocExecutable, PDO::PARAM_INT); + $stmtInsertFunction->bindParam(':locExecuted', $functionLocExecuted, PDO::PARAM_INT); + $stmtInsertFunction->bindParam(':ccn', $functionCcn, PDO::PARAM_INT); + $stmtInsertFunction->bindParam(':crap', $functionCrap); + $stmtInsertFunction->bindParam(':npath', $functionNpath, PDO::PARAM_INT); + $stmtInsertFunction->execute(); + } + + foreach ($fileMetrics->getClasses() as $classMetrics) { + $className = $classMetrics->getClass()->getName(); + + $stmtSelectClassId->bindParam(':className', $className, PDO::PARAM_STR); + $stmtSelectClassId->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmtSelectClassId->execute(); + + $classId = (int)$stmtSelectClassId->fetchColumn(); + $stmtSelectClassId->closeCursor(); + + $classCoverage = $classMetrics->getCoverage(); + $classLoc = $classMetrics->getLoc(); + $classLocExecutable = $classMetrics->getLocExecutable(); + $classLocExecuted = $classMetrics->getLocExecuted(); + $classAif = $classMetrics->getAIF(); + $classAhf = $classMetrics->getAHF(); + $classCis = $classMetrics->getCIS(); + $classCsz = $classMetrics->getCSZ(); + $classDit = $classMetrics->getDIT(); + $classImpl = $classMetrics->getIMPL(); + $classMif = $classMetrics->getMIF(); + $classMhf = $classMetrics->getMHF(); + $classNoc = $classMetrics->getNOC(); + $classPf = $classMetrics->getPF(); + $classVars = $classMetrics->getVARS(); + $classVarsnp = $classMetrics->getVARSnp(); + $classVarsi = $classMetrics->getVARSi(); + $classWmc = $classMetrics->getWMC(); + $classWmcnp = $classMetrics->getWMCnp(); + $classWmci = $classMetrics->getWMCi(); + + $stmtInsertClass->bindParam(':runId', $runId, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':classId', $classId, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':coverage', $classCoverage); + $stmtInsertClass->bindParam(':loc', $classLoc, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':locExecutable', $classLocExecutable, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':locExecuted', $classLocExecuted, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':aif', $classAif); + $stmtInsertClass->bindParam(':ahf', $classAhf); + $stmtInsertClass->bindParam(':cis', $classCis, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':csz', $classCsz, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':dit', $classDit, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':impl', $classImpl, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':mif', $classMif); + $stmtInsertClass->bindParam(':mhf', $classMhf); + $stmtInsertClass->bindParam(':noc', $classNoc, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':pf', $classPf); + $stmtInsertClass->bindParam(':vars', $classVars, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':varsnp', $classVarsnp, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':varsi', $classVarsi, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':wmc', $classWmc, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':wmcnp', $classWmcnp, PDO::PARAM_INT); + $stmtInsertClass->bindParam(':wmci', $classWmci, PDO::PARAM_INT); + $stmtInsertClass->execute(); + + foreach ($classMetrics->getMethods() as $methodMetrics) { + $methodName = $methodMetrics->getMethod()->getName(); + + $stmtSelectMethodId->bindParam(':className', $className, PDO::PARAM_STR); + $stmtSelectMethodId->bindParam(':methodName', $methodName, PDO::PARAM_STR); + $stmtSelectMethodId->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmtSelectMethodId->execute(); + + $methodId = (int)$stmtSelectMethodId->fetchColumn(); + $stmtSelectMethodId->closeCursor(); + + $methodCoverage = $methodMetrics->getCoverage(); + $methodLoc = $methodMetrics->getLoc(); + $methodLocExecutable = $methodMetrics->getLocExecutable(); + $methodLocExecuted = $methodMetrics->getLocExecuted(); + $methodCcn = $methodMetrics->getCCN(); + $methodCrap = $methodMetrics->getCrapIndex(); + $methodNpath = $methodMetrics->getNPath(); + + $stmtInsertMethod->bindParam(':runId', $runId, PDO::PARAM_INT); + $stmtInsertMethod->bindParam(':methodId', $methodId, PDO::PARAM_INT); + $stmtInsertMethod->bindParam(':coverage', $methodCoverage); + $stmtInsertMethod->bindParam(':loc', $methodLoc, PDO::PARAM_INT); + $stmtInsertMethod->bindParam(':locExecutable', $methodLocExecutable, PDO::PARAM_INT); + $stmtInsertMethod->bindParam(':locExecuted', $methodLocExecuted, PDO::PARAM_INT); + $stmtInsertMethod->bindParam(':ccn', $methodCcn, PDO::PARAM_INT); + $stmtInsertMethod->bindParam(':crap', $methodCrap); + $stmtInsertMethod->bindParam(':npath', $methodNpath, PDO::PARAM_INT); + $stmtInsertMethod->execute(); + } + } + + unset($stmtSelectFunctionId); + unset($stmtInsertFunction); + unset($stmtSelectClassId); + unset($stmtInsertClass); + unset($stmtSelectMethodId); + unset($stmtInsertMethod); + + $stmt = $this->dbh->prepare( + 'SELECT code_line_id, code_line_covered + FROM code_line + WHERE code_file_id = :fileId + AND code_line_number = :lineNumber;' + ); + + $stmt2 = $this->dbh->prepare( + 'UPDATE code_line + SET code_line_covered = :lineCovered + WHERE code_line_id = :lineId;' + ); + + $stmt3 = $this->dbh->prepare( + 'INSERT INTO code_coverage + (test_id, code_line_id) + VALUES(:testId, :lineId);' + ); + + for ($lineNumber = 1; $lineNumber <= $fileLoc; $lineNumber++) { + $coveringTests = PHPUnit_Util_CodeCoverage::getCoveringTests( + $codeCoverage, $fileName, $lineNumber + ); + + if (is_array($coveringTests)) { + $stmt->bindParam(':fileId', $fileId, PDO::PARAM_INT); + $stmt->bindParam(':lineNumber', $lineNumber, PDO::PARAM_INT); + $stmt->execute(); + + $codeLineId = (int)$stmt->fetchColumn(0); + $oldCoverageFlag = (int)$stmt->fetchColumn(1); + $newCoverageFlag = isset($summary[$fileName][$lineNumber]) ? 1 : 0; + + if (($oldCoverageFlag == 0 && $newCoverageFlag != 0) || + ($oldCoverageFlag < 0 && $newCoverageFlag > 0)) { + $stmt2->bindParam(':lineCovered', $newCoverageFlag, PDO::PARAM_INT); + $stmt2->bindParam(':lineId', $codeLineId, PDO::PARAM_INT); + $stmt2->execute(); + } + + foreach ($coveringTests as $test) { + $stmt3->bindParam(':testId', $test->__db_id, PDO::PARAM_INT); + $stmt3->bindParam(':lineId', $codeLineId, PDO::PARAM_INT); + $stmt3->execute(); + } + } + } + } + + unset($stmt); + unset($stmt2); + unset($stmt3); + + $stmt = $this->dbh->prepare( + 'SELECT code_method.code_method_id + FROM code_class, code_method + WHERE code_class.code_class_id = code_method.code_class_id + AND code_class.code_class_name = :className + AND code_method.code_method_name = :methodName;' + ); + + $stmt2 = $this->dbh->prepare( + 'UPDATE test + SET code_method_id = :methodId + WHERE test_id = :testId;' + ); + + foreach ($result->topTestSuite() as $test) { + if ($test instanceof PHPUnit_Framework_TestCase) { + $className = get_class($test); + $methodName = $test->getName(); + + $stmt->bindParam(':className', $className, PDO::PARAM_STR); + $stmt->bindParam(':methodName', $methodName, PDO::PARAM_STR); + $stmt->execute(); + + $methodId = (int)$stmt->fetchColumn(); + $stmt->closeCursor(); + + $stmt2->bindParam(':methodId', $methodId, PDO::PARAM_INT); + $stmt2->bindParam(':testId', $test->__db_id, PDO::PARAM_INT); + $stmt2->execute(); + } + } + + unset($stmt); + unset($stmt2); + + $stmt = $this->dbh->prepare( + 'INSERT INTO metrics_project + (run_id, metrics_project_cls, metrics_project_clsa, + metrics_project_clsc, metrics_project_roots, + metrics_project_leafs, metrics_project_interfs, + metrics_project_maxdit) + VALUES(:runId, :cls, :clsa, :clsc, :roots, :leafs, + :interfs, :maxdit);' + ); + + $cls = $projectMetrics->getCLS(); + $clsa = $projectMetrics->getCLSa(); + $clsc = $projectMetrics->getCLSc(); + $interfs = $projectMetrics->getInterfs(); + $roots = $projectMetrics->getRoots(); + $leafs = $projectMetrics->getLeafs(); + $maxDit = $projectMetrics->getMaxDit(); + + $stmt->bindParam(':runId', $runId, PDO::PARAM_INT); + $stmt->bindParam(':cls', $cls, PDO::PARAM_INT); + $stmt->bindParam(':clsa', $clsa, PDO::PARAM_INT); + $stmt->bindParam(':clsc', $clsc, PDO::PARAM_INT); + $stmt->bindParam(':roots', $roots, PDO::PARAM_INT); + $stmt->bindParam(':leafs', $leafs, PDO::PARAM_INT); + $stmt->bindParam(':interfs', $interfs, PDO::PARAM_INT); + $stmt->bindParam(':maxdit', $maxDit, PDO::PARAM_INT); + $stmt->execute(); + + unset($stmt); + + $stmt = $this->dbh->prepare( + 'UPDATE code_class + SET code_class_parent_id = :parentClassId + WHERE code_class_id = :classId;' + ); + + $stmt2 = $this->dbh->prepare( + 'SELECT code_class.code_class_id as code_class_id + FROM code_class, code_file + WHERE code_class.code_file_id = code_file.code_file_id + AND code_file.revision = :revision + AND code_class.code_class_name = :parentClassName;' + ); + + foreach ($storedClasses as $className => $classId) { + $class = new ReflectionClass($className); + $parentClass = $class->getParentClass(); + + if ($parentClass !== FALSE) { + $parentClassName = $parentClass->getName(); + $parentClassId = 0; + + if (isset($storedClasses[$parentClassName])) { + $parentClassId = $storedClasses[$parentClassName]; + } else { + $stmt2->bindParam(':parentClassName', $parentClassName, PDO::PARAM_STR); + $stmt2->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmt2->execute(); + + $parentClassId = (int)$stmt2->fetchColumn(); + $stmt2->closeCursor(); + } + + if ($parentClassId > 0) { + $stmt->bindParam(':classId', $classId, PDO::PARAM_INT); + $stmt->bindParam(':parentClassId', $parentClassId, PDO::PARAM_INT); + $stmt->execute(); + } + } + } + + unset($stmt); + unset($stmt2); + + $this->dbh->commit(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/XML/Clover.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/XML/Clover.php new file mode 100644 index 00000000..94ea0fc3 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/XML/Clover.php @@ -0,0 +1,348 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Runner/Version.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/File.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generates an XML logfile with code coverage information using the + * Clover format "documented" at + * http://svn.atlassian.com/svn/public/contrib/bamboo/bamboo-coverage-plugin/trunk/src/test/resources/test-clover-report.xml + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Util_Log_CodeCoverage_XML_Clover extends PHPUnit_Util_Printer +{ + /** + * @param PHPUnit_Framework_TestResult $result + * @todo Count conditionals. + */ + public function process(PHPUnit_Framework_TestResult $result) + { + $time = time(); + + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = TRUE; + + $coverage = $document->createElement('coverage'); + $coverage->setAttribute('generated', $time); + $coverage->setAttribute('phpunit', PHPUnit_Runner_Version::id()); + $document->appendChild($coverage); + + $project = $document->createElement('project'); + $project->setAttribute('name', $result->topTestSuite()->getName()); + $project->setAttribute('timestamp', $time); + $coverage->appendChild($project); + + $codeCoverageInformation = $result->getCodeCoverageInformation(); + $files = PHPUnit_Util_CodeCoverage::getSummary( + $codeCoverageInformation + ); + $packages = array(); + + $projectStatistics = array( + 'files' => 0, + 'loc' => 0, + 'ncloc' => 0, + 'classes' => 0, + 'methods' => 0, + 'coveredMethods' => 0, + 'conditionals' => 0, + 'coveredConditionals' => 0, + 'statements' => 0, + 'coveredStatements' => 0 + ); + + foreach ($files as $filename => $data) { + $namespace = 'global'; + + if (file_exists($filename)) { + $fileStatistics = array( + 'classes' => 0, + 'methods' => 0, + 'coveredMethods' => 0, + 'conditionals' => 0, + 'coveredConditionals' => 0, + 'statements' => 0, + 'coveredStatements' => 0 + ); + + $file = $document->createElement('file'); + $file->setAttribute('name', $filename); + + $classesInFile = PHPUnit_Util_File::getClassesInFile($filename); + $lines = array(); + + foreach ($classesInFile as $className => $_class) { + $classStatistics = array( + 'methods' => 0, + 'coveredMethods' => 0, + 'conditionals' => 0, + 'coveredConditionals' => 0, + 'statements' => 0, + 'coveredStatements' => 0 + ); + + foreach ($_class['methods'] as $methodName => $method) { + $classStatistics['methods']++; + + $methodCount = 0; + + for ($i = $method['startLine']; $i <= $method['endLine']; $i++) { + $add = TRUE; + $count = 0; + + if (isset($files[$filename][$i])) { + if ($files[$filename][$i] != -2) { + $classStatistics['statements']++; + } + + if (is_array($files[$filename][$i])) { + $classStatistics['coveredStatements']++; + $count = count($files[$filename][$i]); + } + + else if ($files[$filename][$i] == -2) { + $add = FALSE; + } + } else { + $add = FALSE; + } + + $methodCount = max($methodCount, $count); + + if ($add) { + $lines[$i] = array( + 'count' => $count, + 'type' => 'stmt' + ); + } + } + + if ($methodCount > 0) { + $classStatistics['coveredMethods']++; + } + + $lines[$method['startLine']] = array( + 'count' => $methodCount, + 'type' => 'method', + 'name' => $methodName + ); + } + + $packageInformation = PHPUnit_Util_Class::getPackageInformation( + $className, $_class['docComment'] + ); + + if (!empty($packageInformation['namespace'])) { + $namespace = $packageInformation['namespace']; + } + + $class = $document->createElement('class'); + $class->setAttribute('name', $className); + $class->setAttribute('namespace', $namespace); + + if (!empty($packageInformation['fullPackage'])) { + $class->setAttribute( + 'fullPackage', $packageInformation['fullPackage'] + ); + } + + if (!empty($packageInformation['category'])) { + $class->setAttribute( + 'category', $packageInformation['category'] + ); + } + + if (!empty($packageInformation['package'])) { + $class->setAttribute( + 'package', $packageInformation['package'] + ); + } + + if (!empty($packageInformation['subpackage'])) { + $class->setAttribute( + 'subpackage', $packageInformation['subpackage'] + ); + } + + $file->appendChild($class); + + $metrics = $document->createElement('metrics'); + $metrics->setAttribute('methods', $classStatistics['methods']); + $metrics->setAttribute('coveredmethods', $classStatistics['coveredMethods']); + //$metrics->setAttribute('conditionals', $classStatistics['conditionals']); + //$metrics->setAttribute('coveredconditionals', $classStatistics['coveredConditionals']); + $metrics->setAttribute('statements', $classStatistics['statements']); + $metrics->setAttribute('coveredstatements', $classStatistics['coveredStatements']); + $metrics->setAttribute('elements', $classStatistics['conditionals'] + $classStatistics['statements'] + $classStatistics['methods']); + $metrics->setAttribute('coveredelements', $classStatistics['coveredConditionals'] + $classStatistics['coveredStatements'] + $classStatistics['coveredMethods']); + $class->appendChild($metrics); + + $fileStatistics['methods'] += $classStatistics['methods']; + $fileStatistics['coveredMethods'] += $classStatistics['coveredMethods']; + $fileStatistics['conditionals'] += $classStatistics['conditionals']; + $fileStatistics['coveredConditionals'] += $classStatistics['coveredConditionals']; + $fileStatistics['statements'] += $classStatistics['statements']; + $fileStatistics['coveredStatements'] += $classStatistics['coveredStatements']; + $fileStatistics['classes']++; + } + + foreach ($data as $_line => $_data) { + if (isset($lines[$_line])) { + continue; + } + + if ($_data != -2) { + $fileStatistics['statements']++; + + if (is_array($_data)) { + $count = count($_data); + $fileStatistics['coveredStatements']++; + } else { + $count = 0; + } + + $lines[$_line] = array( + 'count' => $count, + 'type' => 'stmt' + ); + } + } + + ksort($lines); + + foreach ($lines as $_line => $_data) { + $line = $document->createElement('line'); + $line->setAttribute('num', $_line); + $line->setAttribute('type', $_data['type']); + + if (isset($_data['name'])) { + $line->setAttribute('name', $_data['name']); + } + + $line->setAttribute('count', $_data['count']); + + $file->appendChild($line); + } + + $count = PHPUnit_Util_File::countLines($filename); + + $metrics = $document->createElement('metrics'); + $metrics->setAttribute('loc', $count['loc']); + $metrics->setAttribute('ncloc', $count['ncloc']); + $metrics->setAttribute('classes', $fileStatistics['classes']); + $metrics->setAttribute('methods', $fileStatistics['methods']); + $metrics->setAttribute('coveredmethods', $fileStatistics['coveredMethods']); + //$metrics->setAttribute('conditionals', $fileStatistics['conditionals']); + //$metrics->setAttribute('coveredconditionals', $fileStatistics['coveredConditionals']); + $metrics->setAttribute('statements', $fileStatistics['statements']); + $metrics->setAttribute('coveredstatements', $fileStatistics['coveredStatements']); + $metrics->setAttribute('elements', $fileStatistics['conditionals'] + $fileStatistics['statements'] + $fileStatistics['methods']); + $metrics->setAttribute('coveredelements', $fileStatistics['coveredConditionals'] + $fileStatistics['coveredStatements'] + $fileStatistics['coveredMethods']); + + $file->appendChild($metrics); + + if ($namespace == 'global') { + $project->appendChild($file); + } else { + if (!isset($packages[$namespace])) { + $packages[$namespace] = $document->createElement( + 'package' + ); + + $packages[$namespace]->setAttribute('name', $namespace); + $project->appendChild($packages[$namespace]); + } + + $packages[$namespace]->appendChild($file); + } + + $projectStatistics['loc'] += $count['loc']; + $projectStatistics['ncloc'] += $count['ncloc']; + $projectStatistics['classes'] += $fileStatistics['classes']; + $projectStatistics['methods'] += $fileStatistics['methods']; + $projectStatistics['coveredMethods'] += $fileStatistics['coveredMethods']; + $projectStatistics['conditionals'] += $fileStatistics['conditionals']; + $projectStatistics['coveredConditionals'] += $fileStatistics['coveredConditionals']; + $projectStatistics['statements'] += $fileStatistics['statements']; + $projectStatistics['coveredStatements'] += $fileStatistics['coveredStatements']; + $projectStatistics['files']++; + } + } + + $metrics = $document->createElement('metrics'); + $metrics->setAttribute('files', $projectStatistics['files']); + $metrics->setAttribute('loc', $projectStatistics['loc']); + $metrics->setAttribute('ncloc', $projectStatistics['ncloc']); + $metrics->setAttribute('classes', $projectStatistics['classes']); + $metrics->setAttribute('methods', $projectStatistics['methods']); + $metrics->setAttribute('coveredmethods', $projectStatistics['coveredMethods']); + //$metrics->setAttribute('conditionals', $projectStatistics['conditionals']); + //$metrics->setAttribute('coveredconditionals', $projectStatistics['coveredConditionals']); + $metrics->setAttribute('statements', $projectStatistics['statements']); + $metrics->setAttribute('coveredstatements', $projectStatistics['coveredStatements']); + $metrics->setAttribute('elements', $projectStatistics['conditionals'] + $projectStatistics['statements'] + $projectStatistics['methods']); + $metrics->setAttribute('coveredelements', $projectStatistics['coveredConditionals'] + $projectStatistics['coveredStatements'] + $projectStatistics['coveredMethods']); + $project->appendChild($metrics); + + $this->write($document->saveXML()); + $this->flush(); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/XML/Source.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/XML/Source.php new file mode 100644 index 00000000..1c15ebcb --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/CodeCoverage/XML/Source.php @@ -0,0 +1,290 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Runner/Version.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/XML.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Writes one XML file per covered PHP source file to a given directory. + * Each element holds a line of PHP sourcecode that is annotated with + * code coverage information. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Util_Log_CodeCoverage_XML_Source +{ + protected $directory; + + /** + * @param string $directory + */ + public function __construct($directory) + { + $this->directory = PHPUnit_Util_Filesystem::getDirectory($directory); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + public function process(PHPUnit_Framework_TestResult $result) + { + $sutData = $result->getCodeCoverageInformation(); + $sutFiles = PHPUnit_Util_CodeCoverage::getSummary($sutData, TRUE); + $allData = $result->getCodeCoverageInformation(FALSE); + $allFiles = PHPUnit_Util_CodeCoverage::getSummary($allData, TRUE); + $testFiles = array_diff(array_keys($allFiles), array_keys($sutFiles)); + + foreach (array_keys($allFiles) as $key) { + if (!in_array($key, $testFiles)) { + unset($allFiles[$key]); + } + } + + $allCommonPath = PHPUnit_Util_Filesystem::reducePaths($allFiles); + $sutCommonPath = PHPUnit_Util_Filesystem::reducePaths($sutFiles); + $testFiles = $allFiles; + + unset($allData); + unset($allFiles); + unset($sutData); + + $testToCoveredLinesMap = array(); + $time = time(); + + foreach ($sutFiles as $filename => $data) { + $fullPath = $sutCommonPath . DIRECTORY_SEPARATOR . $filename; + + if (file_exists($fullPath)) { + $fullPath = realpath($fullPath); + + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = TRUE; + + $coveredFile = $document->createElement('coveredFile'); + $coveredFile->setAttribute('fullPath', $fullPath); + $coveredFile->setAttribute('shortenedPath', $filename); + $coveredFile->setAttribute('generated', $time); + $coveredFile->setAttribute('phpunit', PHPUnit_Runner_Version::id()); + $document->appendChild($coveredFile); + + $lines = file($fullPath, FILE_IGNORE_NEW_LINES); + $lineNum = 1; + + foreach ($lines as $line) { + if (isset($data[$lineNum])) { + if (is_array($data[$lineNum])) { + $count = count($data[$lineNum]); + } else { + $count = $data[$lineNum]; + } + } else { + $count = -3; + } + + $xmlLine = $coveredFile->appendChild( + $document->createElement('line') + ); + + $xmlLine->setAttribute('lineNumber', $lineNum); + $xmlLine->setAttribute('executed', $count); + + $xmlLine->appendChild( + $document->createElement( + 'body', PHPUnit_Util_XML::prepareString($line) + ) + ); + + if (isset($data[$lineNum]) && is_array($data[$lineNum])) { + $xmlTests = $document->createElement('tests'); + $xmlLine->appendChild($xmlTests); + + foreach ($data[$lineNum] as $test) { + $xmlTest = $xmlTests->appendChild( + $document->createElement('test') + ); + + if ($test instanceof PHPUnit_Framework_TestCase) { + $xmlTest->setAttribute('name', $test->getName()); + $xmlTest->setAttribute('status', $test->getStatus()); + + if ($test->hasFailed()) { + $xmlTest->appendChild( + $document->createElement( + 'message', + PHPUnit_Util_XML::prepareString( + $test->getStatusMessage() + ) + ) + ); + } + + $class = new ReflectionClass($test); + $testFullPath = $class->getFileName(); + $testShortenedPath = str_replace($allCommonPath, '', $testFullPath); + $methodName = $test->getName(FALSE); + + if ($class->hasMethod($methodName)) { + $method = $class->getMethod($methodName); + $startLine = $method->getStartLine(); + + $xmlTest->setAttribute('class', $class->getName()); + $xmlTest->setAttribute('fullPath', $testFullPath); + $xmlTest->setAttribute('shortenedPath', $testShortenedPath); + $xmlTest->setAttribute('line', $startLine); + + if (!isset($testToCoveredLinesMap[$testFullPath][$startLine])) { + $testToCoveredLinesMap[$testFullPath][$startLine] = array(); + } + + if (!isset($testToCoveredLinesMap[$testFullPath][$startLine][$fullPath])) { + $testToCoveredLinesMap[$testFullPath][$startLine][$fullPath] = array( + 'coveredLines' => array($lineNum), + 'shortenedPath' => $filename + ); + } else { + $testToCoveredLinesMap[$testFullPath][$startLine][$fullPath]['coveredLines'][] = $lineNum; + } + } + } + } + } + + $lineNum++; + } + + $document->save( + sprintf( + '%s%s.xml', + + $this->directory, + PHPUnit_Util_Filesystem::getSafeFilename( + basename($filename) + ) + ) + ); + } + } + + foreach ($testFiles as $filename => $data) { + $fullPath = $allCommonPath . DIRECTORY_SEPARATOR . $filename; + + if (file_exists($fullPath)) { + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = TRUE; + + $testFile = $document->createElement('testFile'); + $testFile->setAttribute('fullPath', $fullPath); + $testFile->setAttribute('shortenedPath', $filename); + $testFile->setAttribute('generated', $time); + $testFile->setAttribute('phpunit', PHPUnit_Runner_Version::id()); + $document->appendChild($testFile); + + $lines = file($fullPath, FILE_IGNORE_NEW_LINES); + $lineNum = 1; + + foreach ($lines as $line) { + $xmlLine = $testFile->appendChild( + $document->createElement('line') + ); + + $xmlLine->setAttribute('lineNumber', $lineNum); + + $xmlLine->appendChild( + $document->createElement( + 'body', PHPUnit_Util_XML::prepareString($line) + ) + ); + + if (isset($testToCoveredLinesMap[$fullPath][$lineNum])) { + $xmlCoveredFiles = $xmlLine->appendChild( + $document->createElement('coveredFiles') + ); + + foreach ($testToCoveredLinesMap[$fullPath][$lineNum] as $coveredFileFullPath => $coveredFileData) { + $xmlCoveredFile = $xmlCoveredFiles->appendChild( + $document->createElement('coveredFile') + ); + + $xmlCoveredFile->setAttribute('fullPath', $fullPath); + $xmlCoveredFile->setAttribute('shortenedPath', $coveredFileData['shortenedPath']); + + foreach ($coveredFileData['coveredLines'] as $coveredLineNum) { + $xmlCoveredLine = $xmlCoveredFile->appendChild( + $document->createElement('coveredLine', $coveredLineNum) + ); + } + } + } + + $lineNum++; + } + + $document->save( + sprintf( + '%s%s.xml', + + $this->directory, + PHPUnit_Util_Filesystem::getSafeFilename( + basename($filename) + ) + ) + ); + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database.php new file mode 100644 index 00000000..f4b377c7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database.php @@ -0,0 +1,520 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Runner/BaseTestRunner.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Writes test result and code coverage data to a database. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Util_Log_Database implements PHPUnit_Framework_TestListener +{ + /** + * @var PHPUnit_Util_Log_Database + */ + protected static $instance = NULL; + + /** + * @var integer + */ + protected $currentTestId; + + /** + * @var integer + */ + protected $runId; + + /** + * @var integer[] + */ + protected $testSuites = array(); + + /** + * @var boolean + */ + protected $currentTestSuccess = TRUE; + + /** + * @var PDO + */ + protected $dbh; + + /** + * Constructor. + * + * @param PDO $dbh + * @param integer $revision + * @param string $information + * @throws PDOException + * @throws RuntimeException + */ + protected function __construct(PDO $dbh, $revision, $information = '') + { + $this->dbh = $dbh; + + $stmt = $this->dbh->prepare( + 'INSERT INTO run + (timestamp, revision, information) + VALUES(:timestamp, :revision, :information);' + ); + + $timestamp = time(); + + $stmt->bindParam(':timestamp', $timestamp, PDO::PARAM_INT); + $stmt->bindParam(':revision', $revision, PDO::PARAM_INT); + $stmt->bindParam(':information', $information, PDO::PARAM_STR); + $stmt->execute(); + + $this->runId = $this->dbh->lastInsertId(); + } + + /** + * @param PDO $dbh + * @param integer $revision + * @param string $information + * @return PHPUnit_Util_Log_Database + * @throws InvalidArgumentException + * @throws PDOException + * @throws RuntimeException + */ + public static function getInstance(PDO $dbh = NULL, $revision = '', $information = '') + { + if ($dbh === NULL) { + if (self::$instance != NULL) { + return self::$instance; + } else { + return FALSE; + } + } + + if (self::$instance != NULL) { + throw new RuntimeException; + } + + if (empty($revision)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'non-empty string'); + } + + self::$instance = new PHPUnit_Util_Log_Database( + $dbh, $revision, $information + ); + + return self::$instance; + } + + /** + * Returns the ID of the current test. + * + * @return integer + */ + public function getCurrentTestId() + { + return $this->currentTestId; + } + + /** + * Returns the ID of this test run. + * + * @return integer + */ + public function getRunId() + { + return $this->runId; + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $message = PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE); + + $this->storeResult( + PHPUnit_Runner_BaseTestRunner::STATUS_ERROR, + $time, + $message + ); + + $this->updateParents( + $time, PHPUnit_Runner_BaseTestRunner::STATUS_ERROR + ); + + $this->currentTestSuccess = FALSE; + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $message = PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE); + + $this->storeResult( + PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE, + $time, + $message + ); + + $this->updateParents( + $time, PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE + ); + + $this->currentTestSuccess = FALSE; + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $message = PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE); + + $this->storeResult( + PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE, + $time, + $message + ); + + $this->currentTestSuccess = FALSE; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $message = PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE); + + $this->storeResult( + PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED, + $time, + $message + ); + + $this->currentTestSuccess = FALSE; + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + if (empty($this->testSuites)) { + $testSuiteId = $this->insertRootNode($suite->getName()); + } else { + $testSuiteId = $this->insertNode($suite); + } + + $this->testSuites[] = array( + 'id' => $testSuiteId, + 'result' => PHPUnit_Runner_BaseTestRunner::STATUS_PASSED + ); + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + array_pop($this->testSuites); + + if (empty($this->testSuites)) { + $stmt = $this->dbh->prepare( + 'UPDATE run + SET completed = 1 + WHERE run_id = :runId;' + ); + + $stmt->bindParam(':runId', $this->runId, PDO::PARAM_INT); + $stmt->execute(); + } + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->insertNode($test); + $this->currentTestSuccess = TRUE; + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($this->currentTestSuccess) { + $this->storeResult( + PHPUnit_Runner_BaseTestRunner::STATUS_PASSED, $time + ); + + $this->updateParents($time); + } + } + + /** + * Inserts the root node into the tree. + * + * @param string $name + * @return integer + * @throws PDOException + */ + protected function insertRootNode($name) + { + $this->dbh->beginTransaction(); + + $stmt = $this->dbh->prepare( + 'INSERT INTO test + (run_id, test_name, node_left, node_right, node_is_leaf, + node_parent, node_depth) + VALUES(:runId, :testName, 1, 2, 0, 0, 0);' + ); + + $stmt->bindParam(':runId', $this->runId, PDO::PARAM_INT); + $stmt->bindParam(':testName', $name, PDO::PARAM_STR); + $stmt->execute(); + + $rootId = $this->dbh->lastInsertId(); + + $stmt = $this->dbh->prepare( + 'UPDATE test + SET node_root = :root + WHERE test_id = :testId;' + ); + + $stmt->bindParam(':root', $rootId, PDO::PARAM_INT); + $stmt->bindParam(':testId', $rootId, PDO::PARAM_INT); + $stmt->execute(); + + $this->dbh->commit(); + + return $rootId; + } + + /** + * Inserts a node into the tree. + * + * @param PHPUnit_Framework_Test $test + * @throws PDOException + */ + protected function insertNode(PHPUnit_Framework_Test $test) + { + $isLeaf = (int)!$test instanceof PHPUnit_Framework_TestSuite; + + $this->dbh->beginTransaction(); + + $stmt = $this->dbh->prepare( + 'SELECT node_right + FROM test + WHERE test_id = :testId;' + ); + + $stmt->bindParam(':testId', $this->testSuites[count($this->testSuites)-1]['id'], PDO::PARAM_INT); + $stmt->execute(); + + $right = (int)$stmt->fetchColumn(); + unset($stmt); + + $stmt = $this->dbh->prepare( + 'UPDATE test + SET node_left = node_left + 2 + WHERE node_root = :root + AND node_left > :left;' + ); + + $stmt->bindParam(':root', $this->testSuites[0]['id'], PDO::PARAM_INT); + $stmt->bindParam(':left', $right, PDO::PARAM_INT); + $stmt->execute(); + + $stmt = $this->dbh->prepare( + 'UPDATE test + SET node_right = node_right + 2 + WHERE node_root = :root + AND node_right >= :right;' + ); + + $stmt->bindParam(':root', $this->testSuites[0]['id'], PDO::PARAM_INT); + $stmt->bindParam(':right', $right, PDO::PARAM_INT); + $stmt->execute(); + + $testName = $test->getName(); + $left = $right; + $right = $right + 1; + + $stmt = $this->dbh->prepare( + 'INSERT INTO test + (run_id, test_name, test_result, test_message, + test_execution_time, node_root, node_parent, node_left, + node_right, node_depth, node_is_leaf) + VALUES(:runId, :testName, 0, "", 0, :root, :parent, :left, :right, :depth, + :isLeaf);' + ); + + $currentTestDepth = count($this->testSuites); + + $stmt->bindParam(':runId', $this->runId, PDO::PARAM_INT); + $stmt->bindParam(':testName', $testName, PDO::PARAM_STR); + $stmt->bindParam(':root', $this->testSuites[0]['id'], PDO::PARAM_INT); + $stmt->bindParam(':parent', $this->testSuites[(count($this->testSuites)-1)]['id'], PDO::PARAM_INT); + $stmt->bindParam(':left', $left, PDO::PARAM_INT); + $stmt->bindParam(':right', $right, PDO::PARAM_INT); + $stmt->bindPAram(':depth', $currentTestDepth, PDO::PARAM_INT); + $stmt->bindParam(':isLeaf', $isLeaf, PDO::PARAM_INT); + $stmt->execute(); + + $this->currentTestId = $this->dbh->lastInsertId(); + $this->dbh->commit(); + + if (!$test instanceof PHPUnit_Framework_TestSuite) { + $test->__db_id = $this->currentTestId; + } + + return $this->currentTestId; + } + + /** + * Stores a test result. + * + * @param integer $result + * @param float $time + * @param string $message + * @throws PDOException + */ + protected function storeResult($result = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED, $time = 0, $message = '') + { + $stmt = $this->dbh->prepare( + 'UPDATE test + SET test_result = :result, + test_message = :message, + test_execution_time = :executionTime + WHERE test_id = :testId;' + ); + + $stmt->bindParam(':result', $result, PDO::PARAM_INT); + $stmt->bindParam(':message', $message, PDO::PARAM_STR); + $stmt->bindParam(':executionTime', $time); + $stmt->bindParam(':testId', $this->currentTestId, PDO::PARAM_INT); + $stmt->execute(); + } + + /** + * @param float $time + * @param integer $result + * @throws PDOException + */ + protected function updateParents($time, $result = NULL) + { + $stmtUpdateResultAndTime = $this->dbh->prepare( + 'UPDATE test + SET test_result = :result, + test_execution_time = test_execution_time + :time + WHERE test_id = :testSuiteId;' + ); + + $stmtUpdateTime = $this->dbh->prepare( + 'UPDATE test + SET test_execution_time = test_execution_time + :time + WHERE test_id = :testSuiteId;' + ); + + foreach ($this->testSuites as &$testSuite) { + if ($result > $testSuite['result']) { + $stmtUpdateResultAndTime->bindParam(':result', $result, PDO::PARAM_INT); + $stmtUpdateResultAndTime->bindParam(':testSuiteId', $testSuite['id'], PDO::PARAM_INT); + $stmtUpdateResultAndTime->bindParam(':time', $time); + $stmtUpdateResultAndTime->execute(); + + $testSuite['result'] = $result; + } else { + $stmtUpdateTime->bindParam(':testSuiteId', $testSuite['id'], PDO::PARAM_INT); + $stmtUpdateTime->bindParam(':time', $time); + $stmtUpdateTime->execute(); + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database/MySQL.sql b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database/MySQL.sql new file mode 100644 index 00000000..7a33dd8b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database/MySQL.sql @@ -0,0 +1,210 @@ +# +# PHPUnit +# +# Copyright (c) 2002-2009, Sebastian Bergmann . +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of Sebastian Bergmann nor the names of his +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# $Id$ +# + +CREATE TABLE IF NOT EXISTS run( + run_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + timestamp INTEGER UNSIGNED NOT NULL, + revision INTEGER UNSIGNED NOT NULL, + information TEXT NOT NULL, + completed BOOLEAN NOT NULL DEFAULT 0 +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS test( + run_id INTEGER UNSIGNED NOT NULL REFERENCES run.run_id, + test_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + test_name CHAR(128) NOT NULL, + test_result TINYINT UNSIGNED NOT NULL DEFAULT 0, + test_message TEXT NOT NULL DEFAULT "", + test_execution_time FLOAT UNSIGNED NOT NULL DEFAULT 0, + code_method_id INTEGER UNSIGNED REFERENCES code_method.code_method_id, + node_root INTEGER UNSIGNED NOT NULL, + node_left INTEGER UNSIGNED NOT NULL, + node_right INTEGER UNSIGNED NOT NULL, + node_parent INTEGER UNSIGNED NOT NULL, + node_depth TINYINT UNSIGNED NOT NULL, + node_is_leaf BOOLEAN NOT NULL DEFAULT 0, + + INDEX (run_id), + INDEX (test_result), + INDEX (code_method_id), + INDEX (node_root), + INDEX (node_left), + INDEX (node_right), + INDEX (node_parent) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS code_file( + code_file_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + code_file_name CHAR(255), + code_full_file_name CHAR(255), + code_file_md5 CHAR(32), + revision INTEGER UNSIGNED NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS code_function( + code_file_id INTEGER UNSIGNED NOT NULL REFERENCES code_file.code_file_id, + code_function_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + code_function_name CHAR(255), + code_function_start_line INTEGER UNSIGNED NOT NULL, + code_function_end_line INTEGER UNSIGNED NOT NULL, + + INDEX (code_file_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS code_class( + code_file_id INTEGER UNSIGNED NOT NULL REFERENCES code_file.code_file_id, + code_class_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + code_class_parent_id INTEGER UNSIGNED REFERENCES code_class.code_class_id, + code_class_name CHAR(255), + code_class_start_line INTEGER UNSIGNED NOT NULL, + code_class_end_line INTEGER UNSIGNED NOT NULL, + + INDEX (code_file_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS code_method( + code_class_id INTEGER UNSIGNED NOT NULL REFERENCES code_class.code_class_id, + code_method_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + code_method_name CHAR(255), + code_method_start_line INTEGER UNSIGNED NOT NULL, + code_method_end_line INTEGER UNSIGNED NOT NULL, + + INDEX (code_class_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS code_line( + code_file_id INTEGER UNSIGNED NOT NULL REFERENCES code_file.code_file_id, + code_line_id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + code_line_number INTEGER UNSIGNED NOT NULL, + code_line TEXT, + code_line_covered TINYINT NOT NULL, + + INDEX (code_file_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS code_coverage( + test_id INTEGER UNSIGNED NOT NULL REFERENCES test.test_id, + code_line_id INTEGER UNSIGNED NOT NULL REFERENCES code_line.code_line_id, + + PRIMARY KEY (test_id, code_line_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS metrics_project( + run_id INTEGER UNSIGNED NOT NULL, + metrics_project_cls INTEGER UNSIGNED NOT NULL, + metrics_project_clsa INTEGER UNSIGNED NOT NULL, + metrics_project_clsc INTEGER UNSIGNED NOT NULL, + metrics_project_roots INTEGER UNSIGNED NOT NULL, + metrics_project_leafs INTEGER UNSIGNED NOT NULL, + metrics_project_interfs INTEGER UNSIGNED NOT NULL, + metrics_project_maxdit INTEGER UNSIGNED NOT NULL, + + INDEX (run_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS metrics_file( + run_id INTEGER UNSIGNED NOT NULL, + code_file_id INTEGER UNSIGNED NOT NULL REFERENCES code_file.code_file_id, + metrics_file_coverage FLOAT UNSIGNED NOT NULL, + metrics_file_loc INTEGER UNSIGNED NOT NULL, + metrics_file_cloc INTEGER UNSIGNED NOT NULL, + metrics_file_ncloc INTEGER UNSIGNED NOT NULL, + metrics_file_loc_executable INTEGER UNSIGNED NOT NULL, + metrics_file_loc_executed INTEGER UNSIGNED NOT NULL, + + INDEX (run_id), + INDEX (code_file_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS metrics_function( + run_id INTEGER UNSIGNED NOT NULL, + code_function_id INTEGER UNSIGNED NOT NULL REFERENCES code_method.code_function_id, + metrics_function_coverage FLOAT UNSIGNED NOT NULL, + metrics_function_loc INTEGER UNSIGNED NOT NULL, + metrics_function_loc_executable INTEGER UNSIGNED NOT NULL, + metrics_function_loc_executed INTEGER UNSIGNED NOT NULL, + metrics_function_ccn INTEGER UNSIGNED NOT NULL, + metrics_function_crap FLOAT UNSIGNED NOT NULL, + metrics_function_npath INTEGER UNSIGNED NOT NULL, + + INDEX (run_id), + INDEX (code_function_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS metrics_class( + run_id INTEGER UNSIGNED NOT NULL, + code_class_id INTEGER UNSIGNED NOT NULL REFERENCES code_class.code_class_id, + metrics_class_coverage FLOAT UNSIGNED NOT NULL, + metrics_class_loc INTEGER UNSIGNED NOT NULL, + metrics_class_loc_executable INTEGER UNSIGNED NOT NULL, + metrics_class_loc_executed INTEGER UNSIGNED NOT NULL, + metrics_class_aif FLOAT UNSIGNED NOT NULL, + metrics_class_ahf FLOAT UNSIGNED NOT NULL, + metrics_class_cis INTEGER UNSIGNED NOT NULL, + metrics_class_csz INTEGER UNSIGNED NOT NULL, + metrics_class_dit INTEGER UNSIGNED NOT NULL, + metrics_class_impl INTEGER UNSIGNED NOT NULL, + metrics_class_mif FLOAT UNSIGNED NOT NULL, + metrics_class_mhf FLOAT UNSIGNED NOT NULL, + metrics_class_noc INTEGER UNSIGNED NOT NULL, + metrics_class_pf FLOAT UNSIGNED NOT NULL, + metrics_class_vars INTEGER UNSIGNED NOT NULL, + metrics_class_varsnp INTEGER UNSIGNED NOT NULL, + metrics_class_varsi INTEGER UNSIGNED NOT NULL, + metrics_class_wmc INTEGER UNSIGNED NOT NULL, + metrics_class_wmcnp INTEGER UNSIGNED NOT NULL, + metrics_class_wmci INTEGER UNSIGNED NOT NULL, + + INDEX (run_id), + INDEX (code_class_id) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS metrics_method( + run_id INTEGER UNSIGNED NOT NULL, + code_method_id INTEGER UNSIGNED NOT NULL REFERENCES code_method.code_method_id, + metrics_method_coverage FLOAT UNSIGNED NOT NULL, + metrics_method_loc INTEGER UNSIGNED NOT NULL, + metrics_method_loc_executable INTEGER UNSIGNED NOT NULL, + metrics_method_loc_executed INTEGER UNSIGNED NOT NULL, + metrics_method_ccn INTEGER UNSIGNED NOT NULL, + metrics_method_crap FLOAT UNSIGNED NOT NULL, + metrics_method_npath INTEGER UNSIGNED NOT NULL, + + INDEX (run_id), + INDEX (code_method_id) +) ENGINE=InnoDB; diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database/SQLite3.sql b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database/SQLite3.sql new file mode 100644 index 00000000..5c8548f7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Database/SQLite3.sql @@ -0,0 +1,210 @@ +-- +-- PHPUnit +-- +-- Copyright (c) 2002-2009, Sebastian Bergmann . +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- * Neither the name of Sebastian Bergmann nor the names of his +-- contributors may be used to endorse or promote products derived +-- from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- $Id$ +-- + +CREATE TABLE IF NOT EXISTS run( + run_id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp INTEGER, + revision INTEGER, + information STRING, + completed INTEGER DEFAULT 0 +); + +CREATE TABLE IF NOT EXISTS test( + run_id INTEGER, + test_id INTEGER PRIMARY KEY AUTOINCREMENT, + test_name TEXT, + test_result INTEGER DEFAULT 0, + test_message TEXT DEFAULT "", + test_execution_time REAL DEFAULT 0, + code_method_id INTEGER, + node_root INTEGER, + node_left INTEGER, + node_right INTEGER, + node_parent INTEGER, + node_depth INTEGER, + node_is_leaf INTEGER DEFAULT 0 +); + +CREATE INDEX IF NOT EXISTS test_run_id ON test (run_id); +CREATE INDEX IF NOT EXISTS test_result ON test (test_result); +CREATE INDEX IF NOT EXISTS test_code_method_id ON test (code_method_id); +CREATE INDEX IF NOT EXISTS test_node_root ON test (node_root); +CREATE INDEX IF NOT EXISTS test_node_left ON test (node_left); +CREATE INDEX IF NOT EXISTS test_node_right ON test (node_right); +CREATE INDEX IF NOT EXISTS test_node_parent ON test (node_parent); + +CREATE TABLE IF NOT EXISTS code_file( + code_file_id INTEGER PRIMARY KEY AUTOINCREMENT, + code_file_name TEXT, + code_full_file_name TEXT, + code_file_md5 TEXT, + revision INTEGER +); + +CREATE TABLE IF NOT EXISTS code_function( + code_file_id INTEGER, + code_function_id INTEGER PRIMARY KEY AUTOINCREMENT, + code_function_name TEXT, + code_function_start_line INTEGER, + code_function_end_line INTEGER +); + +CREATE INDEX IF NOT EXISTS code_file_id ON code_function (code_file_id); + +CREATE TABLE IF NOT EXISTS code_class( + code_file_id INTEGER, + code_class_id INTEGER PRIMARY KEY AUTOINCREMENT, + code_class_parent_id INTEGER, + code_class_name TEXT, + code_class_start_line INTEGER, + code_class_end_line INTEGER +); + +CREATE INDEX IF NOT EXISTS code_file_id ON code_class (code_file_id); + +CREATE TABLE IF NOT EXISTS code_method( + code_class_id INTEGER, + code_method_id INTEGER PRIMARY KEY AUTOINCREMENT, + code_method_name TEXT, + code_method_start_line INTEGER, + code_method_end_line INTEGER +); + +CREATE INDEX IF NOT EXISTS code_class_id ON code_method (code_class_id); + +CREATE TABLE IF NOT EXISTS code_line( + code_file_id INTEGER, + code_line_id INTEGER PRIMARY KEY AUTOINCREMENT, + code_line_number INTEGER, + code_line TEXT, + code_line_covered INTEGER +); + +CREATE INDEX IF NOT EXISTS code_line_code_file_id ON code_line (code_file_id); + +CREATE TABLE IF NOT EXISTS code_coverage( + test_id INTEGER, + code_line_id INTEGER +); + +CREATE UNIQUE INDEX IF NOT EXISTS code_coverage_test_id_code_line_id ON code_coverage (test_id, code_line_id); + +CREATE TABLE IF NOT EXISTS metrics_project( + run_id INTEGER, + metrics_project_cls INTEGER, + metrics_project_clsa INTEGER, + metrics_project_clsc INTEGER, + metrics_project_roots INTEGER, + metrics_project_leafs INTEGER, + metrics_project_interfs INTEGER, + metrics_project_maxdit INTEGER +); + +CREATE INDEX IF NOT EXISTS run_id ON metrics_project (run_id); + +CREATE TABLE IF NOT EXISTS metrics_file( + run_id INTEGER, + code_file_id INTEGER, + metrics_file_coverage REAL, + metrics_file_loc INTEGER, + metrics_file_cloc INTEGER, + metrics_file_ncloc INTEGER, + metrics_file_loc_executable INTEGER, + metrics_file_loc_executed INTEGER +); + +CREATE INDEX IF NOT EXISTS run_id ON metrics_file (run_id); +CREATE INDEX IF NOT EXISTS code_file_id ON metrics_file (code_file_id); + +CREATE TABLE IF NOT EXISTS metrics_function( + run_id INTEGER, + code_function_id INTEGER, + metrics_function_coverage REAL, + metrics_function_loc INTEGER, + metrics_function_loc_executable INTEGER, + metrics_function_loc_executed INTEGER, + metrics_function_ccn INTEGER, + metrics_function_crap REAL, + metrics_function_npath INTEGER +); + +CREATE INDEX IF NOT EXISTS run_id ON metrics_function (run_id); +CREATE INDEX IF NOT EXISTS code_function_id ON metrics_function (code_function_id); + +CREATE TABLE IF NOT EXISTS metrics_class( + run_id INTEGER, + code_class_id INTEGER, + metrics_class_coverage REAL, + metrics_class_loc INTEGER, + metrics_class_loc_executable INTEGER, + metrics_class_loc_executed INTEGER, + metrics_class_aif REAL, + metrics_class_ahf REAL, + metrics_class_cis INTEGER, + metrics_class_csz INTEGER, + metrics_class_dit INTEGER, + metrics_class_impl INTEGER, + metrics_class_mif REAL, + metrics_class_mhf REAL, + metrics_class_noc INTEGER, + metrics_class_pf REAL, + metrics_class_vars INTEGER, + metrics_class_varsnp INTEGER, + metrics_class_varsi INTEGER, + metrics_class_wmc INTEGER, + metrics_class_wmcnp INTEGER, + metrics_class_wmci INTEGER +); + +CREATE INDEX IF NOT EXISTS run_id ON metrics_class (run_id); +CREATE INDEX IF NOT EXISTS code_class_id ON metrics_class (code_class_id); + +CREATE TABLE IF NOT EXISTS metrics_method( + run_id INTEGER, + code_method_id INTEGER, + metrics_method_coverage REAL, + metrics_method_loc INTEGER, + metrics_method_loc_executable INTEGER, + metrics_method_loc_executed INTEGER, + metrics_method_ccn INTEGER, + metrics_method_crap REAL, + metrics_method_npath INTEGER +); + +CREATE INDEX IF NOT EXISTS run_id ON metrics_method (run_id); +CREATE INDEX IF NOT EXISTS code_method_id ON metrics_method (code_method_id); diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/GraphViz.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/GraphViz.php new file mode 100644 index 00000000..98c7946d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/GraphViz.php @@ -0,0 +1,300 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/Test.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestListener that generates maps of the executed tests + * in GraphViz markup. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Log_GraphViz extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var Image_GraphViz + */ + protected $graph; + + /** + * @var boolean + */ + protected $currentTestSuccess = TRUE; + + /** + * @var string[] + */ + protected $testSuites = array(); + + /** + * @var integer + */ + protected $testSuiteLevel = 0; + + /** + * @var integer[] + */ + protected $testSuiteFailureOrErrorCount = array(0); + + /** + * @var integer[] + */ + protected $testSuiteIncompleteOrSkippedCount = array(0); + + /** + * Constructor. + * + * @param mixed $out + */ + public function __construct($out = NULL) + { + if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Image/GraphViz.php')) { + PHPUnit_Util_Filesystem::collectStart(); + require_once 'Image/GraphViz.php'; + + $this->graph = new Image_GraphViz( + TRUE, + array( + 'overlap' => 'scale', + 'splines' => 'true', + 'sep' => '.1', + 'fontsize' => '8' + ) + ); + + parent::__construct($out); + + foreach (PHPUnit_Util_Filesystem::collectEnd() as $blacklistedFile) { + PHPUnit_Util_Filter::addFileToFilter($blacklistedFile, 'PHPUNIT'); + } + } else { + throw new RuntimeException('Image_GraphViz is not available.'); + } + } + + /** + * Flush buffer and close output. + * + */ + public function flush() + { + $this->write($this->graph->parse()); + + parent::flush(); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->addTestNode($test, 'red'); + $this->testSuiteFailureOrErrorCount[$this->testSuiteLevel]++; + + $this->currentTestSuccess = FALSE; + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->addTestNode($test, 'red'); + $this->testSuiteFailureOrErrorCount[$this->testSuiteLevel]++; + + $this->currentTestSuccess = FALSE; + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->addTestNode($test, 'yellow'); + $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel]++; + + $this->currentTestSuccess = FALSE; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->addTestNode($test, 'yellow'); + $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel]++; + + $this->currentTestSuccess = FALSE; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->graph->addNode($suite->getName()); + + if ($this->testSuiteLevel > 0) { + $this->graph->addEdge( + array( + $this->testSuites[$this->testSuiteLevel] => $suite->getName() + ) + ); + } + + $this->testSuiteLevel++; + $this->testSuites[$this->testSuiteLevel] = $suite->getName(); + $this->testSuiteFailureOrErrorCount[$this->testSuiteLevel] = 0; + $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel] = 0; + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $color = 'red'; + + if ($this->testSuiteFailureOrErrorCount[$this->testSuiteLevel] == 0 && + $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel] == 0) { + $color = 'green'; + } + + else if ($this->testSuiteFailureOrErrorCount[$this->testSuiteLevel] == 0 && + $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel] > 0) { + $color = 'yellow'; + } + + $this->graph->addNode( + $this->testSuites[$this->testSuiteLevel], + array('color' => $color) + ); + + if ($this->testSuiteLevel > 1) { + $this->testSuiteFailureOrErrorCount[$this->testSuiteLevel - 1] += $this->testSuiteFailureOrErrorCount[$this->testSuiteLevel]; + $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel - 1] += $this->testSuiteIncompleteOrSkippedCount[$this->testSuiteLevel]; + } + + $this->testSuiteLevel--; + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->currentTestSuccess = TRUE; + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($this->currentTestSuccess) { + $this->addTestNode($test, 'green'); + } + } + + /** + * @param PHPUnit_Framework_Test $test + * @param string $color + */ + protected function addTestNode(PHPUnit_Framework_Test $test, $color) + { + $name = PHPUnit_Util_Test::describe($test, FALSE); + + $this->graph->addNode( + $name[1], + array('color' => $color), + $this->testSuites[$this->testSuiteLevel] + ); + + $this->graph->addEdge( + array( + $this->testSuites[$this->testSuiteLevel] => $name[1] + ) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/JSON.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/JSON.php new file mode 100644 index 00000000..7aba84f5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/JSON.php @@ -0,0 +1,281 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/Test.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestListener that generates JSON messages. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Log_JSON extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var string + */ + protected $currentTestSuiteName = ''; + + /** + * @var string + */ + protected $currentTestName = ''; + + /** + * @var boolean + * @access private + */ + protected $currentTestPass = TRUE; + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase( + 'error', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace( + $e, + TRUE, + FALSE + ), + $e->getMessage() + ); + + $this->currentTestPass = FALSE; + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->writeCase( + 'fail', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace( + $e, + TRUE, + FALSE + ), + $e->getMessage() + ); + + $this->currentTestPass = FALSE; + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase('error', $time, array(), 'Incomplete Test'); + + $this->currentTestPass = FALSE; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase('error', $time, array(), 'Skipped Test'); + + $this->currentTestPass = FALSE; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->currentTestSuiteName = $suite->getName(); + $this->currentTestName = ''; + + $message = array( + 'event' => 'suiteStart', + 'suite' => $this->currentTestSuiteName, + 'tests' => count($suite) + ); + + $this->write($this->encode($message)); + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->currentTestSuiteName = ''; + $this->currentTestName = ''; + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->currentTestName = PHPUnit_Util_Test::describe($test); + $this->currentTestPass = TRUE; + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($this->currentTestPass) { + $this->writeCase('pass', $time); + } + } + + /** + * @param string $status + * @param float $time + * @param array $trace + * @param string $message + */ + protected function writeCase($status, $time, array $trace = array(), $message = '') + { + $message = array( + 'event' => 'test', + 'suite' => $this->currentTestSuiteName, + 'test' => $this->currentTestName, + 'status' => $status, + 'time' => $time, + 'trace' => $trace, + 'message' => $message + ); + + $this->write($this->encode($message)); + } + + /** + * @param array $message + * @return string + */ + protected function encode($message) + { + if (function_exists('json_encode')) { + return json_encode($message); + } + + $first = TRUE; + $result = ''; + + if (is_scalar($message)) { + $message = array ($message); + } + + foreach ($message as $key => $value) { + if (!$first) { + $result .= ','; + } else { + $first = FALSE; + } + + $result .= sprintf('"%s":', $this->escape($key)); + + if (is_array($value) || is_object($value)) { + $result .= sprintf('%s', $this->encode($value)); + } else { + $result .= sprintf('"%s"', $this->escape($value)); + } + } + + return '{' . $result . '}'; + } + + /** + * @param string $value + * @return string + */ + protected function escape($value) + { + return str_replace( + array("\\", "\"", "/", "\b", "\f", "\n", "\r", "\t"), + array('\\\\', '\"', '\/', '\b', '\f', '\n', '\r', '\t'), + $value + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/JUnit.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/JUnit.php new file mode 100644 index 00000000..2c6f7334 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/JUnit.php @@ -0,0 +1,494 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/XML.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestListener that generates a logfile of the test execution in XML markup. + * + * The XML markup used is the same as the one that is used by the JUnit Ant task. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_Log_JUnit extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var DOMDocument + */ + protected $document; + + /** + * @var DOMElement + */ + protected $root; + + /** + * @var boolean + */ + protected $logIncompleteSkipped = FALSE; + + /** + * @var boolean + */ + protected $writeDocument = TRUE; + + /** + * @var DOMElement[] + */ + protected $testSuites = array(); + + /** + * @var integer[] + */ + protected $testSuiteTests = array(0); + + /** + * @var integer[] + */ + protected $testSuiteAssertions = array(0); + + /** + * @var integer[] + */ + protected $testSuiteErrors = array(0); + + /** + * @var integer[] + */ + protected $testSuiteFailures = array(0); + + /** + * @var integer[] + */ + protected $testSuiteTimes = array(0); + + /** + * @var integer + */ + protected $testSuiteLevel = 0; + + /** + * @var DOMElement + */ + protected $currentTestCase = NULL; + + /** + * @var boolean + */ + protected $attachCurrentTestCase = TRUE; + + /** + * Constructor. + * + * @param mixed $out + * @param boolean $logIncompleteSkipped + */ + public function __construct($out = NULL, $logIncompleteSkipped = FALSE) + { + $this->document = new DOMDocument('1.0', 'UTF-8'); + $this->document->formatOutput = TRUE; + + $this->root = $this->document->createElement('testsuites'); + $this->document->appendChild($this->root); + + parent::__construct($out); + + $this->logIncompleteSkipped = $logIncompleteSkipped; + } + + /** + * Flush buffer and close output. + * + */ + public function flush() + { + if ($this->writeDocument === TRUE) { + $this->write($this->getXML()); + } + + parent::flush(); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->currentTestCase !== NULL) { + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + $buffer = $test->toString() . "\n"; + } else { + $buffer = ''; + } + + $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . + "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE); + + $error = $this->document->createElement( + 'error', PHPUnit_Util_XML::prepareString($buffer) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + if ($this->currentTestCase !== NULL) { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + $buffer = $test->toString() . "\n"; + } else { + $buffer = ''; + } + + $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e). + "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace( + $e, FALSE + ); + + $failure = $this->document->createElement( + 'failure', PHPUnit_Util_XML::prepareString($buffer) + ); + + $failure->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($failure); + + $this->testSuiteFailures[$this->testSuiteLevel]++; + } + } + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->logIncompleteSkipped && $this->currentTestCase !== NULL) { + $error = $this->document->createElement( + 'error', + PHPUnit_Util_XML::prepareString( + "Incomplete Test\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE) + ) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } else { + $this->attachCurrentTestCase = FALSE; + } + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->logIncompleteSkipped && $this->currentTestCase !== NULL) { + $error = $this->document->createElement( + 'error', + PHPUnit_Util_XML::prepareString( + "Skipped Test\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE) + ) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } else { + $this->attachCurrentTestCase = FALSE; + } + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $testSuite = $this->document->createElement('testsuite'); + $testSuite->setAttribute('name', $suite->getName()); + + if (class_exists($suite->getName(), FALSE)) { + try { + $class = new ReflectionClass($suite->getName()); + + $testSuite->setAttribute('file', $class->getFileName()); + + $packageInformation = PHPUnit_Util_Class::getPackageInformation( + $suite->getName(), $class->getDocComment() + ); + + if (!empty($packageInformation['namespace'])) { + $testSuite->setAttribute( + 'namespace', $packageInformation['namespace'] + ); + } + + if (!empty($packageInformation['fullPackage'])) { + $testSuite->setAttribute( + 'fullPackage', $packageInformation['fullPackage'] + ); + } + + if (!empty($packageInformation['category'])) { + $testSuite->setAttribute( + 'category', $packageInformation['category'] + ); + } + + if (!empty($packageInformation['package'])) { + $testSuite->setAttribute( + 'package', $packageInformation['package'] + ); + } + + if (!empty($packageInformation['subpackage'])) { + $testSuite->setAttribute( + 'subpackage', $packageInformation['subpackage'] + ); + } + } + + catch (ReflectionException $e) { + } + } + + if ($this->testSuiteLevel > 0) { + $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite); + } else { + $this->root->appendChild($testSuite); + } + + $this->testSuiteLevel++; + $this->testSuites[$this->testSuiteLevel] = $testSuite; + $this->testSuiteTests[$this->testSuiteLevel] = 0; + $this->testSuiteAssertions[$this->testSuiteLevel] = 0; + $this->testSuiteErrors[$this->testSuiteLevel] = 0; + $this->testSuiteFailures[$this->testSuiteLevel] = 0; + $this->testSuiteTimes[$this->testSuiteLevel] = 0; + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'tests', $this->testSuiteTests[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'assertions', $this->testSuiteAssertions[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'failures', $this->testSuiteFailures[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'errors', $this->testSuiteErrors[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'time', sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel]) + ); + + if ($this->testSuiteLevel > 1) { + $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel]; + $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel]; + $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel]; + $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel]; + $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel]; + } + + $this->testSuiteLevel--; + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + $testCase = $this->document->createElement('testcase'); + $testCase->setAttribute('name', $test->getName()); + + if ($test instanceof PHPUnit_Framework_TestCase) { + $class = new ReflectionClass($test); + $methodName = $test->getName(); + + if ($class->hasMethod($methodName)) { + $method = $class->getMethod($test->getName()); + + $testCase->setAttribute('class', $class->getName()); + $testCase->setAttribute('file', $class->getFileName()); + $testCase->setAttribute('line', $method->getStartLine()); + } + } + + $this->currentTestCase = $testCase; + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($this->attachCurrentTestCase) { + if ($test instanceof PHPUnit_Framework_TestCase) { + $numAssertions = $test->getNumAssertions(); + $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions; + + $this->currentTestCase->setAttribute( + 'assertions', $numAssertions + ); + } + + $this->currentTestCase->setAttribute( + 'time', sprintf('%F', $time) + ); + + $this->testSuites[$this->testSuiteLevel]->appendChild( + $this->currentTestCase + ); + + $this->testSuiteTests[$this->testSuiteLevel]++; + $this->testSuiteTimes[$this->testSuiteLevel] += $time; + } + } + + $this->attachCurrentTestCase = TRUE; + $this->currentTestCase = NULL; + } + + /** + * Returns the XML as a string. + * + * @return string + * @since Method available since Release 2.2.0 + */ + public function getXML() + { + return $this->document->saveXML(); + } + + /** + * Enables or disables the writing of the document + * in flush(). + * + * This is a "hack" needed for the integration of + * PHPUnit with Phing. + * + * @return string + * @since Method available since Release 2.2.0 + */ + public function setWriteDocument($flag) + { + if (is_bool($flag)) { + $this->writeDocument = $flag; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Metrics.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Metrics.php new file mode 100644 index 00000000..8e4bec3c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/Metrics.php @@ -0,0 +1,181 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Runner/Version.php'; +require_once 'PHPUnit/Util/Metrics/Project.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generates an XML logfile with software metrics information. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_Metrics extends PHPUnit_Util_Printer +{ + /** + * @param PHPUnit_Framework_TestResult $result + */ + public function process(PHPUnit_Framework_TestResult $result) + { + $codeCoverage = $result->getCodeCoverageInformation(); + $summary = PHPUnit_Util_CodeCoverage::getSummary($codeCoverage); + $files = array_keys($summary); + $projectMetrics = new PHPUnit_Util_Metrics_Project($files, $summary); + + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = TRUE; + + $metrics = $document->createElement('metrics'); + $metrics->setAttribute('files', count($projectMetrics->getFiles())); + $metrics->setAttribute('functions', count($projectMetrics->getFunctions())); + $metrics->setAttribute('cls', $projectMetrics->getCLS()); + $metrics->setAttribute('clsa', $projectMetrics->getCLSa()); + $metrics->setAttribute('clsc', $projectMetrics->getCLSc()); + $metrics->setAttribute('roots', $projectMetrics->getRoots()); + $metrics->setAttribute('leafs', $projectMetrics->getLeafs()); + $metrics->setAttribute('interfs', $projectMetrics->getInterfs()); + $metrics->setAttribute('maxdit', $projectMetrics->getMaxDit()); + + $document->appendChild($metrics); + + foreach ($projectMetrics->getFiles() as $fileName => $fileMetrics) { + $xmlFile = $metrics->appendChild( + $document->createElement('file') + ); + + $xmlFile->setAttribute('name', $fileName); + $xmlFile->setAttribute('classes', count($fileMetrics->getClasses())); + $xmlFile->setAttribute('functions', count($fileMetrics->getFunctions())); + $xmlFile->setAttribute('loc', $fileMetrics->getLoc()); + $xmlFile->setAttribute('cloc', $fileMetrics->getCloc()); + $xmlFile->setAttribute('ncloc', $fileMetrics->getNcloc()); + $xmlFile->setAttribute('locExecutable', $fileMetrics->getLocExecutable()); + $xmlFile->setAttribute('locExecuted', $fileMetrics->getLocExecuted()); + $xmlFile->setAttribute('coverage', sprintf('%F', $fileMetrics->getCoverage())); + + foreach ($fileMetrics->getClasses() as $className => $classMetrics) { + if (!$classMetrics->getClass()->implementsInterface('PHPUnit_Framework_Test')) { + $xmlClass = $document->createElement('class'); + + $xmlClass->setAttribute('name', $classMetrics->getClass()->getName()); + $xmlClass->setAttribute('loc', $classMetrics->getLoc()); + $xmlClass->setAttribute('locExecutable', $classMetrics->getLocExecutable()); + $xmlClass->setAttribute('locExecuted', $classMetrics->getLocExecuted()); + $xmlClass->setAttribute('aif', sprintf('%F', $classMetrics->getAIF())); + $xmlClass->setAttribute('ahf', sprintf('%F', $classMetrics->getAHF())); + $xmlClass->setAttribute('ca', $classMetrics->getCa()); + $xmlClass->setAttribute('ce', $classMetrics->getCe()); + $xmlClass->setAttribute('csz', $classMetrics->getCSZ()); + $xmlClass->setAttribute('cis', $classMetrics->getCIS()); + $xmlClass->setAttribute('coverage', sprintf('%F', $classMetrics->getCoverage())); + $xmlClass->setAttribute('dit', $classMetrics->getDIT()); + $xmlClass->setAttribute('i', sprintf('%F', $classMetrics->getI())); + $xmlClass->setAttribute('impl', $classMetrics->getIMPL()); + $xmlClass->setAttribute('mif', sprintf('%F', $classMetrics->getMIF())); + $xmlClass->setAttribute('mhf', sprintf('%F', $classMetrics->getMHF())); + $xmlClass->setAttribute('noc', $classMetrics->getNOC()); + $xmlClass->setAttribute('pf', sprintf('%F', $classMetrics->getPF())); + $xmlClass->setAttribute('vars', $classMetrics->getVARS()); + $xmlClass->setAttribute('varsnp', $classMetrics->getVARSnp()); + $xmlClass->setAttribute('varsi', $classMetrics->getVARSi()); + $xmlClass->setAttribute('wmc', $classMetrics->getWMC()); + $xmlClass->setAttribute('wmcnp', $classMetrics->getWMCnp()); + $xmlClass->setAttribute('wmci', $classMetrics->getWMCi()); + + foreach ($classMetrics->getMethods() as $methodName => $methodMetrics) { + $xmlMethod = $xmlClass->appendChild( + $document->createElement('method') + ); + + $this->processFunctionOrMethod($methodMetrics, $xmlMethod); + } + + $xmlFile->appendChild($xmlClass); + } + } + + foreach ($fileMetrics->getFunctions() as $functionName => $functionMetrics) { + $xmlFunction = $xmlFile->appendChild( + $document->createElement('function') + ); + + $this->processFunctionOrMethod($functionMetrics, $xmlFunction); + } + } + + $this->write($document->saveXML()); + $this->flush(); + } + + /** + * @param PHPUnit_Util_Metrics_Function $metrics + * @param DOMElement $element + */ + protected function processFunctionOrMethod($metrics, DOMElement $element) + { + $element->setAttribute('name', $metrics->getFunction()->getName()); + $element->setAttribute('loc', $metrics->getLoc()); + $element->setAttribute('locExecutable', $metrics->getLocExecutable()); + $element->setAttribute('locExecuted', $metrics->getLocExecuted()); + $element->setAttribute('coverage', sprintf('%F', $metrics->getCoverage())); + $element->setAttribute('ccn', $metrics->getCCN()); + $element->setAttribute('crap', sprintf('%F', $metrics->getCrapIndex())); + $element->setAttribute('npath', $metrics->getNPath()); + $element->setAttribute('parameters', $metrics->getParameters()); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PEAR.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PEAR.php new file mode 100644 index 00000000..bb5006f7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PEAR.php @@ -0,0 +1,244 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestListener that logs to a PEAR_Log sink. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_Log_PEAR implements PHPUnit_Framework_TestListener +{ + /** + * Log. + * + * @var Log + */ + protected $log; + + /** + * @param string $type The type of concrete Log subclass to use. + * Currently, valid values are 'console', + * 'syslog', 'sql', 'file', and 'mcal'. + * @param string $name The name of the actually log file, table, or + * other specific store to use. Defaults to an + * empty string, with which the subclass will + * attempt to do something intelligent. + * @param string $ident The identity reported to the log system. + * @param array $conf A hash containing any additional configuration + * information that a subclass might need. + * @param int $maxLevel Maximum priority level at which to log. + */ + public function __construct($type, $name = '', $ident = '', $conf = array(), $maxLevel = PEAR_LOG_DEBUG) + { + if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Log.php')) { + PHPUnit_Util_Filesystem::collectStart(); + require_once 'Log.php'; + $this->log = Log::factory($type, $name, $ident, $conf, $maxLevel); + + foreach (PHPUnit_Util_Filesystem::collectEnd() as $blacklistedFile) { + PHPUnit_Util_Filter::addFileToFilter($blacklistedFile, 'PHPUNIT'); + } + } else { + throw new RuntimeException('Log is not available.'); + } + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->log->crit( + sprintf( + 'Test "%s" failed: %s', + + $test->getName(), + $e->getMessage() + ) + ); + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->log->err( + sprintf( + 'Test "%s" failed: %s', + + $test->getName(), + $e->getMessage() + ) + ); + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->log->info( + sprintf( + 'Test "%s" incomplete: %s', + + $test->getName(), + $e->getMessage() + ) + ); + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->log->info( + sprintf( + 'Test "%s" skipped: %s', + + $test->getName(), + $e->getMessage() + ) + ); + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->log->info( + sprintf( + 'TestSuite "%s" started.', + + $suite->getName() + ) + ); + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->log->info( + sprintf( + 'TestSuite "%s" ended.', + + $suite->getName() + ) + ); + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->log->info( + sprintf( + 'Test "%s" started.', + + $test->getName() + ) + ); + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + $this->log->info( + sprintf( + 'Test "%s" ended.', + + $test->getName() + ) + ); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD.php new file mode 100644 index 00000000..0f5bfdda --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD.php @@ -0,0 +1,336 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Runner/Version.php'; +require_once 'PHPUnit/Util/Metrics/Project.php'; +require_once 'PHPUnit/Util/Log/PMD/Rule/Class.php'; +require_once 'PHPUnit/Util/Log/PMD/Rule/File.php'; +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Log/PMD/Rule/Project.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/FilterIterator.php'; +require_once 'PHPUnit/Util/Printer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generates an XML logfile with software metrics information using the + * PMD format "documented" at + * http://svn.atlassian.com/fisheye/browse/~raw,r=7084/public/contrib/bamboo/bamboo-pmd-plugin/trunk/src/test/resources/test-pmd-report.xml + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD extends PHPUnit_Util_Printer +{ + protected $added; + + protected $rules = array( + 'project' => array(), + 'file' => array(), + 'class' => array(), + 'function' => array() + ); + + /** + * Constructor. + * + * @param mixed $out + * @param array $configuration + * @throws InvalidArgumentException + */ + public function __construct($out = NULL, array $configuration = array()) + { + parent::__construct($out); + $this->loadClasses($configuration); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + public function process(PHPUnit_Framework_TestResult $result) + { + $codeCoverage = $result->getCodeCoverageInformation(); + $summary = PHPUnit_Util_CodeCoverage::getSummary($codeCoverage); + $files = array_keys($summary); + $metrics = new PHPUnit_Util_Metrics_Project($files, $summary); + + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = TRUE; + + $pmd = $document->createElement('pmd'); + $pmd->setAttribute('version', 'PHPUnit ' . PHPUnit_Runner_Version::id()); + $document->appendChild($pmd); + + foreach ($this->rules['project'] as $ruleName => $rule) { + $result = $rule->apply($metrics); + + if ($result !== NULL) { + $this->addViolation( + $result, + $pmd, + $rule + ); + } + } + + foreach ($metrics->getFiles() as $fileName => $fileMetrics) { + $xmlFile = $document->createElement('file'); + $xmlFile->setAttribute('name', $fileName); + + $this->added = FALSE; + + foreach ($this->rules['file'] as $ruleName => $rule) { + $result = $rule->apply($fileMetrics); + + if ($result !== NULL) { + $this->addViolation( + $result, + $xmlFile, + $rule + ); + + $this->added = TRUE; + } + } + + foreach ($fileMetrics->getClasses() as $className => $classMetrics) { + if (!$classMetrics->getClass()->isInterface()) { + $classStartLine = $classMetrics->getClass()->getStartLine(); + $classEndLine = $classMetrics->getClass()->getEndLine(); + $classPackage = $classMetrics->getPackage(); + + foreach ($this->rules['class'] as $ruleName => $rule) { + $result = $rule->apply($classMetrics); + + if ($result !== NULL) { + $this->addViolation( + $result, + $xmlFile, + $rule, + $classStartLine, + $classEndLine, + $classPackage, + $className + ); + + $this->added = TRUE; + } + } + + foreach ($classMetrics->getMethods() as $methodName => $methodMetrics) { + if (!$methodMetrics->getMethod()->isAbstract()) { + $this->processFunctionOrMethod($xmlFile, $methodMetrics, $classPackage); + } + } + } + } + + foreach ($fileMetrics->getFunctions() as $functionName => $functionMetrics) { + $this->processFunctionOrMethod($xmlFile, $functionMetrics); + } + + if ($this->added) { + $pmd->appendChild($xmlFile); + } + } + + $this->write($document->saveXML()); + $this->flush(); + } + + /** + * @param string $violation + * @param DOMElement $element + * @param PHPUnit_Util_Log_PMD_Rule $rule + * @param integer $line + * @param integer $toLine + * @param string $package + * @param string $class + * @param string $method + */ + protected function addViolation($violation, DOMElement $element, PHPUnit_Util_Log_PMD_Rule $rule, $line = '', $toLine = '', $package = '', $class = '', $method = '', $function = '') + { + $violationXml = $element->appendChild( + $element->ownerDocument->createElement('violation', $violation) + ); + + $violationXml->setAttribute('rule', $rule->getName()); + $violationXml->setAttribute('priority', $rule->getPriority()); + + if (!empty($line)) { + $violationXml->setAttribute('line', $line); + } + + if (!empty($toLine)) { + $violationXml->setAttribute('to-line', $toLine); + } + + if (empty($package)) { + $package = 'global'; + } + + if (!empty($package)) { + $violationXml->setAttribute('package', $package); + } + + if (!empty($class)) { + $violationXml->setAttribute('class', $class); + } + + if (!empty($method)) { + $violationXml->setAttribute('method', $method); + } + + if (!empty($function)) { + $violationXml->setAttribute('function', $function); + } + } + + protected function processFunctionOrMethod(DOMElement $element, $metrics, $package = '') + { + $scope = ''; + + if ($metrics->getFunction() instanceof ReflectionMethod) { + $scope = $metrics->getFunction()->getDeclaringClass()->getName(); + } + + $startLine = $metrics->getFunction()->getStartLine(); + $endLine = $metrics->getFunction()->getEndLine(); + $name = $metrics->getFunction()->getName(); + + foreach ($this->rules['function'] as $ruleName => $rule) { + $result = $rule->apply($metrics); + + if ($result !== NULL) { + $this->addViolation( + $result, + $element, + $rule, + $startLine, + $endLine, + $package, + $scope, + $name + ); + + $this->added = TRUE; + } + } + } + + protected function loadClasses(array $configuration) + { + $basedir = dirname(__FILE__) . DIRECTORY_SEPARATOR . + 'PMD' . DIRECTORY_SEPARATOR . 'Rule'; + + $dirs = array( + $basedir . DIRECTORY_SEPARATOR . 'Class', + $basedir . DIRECTORY_SEPARATOR . 'File', + $basedir . DIRECTORY_SEPARATOR . 'Function', + $basedir . DIRECTORY_SEPARATOR . 'Project' + ); + + foreach ($dirs as $dir) { + if (file_exists($dir)) { + $iterator = new PHPUnit_Util_FilterIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($dir) + ), + '.php' + ); + + foreach ($iterator as $file) { + include_once $file->getPathname(); + } + } + } + + $classes = get_declared_classes(); + + foreach ($classes as $className) { + $class = new ReflectionClass($className); + + if (!$class->isAbstract() && $class->isSubclassOf('PHPUnit_Util_Log_PMD_Rule')) { + $rule = explode('_', $className); + $rule = $rule[count($rule)-1]; + + if (isset($configuration[$className])) { + $object = new $className( + $configuration[$className]['threshold'], + $configuration[$className]['priority'] + ); + } else { + $object = new $className; + } + + if ($class->isSubclassOf('PHPUnit_Util_Log_PMD_Rule_Project')) { + $this->rules['project'][$rule] = $object; + } + + if ($class->isSubclassOf('PHPUnit_Util_Log_PMD_Rule_File')) { + $this->rules['file'][$rule] = $object; + } + + else if ($class->isSubclassOf('PHPUnit_Util_Log_PMD_Rule_Class')) { + $this->rules['class'][$rule] = $object; + } + + else if ($class->isSubclassOf('PHPUnit_Util_Log_PMD_Rule_Function')) { + $this->rules['function'][$rule] = $object; + } + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule.php new file mode 100644 index 00000000..544d0559 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule.php @@ -0,0 +1,88 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Metrics.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for PMD rule classes. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Log_PMD_Rule +{ + protected $threshold; + protected $priority; + + public function __construct($threshold, $priority = 1) + { + $this->threshold = $threshold; + $this->priority = $priority; + } + + public function getName() + { + $name = explode('_', get_class($this)); + + return array_pop($name); + } + + public function getPriority() + { + return $this->priority; + } + + abstract public function apply(PHPUnit_Util_Metrics $metrics); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class.php new file mode 100644 index 00000000..f9228ef8 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for PMD rule classes that operate on the class-level. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Log_PMD_Rule_Class extends PHPUnit_Util_Log_PMD_Rule +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/DepthOfInheritanceTree.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/DepthOfInheritanceTree.php new file mode 100644 index 00000000..17a69102 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/DepthOfInheritanceTree.php @@ -0,0 +1,82 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Class_DepthOfInheritanceTree extends PHPUnit_Util_Log_PMD_Rule_Class +{ + public function __construct($threshold = 6, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $dit = $metrics->getDIT(); + + if ($dit > $this->threshold) { + return sprintf( + 'Depth of Inheritance Tree (DIT) is %d.', + $dit + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/EfferentCoupling.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/EfferentCoupling.php new file mode 100644 index 00000000..2676dbb5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/EfferentCoupling.php @@ -0,0 +1,85 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Class_EfferentCoupling extends PHPUnit_Util_Log_PMD_Rule_Class +{ + public function __construct($threshold = 20, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $ce = $metrics->getCe(); + + if ($ce > $this->threshold) { + return sprintf( + "Class depends on %d other classes.\n" . + 'The number of other classes that the class ' . + 'depends upon is an indicator of the class\' ' . + 'independence.', + $ce + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/ExcessiveClassLength.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/ExcessiveClassLength.php new file mode 100644 index 00000000..c80f9b30 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/ExcessiveClassLength.php @@ -0,0 +1,85 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Class_ExcessiveClassLength extends PHPUnit_Util_Log_PMD_Rule_Class +{ + public function __construct($threshold = 1000, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $locExecutable = $metrics->getLocExecutable(); + + if ($locExecutable > $this->threshold) { + return sprintf( + "Class has %d lines of executable code.\n" . + 'This is an indication that the class may be ' . + 'trying to do too much. Try to break it down, ' . + 'and reduce the size to something manageable.', + $locExecutable + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/ExcessivePublicCount.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/ExcessivePublicCount.php new file mode 100644 index 00000000..f1f23289 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/ExcessivePublicCount.php @@ -0,0 +1,86 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Class_ExcessivePublicCount extends PHPUnit_Util_Log_PMD_Rule_Class +{ + public function __construct($threshold = 45, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $publicMethods = $metrics->getPublicMethods(); + + if ($publicMethods > $this->threshold) { + return sprintf( + "Class has %d public methods.\n" . + 'A large number of public methods and attributes ' . + 'declared in a class can indicate the class may need ' . + 'to be broken up as increased effort will be required ' . + 'to thoroughly test it.', + $publicMethods + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/TooManyFields.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/TooManyFields.php new file mode 100644 index 00000000..1b253fb4 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Class/TooManyFields.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Class_TooManyFields extends PHPUnit_Util_Log_PMD_Rule_Class +{ + public function __construct($threshold = 15, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $varsNp = $metrics->getVARSnp(); + + if ($varsNp > $this->threshold) { + return sprintf( + "Class has %d public fields.\n" . + 'Classes that have too many fields could be redesigned ' . + 'to have fewer fields, possibly through some nested ' . + 'object grouping of some of the information. For ' . + 'example, a class with city/state/zip fields could ' . + 'instead have one Address field.', + $varsNp + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/File.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/File.php new file mode 100644 index 00000000..464c5314 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/File.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for PMD rule classes that operate on the file-level. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Log_PMD_Rule_File extends PHPUnit_Util_Log_PMD_Rule +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function.php new file mode 100644 index 00000000..541831cd --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function.php @@ -0,0 +1,67 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for PMD rule classes that operate on the function- or + * method-level. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Log_PMD_Rule_Function extends PHPUnit_Util_Log_PMD_Rule +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CRAP.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CRAP.php new file mode 100644 index 00000000..4cf4e50f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CRAP.php @@ -0,0 +1,87 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Function_CRAP extends PHPUnit_Util_Log_PMD_Rule_Function +{ + public function __construct($threshold = 30, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $crap = $metrics->getCrapIndex(); + + if ($crap >= $this->threshold) { + return sprintf( + "The CRAP index is %d.\n" . + 'The Change Risk Analysis and Predictions (CRAP) index of a ' . + 'function or method uses cyclomatic complexity and code coverage ' . + 'from automated tests to help estimate the effort and risk ' . + 'associated with maintaining legacy code. A CRAP index over 30 ' . + 'is a good indicator of crappy code.', + $crap + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CodeCoverage.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CodeCoverage.php new file mode 100644 index 00000000..dc0211ea --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CodeCoverage.php @@ -0,0 +1,90 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Function_CodeCoverage extends PHPUnit_Util_Log_PMD_Rule_Function +{ + public function __construct($threshold = array(35, 70), $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $coverage = $metrics->getCoverage(); + + if ($coverage <= $this->threshold[0]) { + $violation = 'The code coverage is %01.2F which is considered low.'; + } + + else if ($coverage > $this->threshold[0] && $coverage < $this->threshold[1]) { + $violation = 'The code coverage is %01.2F which is considered medium.'; + } + + if (isset($violation)) { + return sprintf( + $violation, + $coverage + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CyclomaticComplexity.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CyclomaticComplexity.php new file mode 100644 index 00000000..b79fee81 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/CyclomaticComplexity.php @@ -0,0 +1,88 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Function_CyclomaticComplexity extends PHPUnit_Util_Log_PMD_Rule_Function +{ + public function __construct($threshold = 20, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $ccn = $metrics->getCCN(); + + if ($ccn >= $this->threshold) { + return sprintf( + "The cyclomatic complexity is %d.\n" . + 'Complexity is determined by the number of decision points in a ' . + 'function or method plus one for the function or method entry. ' . + 'The decision points are "if", "for", "foreach", "while", "case", ' . + '"catch", "&&", "||", and "?:". Generally, 1-4 is low ' . + 'complexity, 5-7 indicates moderate complexity, 8-10 is high ' . + 'complexity, and 11+ is very high complexity.', + $ccn + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/ExcessiveMethodLength.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/ExcessiveMethodLength.php new file mode 100644 index 00000000..2bdb7ffa --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/ExcessiveMethodLength.php @@ -0,0 +1,85 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Function_ExcessiveMethodLength extends PHPUnit_Util_Log_PMD_Rule_Function +{ + public function __construct($threshold = 100, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $locExecutable = $metrics->getLocExecutable(); + + if ($locExecutable >= $this->threshold) { + return sprintf( + "Function or method has %d lines of executable code.\n" . + 'Violations of this rule usually indicate that the method is ' . + 'doing too much. Try to reduce the method size by creating ' . + 'helper methods and removing any copy/pasted code.', + $locExecutable + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/ExcessiveParameterList.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/ExcessiveParameterList.php new file mode 100644 index 00000000..d2871aff --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/ExcessiveParameterList.php @@ -0,0 +1,85 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Function_ExcessiveParameterList extends PHPUnit_Util_Log_PMD_Rule_Function +{ + public function __construct($threshold = 10, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $parameters = $metrics->getParameters(); + + if ($parameters >= $this->threshold) { + return sprintf( + "Function or method has %d parameters.\n" . + 'Long parameter lists can indicate that a new object should be ' . + 'created to wrap the numerous parameters. Basically, try to '. + 'group the parameters together.', + $parameters + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/NPathComplexity.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/NPathComplexity.php new file mode 100644 index 00000000..86e83e09 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Function/NPathComplexity.php @@ -0,0 +1,86 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Function_NPathComplexity extends PHPUnit_Util_Log_PMD_Rule_Function +{ + public function __construct($threshold = 200, $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $npath = $metrics->getNPath(); + + if ($npath >= $this->threshold) { + return sprintf( + "The NPath complexity is %d.\n" . + 'The NPath complexity of a function or method is the number of ' . + 'acyclic execution paths through that method. A threshold of 200 ' . + 'is generally considered the point where measures should be taken ' . + 'to reduce complexity.', + $npath + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Project.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Project.php new file mode 100644 index 00000000..87a85678 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Project.php @@ -0,0 +1,66 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for PMD rule classes that operate on the project-level. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Log_PMD_Rule_Project extends PHPUnit_Util_Log_PMD_Rule +{ +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Project/CRAP.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Project/CRAP.php new file mode 100644 index 00000000..d5de78cb --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/PMD/Rule/Project/CRAP.php @@ -0,0 +1,109 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Log/PMD/Rule/Project.php'; +require_once 'PHPUnit/Util/Log/PMD/Rule/Function.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Log_PMD_Rule_Project_CRAP extends PHPUnit_Util_Log_PMD_Rule_Project +{ + public function __construct($threshold = array(5, 30), $priority = 1) + { + parent::__construct($threshold, $priority); + } + + public function apply(PHPUnit_Util_Metrics $metrics) + { + $numCrappyMethods = 0; + $numMethods = 0; + + foreach ($metrics->getClasses() as $class) { + $methods = $class->getMethods(); + + foreach ($methods as $method) { + if ($method->getCrapIndex() > $this->threshold[1]) { + $numCrappyMethods++; + } + } + + $numMethods += count($methods); + } + + if ($numMethods > 0) { + $percent = ($numCrappyMethods / $numMethods) * 100; + } else { + $percent = 0; + } + + if ($percent > $this->threshold[0]) { + return sprintf( + "More than %01.2f%% of the project's methods have a Change Risk " . + 'Analysis and Predictions (CRAP) index that is above the threshold ' . + "of %d.\n" . + 'The CRAP index of a function or method uses cyclomatic complexity ' . + 'and code coverage from automated tests to help estimate the ' . + 'effort and risk associated with maintaining legacy code. A CRAP ' . + 'index over 30 is a good indicator of crappy code.', + $this->threshold[0], + $this->threshold[1] + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/TAP.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/TAP.php new file mode 100644 index 00000000..9fbf6078 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Log/TAP.php @@ -0,0 +1,265 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Printer.php'; +require_once 'PHPUnit/Util/Test.php'; + +if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('SymfonyComponents/YAML/sfYamlDumper.php')) { + require_once 'SymfonyComponents/YAML/sfYamlDumper.php'; +} + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * A TestListener that generates a logfile of the + * test execution using the Test Anything Protocol (TAP). + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Log_TAP extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var integer + */ + protected $testNumber = 0; + + /** + * @var integer + */ + protected $testSuiteLevel = 0; + + /** + * @var boolean + */ + protected $testSuccessful = TRUE; + + /** + * Constructor. + * + * @param mixed $out + * @throws InvalidArgumentException + * @since Method available since Release 3.3.4 + */ + public function __construct($out = NULL) + { + parent::__construct($out); + $this->write("TAP version 13\n"); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeNotOk($test, 'Error'); + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->writeNotOk($test, 'Failure'); + + $message = explode( + "\n", PHPUnit_Framework_TestFailure::exceptionToString($e) + ); + + $diagnostic = array( + 'message' => $message[0], + 'severity' => 'fail' + ); + + if ($e instanceof PHPUnit_Framework_ExpectationFailedException) { + $cf = $e->getComparisonFailure(); + + if ($cf !== NULL) { + $diagnostic['data'] = array( + 'got' => $cf->getActual(), + 'expected' => $cf->getExpected() + ); + } + } + + if (class_exists('sfYamlDumper')) { + $yaml = new sfYamlDumper; + + $this->write( + sprintf( + " ---\n%s ...\n", + $yaml->dump($diagnostic, 2, 2) + ) + ); + } + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeNotOk($test, '', 'TODO Incomplete Test'); + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->write( + sprintf( + "ok %d - # SKIP%s\n", + + $this->testNumber, + $e->getMessage() != '' ? ' ' . $e->getMessage() : '' + ) + ); + + $this->testSuccessful = FALSE; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->testSuiteLevel++; + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->testSuiteLevel--; + + if ($this->testSuiteLevel == 0) { + $this->write(sprintf("1..%d\n", $this->testNumber)); + } + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->testNumber++; + $this->testSuccessful = TRUE; + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($this->testSuccessful === TRUE) { + $this->write( + sprintf( + "ok %d - %s\n", + + $this->testNumber, + PHPUnit_Util_Test::describe($test) + ) + ); + } + } + + /** + * @param PHPUnit_Framework_Test $test + * @param string $prefix + * @param string $directive + */ + protected function writeNotOk(PHPUnit_Framework_Test $test, $prefix = '', $directive = '') + { + $this->write( + sprintf( + "not ok %d - %s%s%s\n", + + $this->testNumber, + $prefix != '' ? $prefix . ': ' : '', + PHPUnit_Util_Test::describe($test), + $directive != '' ? ' # ' . $directive : '' + ) + ); + + $this->testSuccessful = FALSE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics.php new file mode 100644 index 00000000..863051cd --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics.php @@ -0,0 +1,70 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Abstract base class for metrics classes. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Metrics +{ +} + +require_once 'PHPUnit/Util/Metrics/Project.php'; +require_once 'PHPUnit/Util/Metrics/File.php'; +require_once 'PHPUnit/Util/Metrics/Class.php'; +require_once 'PHPUnit/Util/Metrics/Function.php'; +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Class.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Class.php new file mode 100644 index 00000000..2d955f01 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Class.php @@ -0,0 +1,732 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Metrics.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Class-Level Metrics. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Metrics_Class extends PHPUnit_Util_Metrics +{ + protected $aif = 0; + protected $ahf = 0; + protected $ca = 0; + protected $ce = 0; + protected $coverage = 0; + protected $dit = 0; + protected $i = 0; + protected $impl = 0; + protected $loc = 0; + protected $locExecutable = 0; + protected $locExecuted = 0; + protected $mif = 0; + protected $mhf = 0; + protected $noc = 0; + protected $pf = 0; + protected $vars = 0; + protected $varsNp = 0; + protected $varsI = 0; + protected $wmc = 0; + protected $wmcNp = 0; + protected $wmcI = 0; + + protected $project; + protected $package = ''; + protected $class; + protected $methods = array(); + protected $inheritedMethods = array(); + protected $dependencies = array(); + protected $publicMethods = 0; + + protected static $cache = array(); + protected static $nocCache = array(); + + /** + * Constructor. + * + * @param ReflectionClass $class + * @param array $codeCoverage + */ + protected function __construct(ReflectionClass $class, &$codeCoverage = array()) + { + $this->class = $class; + + $className = $class->getName(); + + $packageInformation = PHPUnit_Util_Class::getPackageInformation( + $className, $class->getDocComment() + ); + + if (!empty($packageInformation['fullPackage'])) { + $this->package = $packageInformation['fullPackage']; + } + + $this->setCoverage($codeCoverage); + + $this->dit = count(PHPUnit_Util_Class::getHierarchy($class->getName())) - 1; + $this->impl = count($class->getInterfaces()); + + foreach ($this->class->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() == $className) { + $this->methods[$method->getName()] = PHPUnit_Util_Metrics_Function::factory($method, $codeCoverage); + } else { + $this->inheritedMethods[$method->getName()] = PHPUnit_Util_Metrics_Function::factory($method, $codeCoverage); + } + } + + $this->calculateAttributeMetrics(); + $this->calculateMethodMetrics(); + $this->calculateNumberOfChildren(); + $this->calculatePolymorphismFactor(); + $this->calculateDependencies(); + } + + /** + * Factory. + * + * @param ReflectionClass $class + * @param array $codeCoverage + * @return PHPUnit_Util_Metrics_Class + */ + public static function factory(ReflectionClass $class, &$codeCoverage = array()) + { + $className = $class->getName(); + + if (!isset(self::$cache[$className])) { + self::$cache[$className] = new PHPUnit_Util_Metrics_Class($class, $codeCoverage); + } + + else if (!empty($codeCoverage) && self::$cache[$className]->getCoverage() == 0) { + self::$cache[$className]->setCoverage($codeCoverage); + } + + return self::$cache[$className]; + } + + /** + * @param array $codeCoverage + */ + public function setCoverage(array &$codeCoverage) + { + if (!empty($codeCoverage)) { + $this->calculateCodeCoverage($codeCoverage); + + foreach ($this->methods as $method) { + $method->setCoverage($codeCoverage); + } + } + } + + /** + * @param PHPUnit_Util_Metrics_Project $project + */ + public function setProject(PHPUnit_Util_Metrics_Project $project) + { + $this->project = $project; + + $this->ca = 0; + $this->ce = 0; + $this->i = 0; + } + + /** + * Returns the class. + * + * @return ReflectionClass + */ + public function getClass() + { + return $this->class; + } + + /** + * Returns the package of this class. + * + * @return string + */ + public function getPackage() + { + return $this->package; + } + + /** + * Returns the methods of this class. + * + * @return array + */ + public function getMethods() + { + return $this->methods; + } + + /** + * Returns the names of the classes this class depends on. + * + * @return array + */ + public function getDependencies() + { + return $this->dependencies; + } + + /** + * Lines of Code (LOC). + * + * @return int + */ + public function getLoc() + { + return $this->loc; + } + + /** + * Executable Lines of Code (ELOC). + * + * @return int + */ + public function getLocExecutable() + { + return $this->locExecutable; + } + + /** + * Executed Lines of Code. + * + * @return int + */ + public function getLocExecuted() + { + return $this->locExecuted; + } + + /** + * Returns the Number of Public Methods of the class. + * + * @return integer + */ + public function getPublicMethods() + { + return $this->publicMethods; + } + + /** + * Returns the Attribute Inheritance Factor (AIF) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-mood.html + */ + public function getAIF() + { + return $this->aif; + } + + /** + * Returns the Attribute Hiding Factor (AHF) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-mood.html + */ + public function getAHF() + { + return $this->ahf; + } + + /** + * Returns the Afferent Couplings (Ca) for the class. + * + * The number of other classes that depend upon a class is an indicator of + * the class' responsibility. + * + * @return integer + */ + public function getCa() + { + $this->calculateDependencyMetrics(); + + return $this->ca; + } + + /** + * Returns the Efferent Couplings (Ce) for the class. + * + * The number of other classes that the class depends upon is an indicator + * of the class' independence. + * + * @return integer + */ + public function getCe() + { + $this->calculateDependencyMetrics(); + + return $this->ce; + } + + /** + * Returns the Class Size (CSZ) of the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getCSZ() + { + return count($this->methods) + $this->vars; + } + + /** + * Returns the Class Interface Size (CIS) of the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getCIS() + { + return $this->publicMethods + $this->varsNp; + } + + /** + * Returns the Code Coverage for the class. + * + * @return float + */ + public function getCoverage() + { + return $this->coverage; + } + + /** + * Returns the Depth of Inheritance Tree (DIT) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-ck.html + */ + public function getDIT() + { + return $this->dit; + } + + /** + * Returns the Instability (I) for the class. + * + * The ratio of efferent coupling (Ce) to total coupling (Ce + Ca) such that + * I = Ce / (Ce + Ca). This metric is an indicator of the class' resilience + * to change. + * + * The range for this metric is 0 to 1, with I=0 indicating a completely + * stable class and I=1 indicating a completely instable class. + * + * @return float + */ + public function getI() + { + $this->calculateDependencyMetrics(); + + return $this->i; + } + + /** + * Returns the Number of Interfaces Implemented by the class (IMPL). + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getIMPL() + { + return $this->impl; + } + + /** + * Returns the Method Inheritance Factor (MIF) for the class. + * + * @return float + * @see http://www.aivosto.com/project/help/pm-oo-mood.html + */ + public function getMIF() + { + return $this->mif; + } + + /** + * Returns the Method Hiding Factor (MHF) for the class. + * + * @return float + * @see http://www.aivosto.com/project/help/pm-oo-mood.html + */ + public function getMHF() + { + return $this->mhf; + } + + /** + * Returns the Number of Children (NOC) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-ck.html + */ + public function getNOC() + { + return $this->noc; + } + + /** + * Returns the Polymorphism Factor (PF) for the class. + * + * @return float + * @see http://www.aivosto.com/project/help/pm-oo-mood.html + */ + public function getPF() + { + return $this->pf; + } + + /** + * Returns the Number of Variables (VARS) defined by the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getVARS() + { + return $this->vars; + } + + /** + * Returns the Number of Non-Private Variables (VARSnp) defined by the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getVARSnp() + { + return $this->varsNp; + } + + /** + * Returns the Number of Variables (VARSi) defined and inherited by the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getVARSi() + { + return $this->varsI; + } + + /** + * Returns the Weighted Methods Per Class (WMC) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-ck.html + */ + public function getWMC() + { + return $this->wmc; + } + + /** + * Returns the Weighted Non-Private Methods Per Class (WMCnp) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getWMCnp() + { + return $this->wmcNp; + } + + /** + * Returns the Weighted Inherited Methods Per Class (WMCi) for the class. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getWMCi() + { + return $this->wmcI; + } + + /** + * Calculates the Attribute Inheritance Factor (AIF) and + * Attribute Hiding Factor (AHF) metrics for the class. + * + */ + protected function calculateAttributeMetrics() + { + $attributes = 0; + $hiddenAttributes = 0; + $inheritedAttributes = 0; + + foreach ($this->class->getProperties() as $attribute) { + if ($attribute->isPublic()) { + $this->varsNp++; + } else { + $hiddenAttributes++; + } + + if ($attribute->getDeclaringClass()->getName() == $this->class->getName()) { + $this->vars++; + } else { + $inheritedAttributes++; + } + + $this->varsI++; + $attributes++; + } + + if ($attributes > 0) { + $this->aif = (100 * $inheritedAttributes) / $attributes; + $this->ahf = (100 * $hiddenAttributes) / $attributes; + } + } + + /** + * Calculates the Method Inheritance Factor (MIF) + * Method Hiding Factor (MHF), Weighted Methods Per Class (WMC), + * Weighted Non-Private Methods Per Class (WMCnp), and + * Weighted Inherited Methods Per Class (WMCi) metrics for the class. + * + */ + protected function calculateMethodMetrics() + { + $numMethods = 0; + $hiddenMethods = 0; + $inheritedMethods = 0; + + $methods = array_merge($this->methods, $this->inheritedMethods); + + foreach ($methods as $method) { + $ccn = $method->getCCN(); + + if ($method->getMethod()->getDeclaringClass()->getName() == $this->class->getName()) { + $this->wmc += $ccn; + + if ($method->getMethod()->isPublic()) { + $this->publicMethods++; + $this->wmcNp += $ccn; + } + } else { + $inheritedMethods++; + } + + if (!$method->getMethod()->isPublic()) { + $hiddenMethods++; + } + + $this->wmcI += $ccn; + $numMethods++; + } + + if ($numMethods > 0) { + $this->mif = (100 * $inheritedMethods) / $numMethods; + $this->mhf = (100 * $hiddenMethods) / $numMethods; + } + } + + /** + * Calculates the Number of Children (NOC) metric for the class. + * + */ + protected function calculateNumberOfChildren() + { + $className = $this->class->getName(); + + if (!isset(self::$nocCache[$className])) { + self::$nocCache = array(); + } + + if (empty(self::$nocCache)) { + foreach (get_declared_classes() as $_className) { + $class = new ReflectionClass($_className); + $parent = $class->getParentClass(); + + if ($parent !== FALSE) { + $parentName = $parent->getName(); + + if (isset(self::$nocCache[$parentName])) { + self::$nocCache[$parentName]++; + } else { + self::$nocCache[$parentName] = 1; + } + } + } + } + + if (isset(self::$nocCache[$className])) { + $this->noc = self::$nocCache[$className]; + } + } + + /** + * Calculates the Polymorphism Factor (PF) metric for the class. + * + * @param ReflectionClass $class + */ + protected function calculatePolymorphismFactor() + { + $parentClass = $this->class->getParentClass(); + + if ($parentClass !== FALSE) { + $overridableMethods = array(); + + foreach ($parentClass->getMethods() as $method) { + if (!$method->isPrivate() && !$method->isFinal() && !$method->isAbstract()) { + $overridableMethods[] = $method->getName(); + } + } + + if (!empty($overridableMethods)) { + $overriddenMethods = 0; + + foreach ($this->class->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() == $this->class->getName()) { + $methodName = $method->getName(); + + if (in_array($methodName, $overridableMethods)) { + $overriddenMethods++; + } + } + } + + $this->pf = (100 * $overriddenMethods) / count($overridableMethods); + } + } + } + + /** + * Calculates the Code Coverage for the class. + * + * @param array $codeCoverage + */ + protected function calculateCodeCoverage(&$codeCoverage) + { + $statistics = PHPUnit_Util_CodeCoverage::getStatistics( + $codeCoverage, + $this->class->getFileName(), + $this->class->getStartLine(), + $this->class->getEndLine() + ); + + $this->coverage = $statistics['coverage']; + $this->loc = $statistics['loc']; + $this->locExecutable = $statistics['locExecutable']; + $this->locExecuted = $statistics['locExecuted']; + } + + /** + * Calculates the dependencies for this class. + * + */ + protected function calculateDependencies() + { + $parent = $this->class->getParentClass(); + + if ($parent && $parent->isUserDefined() && !in_array($parent->getName(), $this->dependencies)) { + $this->dependencies[] = $parent->getName(); + } + + $interfaces = $this->class->getInterfaces(); + + foreach ($interfaces as $interface) { + if ($interface->isUserDefined() && !in_array($interface->getName(), $this->dependencies)) { + $this->dependencies[] = $interface->getName(); + } + } + + $methods = array_merge($this->methods, $this->inheritedMethods); + + foreach ($methods as $method) { + foreach ($method->getDependencies() as $dependency) { + if (!in_array($dependency, $this->dependencies)) { + $this->dependencies[] = $dependency; + } + } + } + } + + /** + * Calculates the dependency-based metrics for this class. + * + */ + protected function calculateDependencyMetrics() + { + if ($this->ca == 0 && $this->ce == 0 && $this->i == 0) { + $className = $this->class->getName(); + $dependencies = $this->project->getDependencies(); + + foreach ($dependencies[$className] as $dependency) { + if ($dependency > 0) { + $this->ce++; + } + } + + unset($dependencies[$className]); + + foreach ($dependencies as $_className => $_dependencies) { + if ($_dependencies[$className] > 0) { + $this->ca++; + } + } + + $sum = $this->ce + $this->ca; + + if ($sum > 0) { + $this->i = $this->ce / $sum; + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/File.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/File.php new file mode 100644 index 00000000..30bf943a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/File.php @@ -0,0 +1,308 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/File.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Metrics.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * File-Level Metrics. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Metrics_File extends PHPUnit_Util_Metrics +{ + protected $coverage = 0; + protected $loc = 0; + protected $cloc = 0; + protected $ncloc = 0; + protected $locExecutable = 0; + protected $locExecuted = 0; + + protected $filename; + protected $classes = array(); + protected $functions = array(); + + protected static $cache = array(); + + /** + * Constructor. + * + * @param string $filename + * @param array $codeCoverage + * @throws RuntimeException + */ + protected function __construct($filename, &$codeCoverage = array()) + { + if (!file_exists($filename)) { + throw new RuntimeException( + sprintf( + 'File "%s" not found.', + $filename + ) + ); + } + + $this->filename = $filename; + + foreach (PHPUnit_Util_File::countLines($this->filename) as $name => $value) { + $this->$name = $value; + } + + $this->setCoverage($codeCoverage); + + foreach (PHPUnit_Util_File::getClassesInFile($filename) as $className => $class) { + $this->classes[$className] = PHPUnit_Util_Metrics_Class::factory( + new ReflectionClass($className), $codeCoverage + ); + } + + foreach (PHPUnit_Util_File::getFunctionsInFile($filename) as $functionName => $function) { + $this->functions[$functionName] = PHPUnit_Util_Metrics_Function::factory( + new ReflectionFunction($functionName), $codeCoverage + ); + } + } + + /** + * Factory. + * + * @param string $filename + * @param array $codeCoverage + * @return PHPUnit_Util_Metrics_File + */ + public static function factory($filename, &$codeCoverage = array()) + { + if (!isset(self::$cache[$filename])) { + self::$cache[$filename] = new PHPUnit_Util_Metrics_File($filename, $codeCoverage); + } + + else if (!empty($codeCoverage) && self::$cache[$filename]->getCoverage() == 0) { + self::$cache[$filename]->setCoverage($codeCoverage); + } + + return self::$cache[$filename]; + } + + /** + * @param array $codeCoverage + */ + public function setCoverage(array &$codeCoverage) + { + if (!empty($codeCoverage)) { + $this->calculateCodeCoverage($codeCoverage); + + foreach ($this->classes as $class) { + $class->setCoverage($codeCoverage); + } + + foreach ($this->functions as $function) { + $function->setCoverage($codeCoverage); + } + } + } + + /** + * Returns the path to the file. + * + * @return string + */ + public function getPath() + { + return $this->filename; + } + + /** + * Classes. + * + * @return array + */ + public function getClasses() + { + return $this->classes; + } + + /** + * A class. + * + * @param string $className + * @return ReflectionClass + */ + public function getClass($className) + { + return $this->classes[$className]; + } + + /** + * Functions. + * + * @return array + */ + public function getFunctions() + { + return $this->functions; + } + + /** + * A function. + * + * @param string $functionName + * @return ReflectionClass + */ + public function getFunction($functionName) + { + return $this->functions[$functionName]; + } + + /** + * Lines. + * + * @return array + */ + public function getLines() + { + return file($this->filename); + } + + /** + * Tokens. + * + * @return array + */ + public function getTokens() + { + return token_get_all(file_get_contents($this->filename)); + } + + /** + * Returns the Code Coverage for the file. + * + * @return float + */ + public function getCoverage() + { + return $this->coverage; + } + + /** + * Lines of Code (LOC). + * + * @return int + */ + public function getLoc() + { + return $this->loc; + } + + /** + * Executable Lines of Code (ELOC). + * + * @return int + */ + public function getLocExecutable() + { + return $this->locExecutable; + } + + /** + * Executed Lines of Code. + * + * @return int + */ + public function getLocExecuted() + { + return $this->locExecuted; + } + + /** + * Comment Lines of Code (CLOC). + * + * @return int + */ + public function getCloc() + { + return $this->cloc; + } + + /** + * Non-Comment Lines of Code (NCLOC). + * + * @return int + */ + public function getNcloc() + { + return $this->ncloc; + } + + /** + * Calculates the Code Coverage for the class. + * + * @param array $codeCoverage + */ + protected function calculateCodeCoverage(&$codeCoverage) + { + $statistics = PHPUnit_Util_CodeCoverage::getStatistics( + $codeCoverage, + $this->filename, + 1, + $this->loc + ); + + $this->coverage = $statistics['coverage']; + $this->loc = $statistics['loc']; + $this->locExecutable = $statistics['locExecutable']; + $this->locExecuted = $statistics['locExecuted']; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Function.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Function.php new file mode 100644 index 00000000..d8c59b0f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Function.php @@ -0,0 +1,503 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Function- and Method-Level Metrics. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Metrics_Function extends PHPUnit_Util_Metrics +{ + protected $ccn = 1; + protected $npath = 1; + protected $coverage = 0; + protected $crap; + protected $loc = 0; + protected $locExecutable = 0; + protected $locExecuted = 0; + protected $parameters = 0; + + protected $function; + protected $scope; + protected $tokens; + + protected $dependencies = array(); + + protected static $cache = array(); + + /** + * Constructor. + * + * @param string $scope + * @param ReflectionFunction|ReflectionMethod $function + * @param array $codeCoverage + */ + protected function __construct($scope, $function, &$codeCoverage = array()) + { + $this->scope = $scope; + $this->function = $function; + + $source = PHPUnit_Util_Class::getMethodSource( + $scope, $function->getName() + ); + + if ($source !== FALSE) { + $this->tokens = token_get_all(''); + $this->parameters = $function->getNumberOfParameters(); + + $this->calculateCCN(); + $this->calculateNPath(); + $this->calculateDependencies(); + } + + $this->setCoverage($codeCoverage); + } + + /** + * Factory. + * + * @param ReflectionFunction|ReflectionMethod $function + * @param array $codeCoverage + * @return PHPUnit_Util_Metrics_Method + */ + public static function factory($function, &$codeCoverage = array()) + { + if ($function instanceof ReflectionMethod) { + $scope = $function->getDeclaringClass()->getName(); + } else { + $scope = 'global'; + } + + $name = $function->getName(); + + if (!isset(self::$cache[$scope][$name])) { + self::$cache[$scope][$name] = new PHPUnit_Util_Metrics_Function($scope, $function, $codeCoverage); + } + + else if (!empty($codeCoverage) && self::$cache[$scope][$name]->getCoverage() == 0) { + self::$cache[$scope][$name]->setCoverage($codeCoverage); + } + + return self::$cache[$scope][$name]; + } + + /** + * @param array $codeCoverage + */ + public function setCoverage(array &$codeCoverage) + { + if (!empty($codeCoverage)) { + $this->calculateCodeCoverage($codeCoverage); + $this->calculateCrapIndex(); + } + } + + /** + * Returns the function. + * + * @return ReflectionFunction + */ + public function getFunction() + { + return $this->function; + } + + /** + * Returns the method. + * Alias for getFunction(). + * + * @return ReflectionMethod + */ + public function getMethod() + { + return $this->function; + } + + /** + * Returns the names of the classes this function or method depends on. + * + * @return array + */ + public function getDependencies() + { + return $this->dependencies; + } + + /** + * Lines of Code (LOC). + * + * @return int + */ + public function getLoc() + { + return $this->loc; + } + + /** + * Executable Lines of Code (ELOC). + * + * @return int + */ + public function getLocExecutable() + { + return $this->locExecutable; + } + + /** + * Executed Lines of Code. + * + * @return int + */ + public function getLocExecuted() + { + return $this->locExecuted; + } + + /** + * Number of Parameters. + * + * @return int + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Returns the Cyclomatic Complexity Number (CCN) for the method. + * This is also known as the McCabe metric. + * + * Each method has a minimum value of 1 per default. For each of the + * following PHP keywords/statements this value gets incremented by one: + * + * - if + * - elseif + * - for + * - foreach + * - while + * - case + * - catch + * - AND, && + * - OR, || + * - ? + * + * Note that 'else', 'default', and 'finally' don't increment the value + * any further. On the other hand, a simple method with a 'switch' + * statement and a huge block of 'case 'statements can have a surprisingly + * high value (still it has the same value when converting a 'switch' + * block to an equivalent sequence of 'if' statements). + * + * @return integer + * @see http://en.wikipedia.org/wiki/Cyclomatic_complexity + */ + public function getCCN() + { + return $this->ccn; + } + + /** + * Returns the Change Risk Analysis and Predictions (CRAP) index for the + * method. + * + * @return float + * @see http://www.artima.com/weblogs/viewpost.jsp?thread=210575 + */ + public function getCrapIndex() + { + return $this->crap; + } + + /** + * Returns the Code Coverage for the method. + * + * @return float + */ + public function getCoverage() + { + return $this->coverage; + } + + /** + * Returns the NPath Complexity for the method. + * + * @return integer + */ + public function getNPath() + { + return $this->npath; + } + + /** + * Calculates the Cyclomatic Complexity Number (CCN) for the method. + * + */ + protected function calculateCCN() + { + foreach ($this->tokens as $token) { + if (is_string($token)) { + $token = trim($token); + + if ($token == '?') { + $this->ccn++; + } + + continue; + } + + list ($token, $value) = $token; + + switch ($token) { + case T_IF: + case T_ELSEIF: + case T_FOR: + case T_FOREACH: + case T_WHILE: + case T_CASE: + case T_CATCH: + case T_BOOLEAN_AND: + case T_LOGICAL_AND: + case T_BOOLEAN_OR: + case T_LOGICAL_OR: { + $this->ccn++; + } + break; + } + } + } + + /** + * Calculates the NPath Complexity for the method. + * + */ + protected function calculateNPath() + { + $npathStack = array(); + $stack = array(); + + foreach ($this->tokens as $token) { + if (is_string($token)) { + $token = trim($token); + + if ($token == '?') { + $this->npath = ($this->npath + 1) * $this->npath; + } + + if ($token == '{') { + if (isset($scope)) { + array_push($stack, $scope); + array_push($npathStack, $this->npath); + $this->npath = 1; + } else { + array_push($stack, NULL); + } + } + + if ($token == '}') { + $scope = array_pop($stack); + + if ($scope !== NULL) { + switch ($scope) { + case T_WHILE: + case T_DO: + case T_FOR: + case T_FOREACH: + case T_IF: + case T_TRY: + case T_SWITCH: { + $this->npath = ($this->npath + 1) * array_pop($npathStack); + } + break; + + case T_ELSE: + case T_CATCH: + case T_CASE: { + $this->npath = ($this->npath - 1) + array_pop($npathStack); + } + break; + } + } + } + + continue; + } + + list ($token, $value) = $token; + + switch ($token) { + case T_WHILE: + case T_DO: + case T_FOR: + case T_FOREACH: + case T_IF: + case T_TRY: + case T_SWITCH: + case T_ELSE: + case T_CATCH: + case T_CASE: { + $scope = $token; + } + break; + } + } + } + + /** + * Calculates the Code Coverage for the method. + * + * @param array $codeCoverage + */ + protected function calculateCodeCoverage(&$codeCoverage) + { + $statistics = PHPUnit_Util_CodeCoverage::getStatistics( + $codeCoverage, + $this->function->getFileName(), + $this->function->getStartLine(), + $this->function->getEndLine() + ); + + $this->coverage = $statistics['coverage']; + $this->loc = $statistics['loc']; + $this->locExecutable = $statistics['locExecutable']; + $this->locExecuted = $statistics['locExecuted']; + } + + /** + * Calculates the Change Risk Analysis and Predictions (CRAP) index for the + * method. + * + */ + protected function calculateCrapIndex() + { + if ($this->coverage == 0) { + $this->crap = pow($this->ccn, 2) + $this->ccn; + } + + else if ($this->coverage >= 95) { + $this->crap = $this->ccn; + } + + else { + $this->crap = pow($this->ccn, 2) * pow(1 - $this->coverage/100, 3) + $this->ccn; + } + } + + /** + * Calculates the dependencies for this function or method. + * + */ + protected function calculateDependencies() + { + foreach ($this->function->getParameters() as $parameter) { + try { + $class = $parameter->getClass(); + + if ($class) { + $className = $class->getName(); + + if ($className != $this->scope && !in_array($className, $this->dependencies)) { + $this->dependencies[] = $className; + } + } + } + + catch (ReflectionException $e) { + } + } + + $inNew = FALSE; + + foreach ($this->tokens as $token) { + if (is_string($token)) { + if (trim($token) == ';') { + $inNew = FALSE; + } + + continue; + } + + list ($token, $value) = $token; + + switch ($token) { + case T_NEW: { + $inNew = TRUE; + } + break; + + case T_STRING: { + if ($inNew) { + if ($value != $this->scope && class_exists($value, FALSE)) { + try { + $class = new ReflectionClass($value); + + if ($class->isUserDefined() && !in_array($value, $this->dependencies)) { + $this->dependencies[] = $value; + } + } + + catch (ReflectionException $e) { + } + } + } + + $inNew = FALSE; + } + break; + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Project.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Project.php new file mode 100644 index 00000000..3cc89f92 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Metrics/Project.php @@ -0,0 +1,475 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Metrics.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Project-Level Metrics. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Metrics_Project extends PHPUnit_Util_Metrics +{ + protected static $CPD_IGNORE_LIST = array( + T_INLINE_HTML, + T_COMMENT, + T_DOC_COMMENT, + T_OPEN_TAG, + T_OPEN_TAG_WITH_ECHO, + T_CLOSE_TAG, + T_WHITESPACE + ); + + protected $classes = array(); + protected $files = array(); + protected $functions = array(); + + protected $cls = 0; + protected $clsa = 0; + protected $clsc = 0; + protected $interfs = 0; + protected $roots = 0; + protected $leafs = 0; + protected $maxDit = 0; + + protected $cpdDuplicates = array(); + protected $cpdHashes = array(); + protected $dependencies = array(); + + /** + * Constructor. + * + * @param array $files + * @param array $codeCoverage + * @param boolean $cpd + * @param integer $cpdMinLines + * @param integer $cpdMinMatches + */ + public function __construct(Array $files, &$codeCoverage = array(), $cpd = FALSE, $cpdMinLines = 5, $cpdMinMatches = 70) + { + foreach ($files as $file) { + if (file_exists($file)) { + $this->files[$file] = PHPUnit_Util_Metrics_File::factory( + $file, $codeCoverage + ); + + foreach ($this->files[$file]->getFunctions() as $function) { + $this->functions[$function->getFunction()->getName()] = $function; + } + + foreach ($this->files[$file]->getClasses() as $class) { + $className = $class->getClass()->getName(); + $package = $class->getPackage(); + + $this->classes[$className] = $class; + + if ($class->getClass()->isInterface()) { + $this->interfs++; + } else { + if ($class->getClass()->isAbstract()) { + $this->clsa++; + } else { + $this->clsc++; + } + + $this->cls++; + } + } + } + } + + $numClasses = count($this->classes); + + foreach ($this->classes as $a => $b) { + foreach ($this->classes as $c => $d) { + $this->dependencies[$a][$c] = 0; + } + } + + foreach ($this->classes as $className => $class) { + foreach ($class->getDependencies() as $dependency) { + $this->dependencies[$className][$dependency] = 1; + } + + $class->setProject($this); + + if ($class->getNOC() == 0) { + $this->leafs++; + } + + else if ($class->getClass()->getParentClass() === FALSE) { + $this->roots++; + } + + $this->maxDit = max($this->maxDit, $class->getDit()); + } + + if ($cpd) { + $this->copyPasteDetection($cpdMinLines, $cpdMinMatches); + } + } + + /** + * Returns the classes of this project. + * + * @return array + */ + public function getClasses() + { + return $this->classes; + } + + /** + * A class. + * + * @param string $className + * @return ReflectionClass + */ + public function getClass($className) + { + return $this->classes[$className]; + } + + /** + * Returns the dependencies between the classes of this project. + * + * @return array + */ + public function getDependencies() + { + return $this->dependencies; + } + + /** + * Returns the dependencies between the classes of this project + * as GraphViz/DOT markup. + * + * @return Image_GraphViz + * @since Method available since Release 3.2.2 + */ + public function getDependenciesAsDOT() + { + if (PHPUnit_Util_Filesystem::fileExistsInIncludePath('Image/GraphViz.php')) { + require_once 'Image/GraphViz.php'; + } else { + throw new RuntimeException('Image_GraphViz is not available.'); + } + + $graph = new Image_GraphViz( + TRUE, + array( + 'overlap' => 'scale', + 'splines' => 'true', + 'sep' => '.1', + 'fontsize' => '8' + ) + ); + + foreach (array_keys($this->dependencies) as $className) { + $graph->addNode($className); + } + + foreach ($this->dependencies as $from => $dependencies) { + foreach ($dependencies as $to => $flag) { + if ($flag === 1) { + $graph->addEdge(array($from => $to)); + } + } + } + + return $graph; + } + + /** + * Returns the duplicates found by the Copy & Paste Detection (CPD). + * + * @return array + */ + public function getDuplicates() + { + return $this->cpdDuplicates; + } + + /** + * Returns the files of this project. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * A file. + * + * @param string $className + * @return ReflectionClass + */ + public function getFile($filename) + { + return $this->files[$filename]; + } + + /** + * Functions. + * + * @return array + */ + public function getFunctions() + { + return $this->functions; + } + + /** + * A function. + * + * @param string $functionName + * @return ReflectionClass + */ + public function getFunction($functionName) + { + return $this->functions[$functionName]; + } + + /** + * Returns the Number of Classes (CLS) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getCLS() + { + return $this->cls; + } + + /** + * Returns the Number of Abstract Classes (CLSa) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getCLSa() + { + return $this->clsa; + } + + /** + * Returns the Number of Concrete Classes (CLSc) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getCLSc() + { + return $this->clsc; + } + + /** + * Returns the Number of Root Classes (ROOTS) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getRoots() + { + return $this->roots; + } + + /** + * Returns the Number of Leaf Classes (LEAFS) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getLeafs() + { + return $this->leafs; + } + + /** + * Returns the Number of Interfaces (INTERFS) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getInterfs() + { + return $this->interfs; + } + + /** + * Returns the Maximum Depth of Intheritance Tree (maxDIT) for the project. + * + * @return integer + * @see http://www.aivosto.com/project/help/pm-oo-misc.html + */ + public function getMaxDit() + { + return $this->maxDit; + } + + /** + * Copy & Paste Detection (CPD). + * + * @param integer $minLines + * @param integer $minMatches + * @author Johann-Peter Hartmann + */ + protected function copyPasteDetection($minLines, $minMatches) + { + foreach ($this->files as $file) { + $currentTokenPositions = array(); + $currentSignature = ''; + $tokens = $file->getTokens(); + $tokenNr = 0; + $line = 1; + + foreach (array_keys($tokens) as $key) { + $token = $tokens[$key]; + + if (is_string($token)) { + $line += substr_count($token, "\n"); + } else { + if (!in_array($token[0], self::$CPD_IGNORE_LIST)) { + $currentTokenPositions[$tokenNr++] = $line; + $currentSignature .= chr($token[0] & 255) . pack('N*', crc32($token[1])); + } + + $line += substr_count($token[1], "\n"); + } + } + + $tokenNr = 0; + $firstLine = 0; + $found = FALSE; + + if (count($currentTokenPositions) > 0) { + do { + $line = $currentTokenPositions[$tokenNr]; + + $hash = substr( + md5( + substr( + $currentSignature, $tokenNr * 5, + $minMatches * 5 + ), + TRUE + ), + 0, + 8 + ); + + if (isset($this->cpdHashes[$hash])) { + $found = TRUE; + + if ($firstLine === 0) { + $firstLine = $line; + $firstHash = $hash; + $firstToken = $tokenNr; + } + } else { + if ($found) { + $fileA = $this->cpdHashes[$firstHash][0]; + $firstLineA = $this->cpdHashes[$firstHash][1]; + + if ($line + 1 - $firstLine > $minLines && + ($fileA->getPath() != $file->getPath() || + $firstLineA != $firstLine)) { + $this->cpdDuplicates[] = array( + 'fileA' => $fileA, + 'firstLineA' => $firstLineA, + 'fileB' => $file, + 'firstLineB' => $firstLine, + 'numLines' => $line + 1 - $firstLine, + 'numTokens' => $tokenNr + 1 - $firstToken + ); + } + + $found = FALSE; + $firstLine = 0; + } + + $this->cpdHashes[$hash] = array($file, $line); + } + + $tokenNr++; + } while ($tokenNr <= (count($currentTokenPositions) - + $minMatches )+1); + } + + if ($found) { + $fileA = $this->cpdHashes[$firstHash][0]; + $firstLineA = $this->cpdHashes[$firstHash][1]; + + if ($line + 1 - $firstLine > $minLines && + ($fileA->getPath() != $file->getPath() || + $firstLineA != $firstLine)) { + $this->cpdDuplicates[] = array( + 'fileA' => $fileA, + 'firstLineA' => $firstLineA, + 'fileB' => $file, + 'firstLineB' => $firstLine, + 'numLines' => $line + 1 - $firstLine, + 'numTokens' => $tokenNr + 1 - $firstToken + ); + } + + $found = FALSE; + } + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/PDO.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/PDO.php new file mode 100644 index 00000000..43b1383f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/PDO.php @@ -0,0 +1,361 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.4 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * PDO helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Util_PDO +{ + public static function factory($dsn) + { + $parsed = self::parseDSN($dsn); + + switch ($parsed['phptype']) { + case 'mysql': { + $database = NULL; + $charset = NULL; + $host = NULL; + $port = NULL; + $socket = NULL; + $user = NULL; + $pass = NULL; + $driverOptions = NULL; + + foreach ( $parsed as $key => $val ) + { + switch ( $key ) + { + case 'database': + case 'dbname': + $database = $val; + break; + + case 'charset': + $charset = $val; + break; + + case 'host': + case 'hostspec': + $host = $val; + break; + + case 'port': + $port = $val; + break; + + case 'socket': + $socket = $val; + break; + + case 'user': + case 'username': + $user = $val; + break; + + case 'pass': + case 'password': + $pass = $val; + break; + + case 'driver-opts': + $driverOptions = $val; + break; + } + } + + if ( !isset( $database ) ) + { + throw new InvalidArgumentException('Invalid DSN.'); + } + + $dsn = "mysql:dbname=$database"; + + if ( isset( $host ) && $host ) + { + $dsn .= ";host=$host"; + } + + if ( isset( $port ) && $port ) + { + $dsn .= ";port=$port"; + } + + if ( isset( $charset ) && $charset ) + { + $dsn .= ";charset=$charset"; + } + + if ( isset( $socket ) && $socket ) + { + $dsn .= ";unix_socket=$socket"; + } + + $dbh = new PDO($dsn, $user, $pass, $driverOptions); + } + break; + + case 'sqlite': { + $dbh = new PDO($dsn); + } + break; + + default: { + throw new InvalidArgumentException('Invalid DSN.'); + } + } + + $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + return $dbh; + } + + /** + * Returns the Data Source Name as a structure containing the various parts of the DSN. + * + * Additional keys can be added by appending a URI query string to the + * end of the DSN. + * + * The format of the supplied DSN is in its fullest form: + * + * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true + * + * + * Most variations are allowed: + * + * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 + * phptype://username:password@hostspec/database_name + * phptype://username:password@hostspec + * phptype://username@hostspec + * phptype://hostspec/database + * phptype://hostspec + * phptype(dbsyntax) + * phptype + * + * + * This function is 'borrowed' from PEAR /DB.php . + * + * @param string $dsn Data Source Name to be parsed + * + * @return array an associative array with the following keys: + * + phptype: Database backend used in PHP (mysql, odbc etc.) + * + dbsyntax: Database used with regards to SQL syntax etc. + * + protocol: Communication protocol to use (tcp, unix etc.) + * + hostspec: Host specification (hostname[:port]) + * + database: Database to use on the DBMS server + * + username: User name for login + * + password: Password for login + */ + public static function parseDSN( $dsn ) + { + if ( $dsn == 'sqlite::memory:' ) + { + $dsn = 'sqlite://:memory:'; + } + + $parsed = array( + 'phptype' => FALSE, + 'dbsyntax' => FALSE, + 'username' => FALSE, + 'password' => FALSE, + 'protocol' => FALSE, + 'hostspec' => FALSE, + 'port' => FALSE, + 'socket' => FALSE, + 'database' => FALSE, + ); + + if ( is_array( $dsn ) ) + { + $dsn = array_merge( $parsed, $dsn ); + if ( !$dsn['dbsyntax'] ) + { + $dsn['dbsyntax'] = $dsn['phptype']; + } + return $dsn; + } + + // Find phptype and dbsyntax + if ( ( $pos = strpos( $dsn, '://' ) ) !== FALSE ) + { + $str = substr( $dsn, 0, $pos ); + $dsn = substr( $dsn, $pos + 3 ); + } + else + { + $str = $dsn; + $dsn = NULL; + } + + // Get phptype and dbsyntax + // $str => phptype(dbsyntax) + if ( preg_match( '|^(.+?)\((.*?)\)$|', $str, $arr ) ) + { + $parsed['phptype'] = $arr[1]; + $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; + } + else + { + $parsed['phptype'] = $str; + $parsed['dbsyntax'] = $str; + } + + if ( !count( $dsn ) ) + { + return $parsed; + } + + // Get (if found): username and password + // $dsn => username:password@protocol+hostspec/database + if ( ( $at = strrpos( (string) $dsn, '@' ) ) !== FALSE ) + { + $str = substr( $dsn, 0, $at ); + $dsn = substr( $dsn, $at + 1 ); + if ( ( $pos = strpos( $str, ':' ) ) !== FALSE ) + { + $parsed['username'] = rawurldecode( substr( $str, 0, $pos ) ); + $parsed['password'] = rawurldecode( substr( $str, $pos + 1 ) ); + } + else + { + $parsed['username'] = rawurldecode( $str ); + } + } + + // Find protocol and hostspec + + if ( preg_match( '|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match ) ) + { + // $dsn => proto(proto_opts)/database + $proto = $match[1]; + $proto_opts = $match[2] ? $match[2] : FALSE; + $dsn = $match[3]; + } + else + { + // $dsn => protocol+hostspec/database (old format) + if ( strpos( $dsn, '+' ) !== FALSE ) + { + list( $proto, $dsn ) = explode( '+', $dsn, 2 ); + } + if ( strpos( $dsn, '/' ) !== FALSE ) + { + list( $proto_opts, $dsn ) = explode( '/', $dsn, 2 ); + } + else + { + $proto_opts = $dsn; + $dsn = NULL; + } + } + + // process the different protocol options + $parsed['protocol'] = ( !empty( $proto ) ) ? $proto : 'tcp'; + $proto_opts = rawurldecode( $proto_opts ); + if ( $parsed['protocol'] == 'tcp' ) + { + if ( strpos( $proto_opts, ':' ) !== FALSE ) + { + list( $parsed['hostspec'], $parsed['port'] ) = explode( ':', $proto_opts ); + } + else + { + $parsed['hostspec'] = $proto_opts; + } + } + elseif ( $parsed['protocol'] == 'unix' ) + { + $parsed['socket'] = $proto_opts; + } + + // Get dabase if any + // $dsn => database + if ( $dsn ) + { + if ( ( $pos = strpos( $dsn, '?' ) ) === FALSE ) + { + // /database + $parsed['database'] = rawurldecode( $dsn ); + } + else + { + // /database?param1=value1¶m2=value2 + $parsed['database'] = rawurldecode( substr( $dsn, 0, $pos ) ); + $dsn = substr( $dsn, $pos + 1 ); + if ( strpos( $dsn, '&') !== FALSE ) + { + $opts = explode( '&', $dsn ); + } + else + { // database?param1=value1 + $opts = array( $dsn ); + } + foreach ( $opts as $opt ) + { + list( $key, $value ) = explode( '=', $opt ); + if ( !isset( $parsed[$key] ) ) + { + // don't allow params overwrite + $parsed[$key] = rawurldecode( $value ); + } + } + } + } + return $parsed; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/PHP.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/PHP.php new file mode 100644 index 00000000..bf12e018 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/PHP.php @@ -0,0 +1,162 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.4.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Utility methods for PHP sub-processes. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_PHP +{ + /** + * Path to the PHP interpreter that is to be used. + * + * @var string $phpBinary + */ + protected static $phpBinary = NULL; + + /** + * Descriptor specification for proc_open(). + * + * @var array + */ + protected static $descriptorSpec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + + /** + * Returns the path to a PHP interpreter. + * + * PHPUnit_Util_PHP::$phpBinary contains the path to the PHP + * interpreter. + * + * When not set, the following assumptions will be made: + * + * 1. When the PHP CLI/CGI binary configured with the PEAR Installer + * (php_bin configuration value) is readable, it will be used. + * + * 2. When PHPUnit is run using the CLI SAPI and the $_SERVER['_'] + * variable does not contain the string "PHPUnit", $_SERVER['_'] + * is assumed to contain the path to the current PHP interpreter + * and that will be used. + * + * 3. When PHPUnit is run using the CLI SAPI and the $_SERVER['_'] + * variable contains the string "PHPUnit", the file that $_SERVER['_'] + * points to is assumed to be the PHPUnit TextUI CLI wrapper script + * "phpunit" and the binary set up using #! on that file's first + * line of code is assumed to contain the path to the current PHP + * interpreter and that will be used. + * + * 4. The current PHP interpreter is assumed to be in the $PATH and + * to be invokable through "php". + * + * @return string + */ + public static function getPhpBinary() + { + if (self::$phpBinary === NULL) { + if (is_readable('@php_bin@')) { + self::$phpBinary = '@php_bin@'; + } + + else if (PHP_SAPI == 'cli' && isset($_SERVER['_']) && + strpos($_SERVER['_'], 'phpunit') !== FALSE) { + $file = file($_SERVER['_']); + $tmp = explode(' ', $file[0]); + self::$phpBinary = trim($tmp[1]); + } + + if (!is_readable(self::$phpBinary)) { + self::$phpBinary = 'php'; + } else { + self::$phpBinary = escapeshellarg(self::$phpBinary); + } + } + + return self::$phpBinary; + } + + /** + * Runs a single job (PHP code) using a separate PHP process. + * + * @param string $job + * @return string + */ + public static function runJob($job) + { + $process = proc_open( + self::getPhpBinary(), self::$descriptorSpec, $pipes + ); + + if (is_resource($process)) { + fwrite($pipes[0], $job); + fclose($pipes[0]); + + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + proc_close($process); + + return array('stdout' => $stdout, 'stderr' => $stderr); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Printer.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Printer.php new file mode 100644 index 00000000..43fb2e3d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Printer.php @@ -0,0 +1,209 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Utility class that can print to STDOUT or write to a file. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + * @abstract + */ +abstract class PHPUnit_Util_Printer +{ + /** + * If TRUE, flush output after every write. + * + * @var boolean + */ + protected $autoFlush = FALSE; + + /** + * @var resource + */ + protected $out; + + /** + * @var string + */ + protected $outTarget; + + /** + * @var boolean + */ + protected $printsHTML = FALSE; + + /** + * Constructor. + * + * @param mixed $out + * @throws InvalidArgumentException + */ + public function __construct($out = NULL) + { + if ($out !== NULL) { + if (is_string($out)) { + if (strpos($out, 'socket://') === 0) { + $out = explode(':', str_replace('socket://', '', $out)); + + if (sizeof($out) != 2) { + throw new InvalidArgumentException; + } + + $this->out = fsockopen($out[0], $out[1]); + } else { + $this->out = fopen($out, 'wt'); + } + + $this->outTarget = $out; + } else { + $this->out = $out; + } + } + } + + /** + * Flush buffer, optionally tidy up HTML, and close output. + */ + public function flush() + { + if ($this->out !== NULL && $this->outTarget !== 'php://stderr') { + fclose($this->out); + } + + if ($this->printsHTML === TRUE && $this->outTarget !== NULL && + strpos($this->outTarget, 'php://') !== 0 && + strpos($this->outTarget, 'socket://') !== 0 && + extension_loaded('tidy')) { + file_put_contents( + $this->outTarget, + tidy_repair_file( + $this->outTarget, array('indent' => TRUE, 'wrap' => 0), 'utf8' + ) + ); + } + } + + /** + * Performs a safe, incremental flush. + * + * Do not confuse this function with the flush() function of this class, + * since the flush() function may close the file being written to, rendering + * the current object no longer usable. + * + * @since Method available since Release 3.3.0 + */ + public function incrementalFlush() + { + if ($this->out !== NULL) { + fflush($this->out); + } else { + flush(); + } + } + + /** + * @param string $buffer + */ + public function write($buffer) + { + if ($this->out !== NULL) { + fwrite($this->out, $buffer); + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } else { + if (PHP_SAPI != 'cli') { + $buffer = htmlspecialchars($buffer); + } + + print $buffer; + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } + } + + /** + * Check auto-flush mode. + * + * @return boolean + * @since Method available since Release 3.3.0 + */ + public function getAutoFlush() + { + return $this->autoFlush; + } + + /** + * Set auto-flushing mode. + * + * If set, *incremental* flushes will be done after each write. This should + * not be confused with the different effects of this class' flush() method. + * + * @param boolean $autoFlush + * @since Method available since Release 3.3.0 + */ + public function setAutoFlush($autoFlush) + { + if (is_bool($autoFlush)) { + $this->autoFlush = $autoFlush; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report.php new file mode 100644 index 00000000..9772d714 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report.php @@ -0,0 +1,250 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/CodeCoverage.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Report/Node/Directory.php'; +require_once 'PHPUnit/Util/Report/Node/File.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + * @abstract + */ +abstract class PHPUnit_Util_Report +{ + public static $templatePath; + + /** + * Renders the report. + * + * @param PHPUnit_Framework_TestResult $result + * @param string $title + * @param string $target + * @param string $charset + * @param boolean $yui + * @param boolean $highlight + * @param integer $lowUpperBound + * @param integer $highLowerBound + */ + public static function render(PHPUnit_Framework_TestResult $result, $target, $title = '', $charset = 'ISO-8859-1', $yui = TRUE, $highlight = FALSE, $lowUpperBound = 35, $highLowerBound = 70) + { + $target = PHPUnit_Util_Filesystem::getDirectory($target); + + self::$templatePath = sprintf( + '%s%sReport%sTemplate%s', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ); + + $codeCoverageInformation = $result->getCodeCoverageInformation(); + $files = PHPUnit_Util_CodeCoverage::getSummary( + $codeCoverageInformation + ); + $commonPath = PHPUnit_Util_Filesystem::reducePaths($files); + $items = self::buildDirectoryStructure($files); + + unset($codeCoverageInformation); + + if ($title == '') { + $topTestSuite = $result->topTestSuite(); + + if ($topTestSuite instanceof PHPUnit_Framework_TestSuite) { + $title = $topTestSuite->getName(); + } + } + + unset($result); + + $root = new PHPUnit_Util_Report_Node_Directory($commonPath, NULL); + + self::addItems($root, $items, $files, $yui, $highlight); + self::copyFiles($target); + + PHPUnit_Util_CodeCoverage::clearSummary(); + + $root->render( + $target, + $title, + $charset, + $lowUpperBound, + $highLowerBound + ); + } + + /** + * @param PHPUnit_Util_Report_Node_Directory $root + * @param array $items + * @param array $files + * @param boolean $yui + * @param boolean $highlight + */ + protected static function addItems(PHPUnit_Util_Report_Node_Directory $root, array $items, array $files, $yui, $highlight) + { + foreach ($items as $key => $value) { + if (substr($key, -2) == '/f') { + try { + $file = $root->addFile( + substr($key, 0, -2), $value, $yui, $highlight + ); + } + + catch (RuntimeException $e) { + continue; + } + } else { + $child = $root->addDirectory($key); + self::addItems($child, $value, $files, $yui, $highlight); + } + } + } + + /** + * Builds an array representation of the directory structure. + * + * For instance, + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is transformed into + * + * + * Array + * ( + * [.] => Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * ) + * + * + * @param array $files + * @return array + */ + protected static function buildDirectoryStructure($files) + { + $result = array(); + + foreach ($files as $path => $file) { + $path = explode('/', $path); + $pointer = &$result; + $max = count($path); + + for ($i = 0; $i < $max; $i++) { + if ($i == ($max - 1)) { + $type = '/f'; + } else { + $type = ''; + } + + $pointer = &$pointer[$path[$i] . $type]; + } + + $pointer = $file; + } + + return $result; + } + + /** + * @param string $target + */ + protected static function copyFiles($target) + { + $files = array( + 'butter.png', + 'chameleon.png', + 'close12_1.gif', + 'container.css', + 'container-min.js', + 'glass.png', + 'scarlet_red.png', + 'snow.png', + 'style.css', + 'yahoo-dom-event.js' + ); + + foreach ($files as $file) { + copy(self::$templatePath . $file, $target . $file); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node.php new file mode 100644 index 00000000..2e8a1645 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node.php @@ -0,0 +1,487 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Test.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Base class for nodes in the code coverage information tree. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +abstract class PHPUnit_Util_Report_Node +{ + /** + * @var array + */ + protected $cache = array(); + + /** + * @var string + */ + protected $name; + + /** + * @var PHPUnit_Util_Report_Node + */ + protected $parent; + + /** + * Constructor. + * + * @param string $name + * @param PHPUnit_Util_Report_Node $parent + */ + public function __construct($name, PHPUnit_Util_Report_Node $parent = NULL) + { + $this->name = $name; + $this->parent = $parent; + } + + /** + * Returns the percentage of classes that has been tested. + * + * @return integer + */ + public function getTestedClassesPercent() + { + return $this->calculatePercent( + $this->getNumTestedClasses(), + $this->getNumClasses() + ); + } + + /** + * Returns the percentage of methods that has been tested. + * + * @return integer + */ + public function getTestedMethodsPercent() + { + return $this->calculatePercent( + $this->getNumTestedMethods(), + $this->getNumMethods() + ); + } + + /** + * Returns the percentage of executed lines. + * + * @return integer + */ + public function getLineExecutedPercent() + { + return $this->calculatePercent( + $this->getNumExecutedLines(), + $this->getNumExecutableLines() + ); + } + + /** + * Returns this node's ID. + * + * @return string + */ + public function getId() + { + if (!isset($this->cache['id'])) { + if ($this->parent === NULL) { + $this->cache['id'] = 'index'; + } else { + $parentId = $this->parent->getId(); + + if ($parentId == 'index') { + $this->cache['id'] = $this->getName(); + } else { + $this->cache['id'] = $parentId . '_' . $this->getName(); + } + } + } + + return $this->cache['id']; + } + + /** + * Returns this node's name. + * + * @param boolean $includeParent + * @return string + */ + public function getName($includeParent = FALSE, $includeCommonPath = FALSE) + { + if ($includeParent && $this->parent !== NULL) { + if (!isset($this->cache['nameIncludingParent'])) { + $parent = $this->parent->getName(TRUE); + $this->cache['nameIncludingParent'] = !empty($parent) ? $parent . '/' . $this->name : $this->name; + } + + return $this->cache['nameIncludingParent']; + } else { + if ($this->parent !== NULL) { + return $this->name; + } else { + return $includeCommonPath ? $this->name : ''; + } + } + } + + /** + * Returns the link to this node. + * + * @param boolean $full + * @return string + */ + public function getLink($full) + { + if (substr($this->name, -1) == DIRECTORY_SEPARATOR) { + $name = substr($this->name, 0, -1); + } else { + $name = $this->name; + } + + $cleanId = PHPUnit_Util_Filesystem::getSafeFilename($this->getId()); + + if ($full) { + if ($this->parent !== NULL) { + $parent = $this->parent->getLink(TRUE) . DIRECTORY_SEPARATOR; + } else { + $parent = ''; + } + + return sprintf( + '%s%s', + $parent, + $cleanId, + $name + ); + } else { + return sprintf( + '%s', + $cleanId, + $name + ); + } + } + + /** + * Returns this node's path. + * + * @return string + */ + public function getPath() + { + if (!isset($this->cache['path'])) { + if ($this->parent === NULL) { + $this->cache['path'] = $this->getName(FALSE, TRUE); + } else { + if (substr($this->parent->getPath(), -1) == DIRECTORY_SEPARATOR) { + $this->cache['path'] = $this->parent->getPath() . + $this->getName(FALSE, TRUE); + } else { + $this->cache['path'] = $this->parent->getPath() . + DIRECTORY_SEPARATOR . + $this->getName(FALSE, TRUE); + + if ($this->parent->getPath() === '' && + realpath($this->cache['path']) === FALSE && + realpath($this->getName(FALSE, TRUE)) !== FALSE) { + $this->cache['path'] = $this->getName(FALSE, TRUE); + } + } + } + } + + return $this->cache['path']; + } + + /** + * Calculates a percentage value. + * + * @param integer $a + * @param integer $b + * @return float ($a / $b) * 100 + */ + protected function calculatePercent($a, $b) + { + if ($b > 0) { + $percent = ($a / $b) * 100; + } else { + $percent = 100; + } + + return sprintf( + '%01.2F', + $percent + ); + } + + protected function doRenderItemObject(PHPUnit_Util_Report_Node $item, $lowUpperBound, $highLowerBound, $link = NULL, $itemClass = 'coverItem') + { + return $this->doRenderItem( + array( + 'name' => $link != NULL ? $link : $item->getLink(FALSE), + 'itemClass' => $itemClass, + 'numClasses' => $item->getNumClasses(), + 'numTestedClasses' => $item->getNumTestedClasses(), + 'testedClassesPercent' => $item->getTestedClassesPercent(), + 'numMethods' => $item->getNumMethods(), + 'numTestedMethods' => $item->getNumTestedMethods(), + 'testedMethodsPercent' => $item->getTestedMethodsPercent(), + 'numExecutableLines' => $item->getNumExecutableLines(), + 'numExecutedLines' => $item->getNumExecutedLines(), + 'executedLinesPercent' => $item->getLineExecutedPercent() + ), + $lowUpperBound, + $highLowerBound + ); + } + + protected function doRenderItem(array $data, $lowUpperBound, $highLowerBound, $template = NULL) + { + if ($template === NULL) { + if ($this instanceof PHPUnit_Util_Report_Node_Directory) { + $template = 'directory_item.html'; + } else { + $template = 'file_item.html'; + } + } + + $itemTemplate = new PHPUnit_Util_Template( + PHPUnit_Util_Report::$templatePath . $template + ); + + if ($data['numClasses'] > 0) { + list($classesColor, $classesLevel) = $this->getColorLevel( + $data['testedClassesPercent'], $lowUpperBound, $highLowerBound + ); + + $classesNumber = $data['numTestedClasses'] . ' / ' . $data['numClasses']; + } else { + $classesColor = 'snow'; + $classesLevel = 'None'; + $classesNumber = ' '; + } + + if ($data['numMethods'] > 0) { + list($methodsColor, $methodsLevel) = $this->getColorLevel( + $data['testedMethodsPercent'], $lowUpperBound, $highLowerBound + ); + + $methodsNumber = $data['numTestedMethods'] . ' / ' . $data['numMethods']; + } else { + $methodsColor = 'snow'; + $methodsLevel = 'None'; + $methodsNumber = ' '; + } + + list($linesColor, $linesLevel) = $this->getColorLevel( + $data['executedLinesPercent'], $lowUpperBound, $highLowerBound + ); + + if ($data['name'] == '*') { + $functions = TRUE; + } else { + $functions = FALSE; + } + + $itemTemplate->setVar( + array( + 'name' => $functions ? 'Functions' : $data['name'], + 'itemClass' => isset($data['itemClass']) ? $data['itemClass'] : 'coverItem', + 'classes_color' => $classesColor, + 'classes_level' => $functions ? 'None' : $classesLevel, + 'classes_tested_width' => floor($data['testedClassesPercent']), + 'classes_tested_percent' => !$functions && $data['numClasses'] > 0 ? $data['testedClassesPercent'] . '%' : ' ', + 'classes_not_tested_width' => 100 - floor($data['testedClassesPercent']), + 'classes_number' => $functions ? ' ' : $classesNumber, + 'methods_color' => $methodsColor, + 'methods_level' => $methodsLevel, + 'methods_tested_width' => floor($data['testedMethodsPercent']), + 'methods_tested_percent' => $data['numMethods'] > 0 ? $data['testedMethodsPercent'] . '%' : ' ', + 'methods_not_tested_width' => 100 - floor($data['testedMethodsPercent']), + 'methods_number' => $methodsNumber, + 'lines_color' => $linesColor, + 'lines_level' => $linesLevel, + 'lines_executed_width' => floor($data['executedLinesPercent']), + 'lines_executed_percent' => $data['executedLinesPercent'] . '%', + 'lines_not_executed_width' => 100 - floor($data['executedLinesPercent']), + 'num_executable_lines' => $data['numExecutableLines'], + 'num_executed_lines' => $data['numExecutedLines'] + ) + ); + + return $itemTemplate->render(); + } + + protected function getColorLevel($percent, $lowUpperBound, $highLowerBound) + { + $floorPercent = floor($percent); + + if ($floorPercent < $lowUpperBound) { + $color = 'scarlet_red'; + $level = 'Lo'; + } + + else if ($floorPercent >= $lowUpperBound && + $floorPercent < $highLowerBound) { + $color = 'butter'; + $level = 'Med'; + } + + else { + $color = 'chameleon'; + $level = 'Hi'; + } + + return array($color, $level); + } + + protected function renderTotalItem($lowUpperBound, $highLowerBound, $directory = TRUE) + { + if ($directory && empty($this->directories) && count($this->files) == 1) { + return ''; + } + + return $this->doRenderItemObject($this, $lowUpperBound, $highLowerBound, 'Total') . + " \n" . + '  ' . "\n" . + " \n"; + } + + /** + * @param PHPUnit_Util_Template $template + * @param string $title + * @param string $charset + */ + protected function setTemplateVars(PHPUnit_Util_Template $template, $title, $charset) + { + $template->setVar( + array( + 'title' => $title, + 'charset' => $charset, + 'link' => $this->getLink(TRUE), + 'num_executable_lines' => $this->getNumExecutableLines(), + 'num_executed_lines' => $this->getNumExecutedLines(), + 'lines_executed_percent' => $this->getLineExecutedPercent(), + 'date' => $template->getDate(), + 'phpunit_version' => PHPUnit_Runner_Version::id(), + 'xdebug_version' => phpversion('xdebug'), + 'php_version' => PHP_VERSION + ) + ); + } + + /** + * Returns the classes of this node. + * + * @return array + */ + abstract public function getClasses(); + + /** + * Returns the number of executable lines. + * + * @return integer + */ + abstract public function getNumExecutableLines(); + + /** + * Returns the number of executed lines. + * + * @return integer + */ + abstract public function getNumExecutedLines(); + + /** + * Returns the number of classes. + * + * @return integer + */ + abstract public function getNumClasses(); + + /** + * Returns the number of tested classes. + * + * @return integer + */ + abstract public function getNumTestedClasses(); + + /** + * Returns the number of methods. + * + * @return integer + */ + abstract public function getNumMethods(); + + /** + * Returns the number of tested methods. + * + * @return integer + */ + abstract public function getNumTestedMethods(); + + /** + * Renders this node. + * + * @param string $target + * @param string $title + * @param string $charset + * @param integer $lowUpperBound + * @param integer $highLowerBound + */ + abstract public function render($target, $title, $charset = 'ISO-8859-1', $lowUpperBound = 35, $highLowerBound = 70); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node/Directory.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node/Directory.php new file mode 100644 index 00000000..6d76f0d4 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node/Directory.php @@ -0,0 +1,392 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Template.php'; +require_once 'PHPUnit/Util/Report/Node.php'; +require_once 'PHPUnit/Util/Report/Node/File.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Represents a directory in the code coverage information tree. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Report_Node_Directory extends PHPUnit_Util_Report_Node +{ + /** + * @var PHPUnit_Util_Report_Node[] + */ + protected $children = array(); + + /** + * @var PHPUnit_Util_Report_Node_Directory[] + */ + protected $directories = array(); + + /** + * @var PHPUnit_Util_Report_Node_File[] + */ + protected $files = array(); + + /** + * @var array + */ + protected $classes; + + /** + * @var integer + */ + protected $numExecutableLines = -1; + + /** + * @var integer + */ + protected $numExecutedLines = -1; + + /** + * @var integer + */ + protected $numClasses = -1; + + /** + * @var integer + */ + protected $numTestedClasses = -1; + + /** + * @var integer + */ + protected $numMethods = -1; + + /** + * @var integer + */ + protected $numTestedMethods = -1; + + /** + * Adds a new directory. + * + * @return PHPUnit_Util_Report_Node_Directory + */ + public function addDirectory($name) + { + $directory = new PHPUnit_Util_Report_Node_Directory($name, $this); + + $this->children[] = $directory; + $this->directories[] = &$this->children[count($this->children) - 1]; + + return $directory; + } + + /** + * Adds a new file. + * + * @param string $name + * @param array $lines + * @param boolean $yui + * @param boolean $highlight + * @return PHPUnit_Util_Report_Node_File + * @throws RuntimeException + */ + public function addFile($name, array $lines, $yui, $highlight) + { + $file = new PHPUnit_Util_Report_Node_File( + $name, $this, $lines, $yui, $highlight + ); + + $this->children[] = $file; + $this->files[] = &$this->children[count($this->children) - 1]; + + $this->numExecutableLines = -1; + $this->numExecutedLines = -1; + + return $file; + } + + /** + * Returns the directories in this directory. + * + * @return array + */ + public function getDirectories() + { + return $this->directories; + } + + /** + * Returns the files in this directory. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * Returns the classes of this node. + * + * @return array + */ + public function getClasses() + { + if ($this->classes === NULL) { + $this->classes = array(); + + foreach ($this->children as $child) { + $this->classes = array_merge($this->classes, $child->getClasses()); + } + } + + return $this->classes; + } + + /** + * Returns the number of executable lines. + * + * @return integer + */ + public function getNumExecutableLines() + { + if ($this->numExecutableLines == -1) { + $this->numExecutableLines = 0; + + foreach ($this->children as $child) { + $this->numExecutableLines += $child->getNumExecutableLines(); + } + } + + return $this->numExecutableLines; + } + + /** + * Returns the number of executed lines. + * + * @return integer + */ + public function getNumExecutedLines() + { + if ($this->numExecutedLines == -1) { + $this->numExecutedLines = 0; + + foreach ($this->children as $child) { + $this->numExecutedLines += $child->getNumExecutedLines(); + } + } + + return $this->numExecutedLines; + } + + /** + * Returns the number of classes. + * + * @return integer + */ + public function getNumClasses() + { + if ($this->numClasses == -1) { + $this->numClasses = 0; + + foreach ($this->children as $child) { + $this->numClasses += $child->getNumClasses(); + } + } + + return $this->numClasses; + } + + /** + * Returns the number of tested classes. + * + * @return integer + */ + public function getNumTestedClasses() + { + if ($this->numTestedClasses == -1) { + $this->numTestedClasses = 0; + + foreach ($this->children as $child) { + $this->numTestedClasses += $child->getNumTestedClasses(); + } + } + + return $this->numTestedClasses; + } + + /** + * Returns the number of methods. + * + * @return integer + */ + public function getNumMethods() + { + if ($this->numMethods == -1) { + $this->numMethods = 0; + + foreach ($this->children as $child) { + $this->numMethods += $child->getNumMethods(); + } + } + + return $this->numMethods; + } + + /** + * Returns the number of tested methods. + * + * @return integer + */ + public function getNumTestedMethods() + { + if ($this->numTestedMethods == -1) { + $this->numTestedMethods = 0; + + foreach ($this->children as $child) { + $this->numTestedMethods += $child->getNumTestedMethods(); + } + } + + return $this->numTestedMethods; + } + + /** + * Renders this node. + * + * @param string $target + * @param string $title + * @param string $charset + * @param integer $lowUpperBound + * @param integer $highLowerBound + */ + public function render($target, $title, $charset = 'ISO-8859-1', $lowUpperBound = 35, $highLowerBound = 70) + { + $this->doRender( + $target, $title, $charset, $lowUpperBound, $highLowerBound + ); + + foreach ($this->children as $child) { + $child->render( + $target, $title, $charset, $lowUpperBound, $highLowerBound + ); + } + + $this->children = array(); + } + + /** + * @param string $target + * @param string $title + * @param string $charset + * @param integer $lowUpperBound + * @param integer $highLowerBound + */ + protected function doRender($target, $title, $charset, $lowUpperBound, $highLowerBound) + { + $cleanId = PHPUnit_Util_Filesystem::getSafeFilename($this->getId()); + $file = $target . $cleanId . '.html'; + + $template = new PHPUnit_Util_Template( + PHPUnit_Util_Report::$templatePath . 'directory.html' + ); + + $this->setTemplateVars($template, $title, $charset); + + $template->setVar( + array( + 'total_item' => $this->renderTotalItem($lowUpperBound, $highLowerBound), + 'items' => $this->renderItems($lowUpperBound, $highLowerBound), + 'low_upper_bound' => $lowUpperBound, + 'high_lower_bound' => $highLowerBound + ) + ); + + $template->renderTo($file); + + $this->directories = array(); + $this->files = array(); + } + + /** + * @param float $lowUpperBound + * @param float $highLowerBound + * @return string + */ + protected function renderItems($lowUpperBound, $highLowerBound) + { + $items = $this->doRenderItems($this->directories, $lowUpperBound, $highLowerBound, 'coverDirectory'); + $items .= $this->doRenderItems($this->files, $lowUpperBound, $highLowerBound, 'coverFile'); + + return $items; + } + + /** + * @param array $items + * @param float $lowUpperBound + * @param float $highLowerBound + * @param string $itemClass + * @return string + */ + protected function doRenderItems(array $items, $lowUpperBound, $highLowerBound, $itemClass) + { + $result = ''; + + foreach ($items as $item) { + $result .= $this->doRenderItemObject($item, $lowUpperBound, $highLowerBound, NULL, $itemClass); + } + + return $result; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node/File.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node/File.php new file mode 100644 index 00000000..5e69d295 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Node/File.php @@ -0,0 +1,860 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/File.php'; +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Template.php'; +require_once 'PHPUnit/Util/Report/Node.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Report_Node_File extends PHPUnit_Util_Report_Node +{ + /** + * @var array + */ + protected $codeLines; + + /** + * @var array + */ + protected $codeLinesFillup = array(); + + /** + * @var array + */ + protected $executedLines; + + /** + * @var boolean + */ + protected $yui = TRUE; + + /** + * @var boolean + */ + protected $highlight = FALSE; + + /** + * @var integer + */ + protected $numExecutableLines = 0; + + /** + * @var integer + */ + protected $numExecutedLines = 0; + + /** + * @var array + */ + protected $classes = array(); + + /** + * @var integer + */ + protected $numClasses = 0; + + /** + * @var integer + */ + protected $numTestedClasses = 0; + + /** + * @var integer + */ + protected $numMethods = 0; + + /** + * @var integer + */ + protected $numTestedMethods = 0; + + /** + * @var string + */ + protected $yuiPanelJS = ''; + + /** + * @var array + */ + protected $startLines = array(); + + /** + * @var array + */ + protected $endLines = array(); + + /** + * Constructor. + * + * @param string $name + * @param PHPUnit_Util_Report_Node $parent + * @param array $executedLines + * @param boolean $yui + * @param boolean $highlight + * @throws RuntimeException + */ + public function __construct($name, PHPUnit_Util_Report_Node $parent = NULL, array $executedLines, $yui = TRUE, $highlight = FALSE) + { + parent::__construct($name, $parent); + + $path = $this->getPath(); + + if (!file_exists($path)) { + throw new PHPUnit_Framework_Exception( + sprintf('Path "%s" does not exist.', $path) + ); + } + + $this->executedLines = $executedLines; + $this->highlight = $highlight; + $this->yui = $yui; + $this->codeLines = $this->loadFile($path); + + $this->calculateStatistics(); + } + + /** + * Returns the classes of this node. + * + * @return array + */ + public function getClasses() + { + return $this->classes; + } + + /** + * Returns the number of executable lines. + * + * @return integer + */ + public function getNumExecutableLines() + { + return $this->numExecutableLines; + } + + /** + * Returns the number of executed lines. + * + * @return integer + */ + public function getNumExecutedLines() + { + return $this->numExecutedLines; + } + + /** + * Returns the number of classes. + * + * @return integer + */ + public function getNumClasses() + { + return $this->numClasses; + } + + /** + * Returns the number of tested classes. + * + * @return integer + */ + public function getNumTestedClasses() + { + return $this->numTestedClasses; + } + + /** + * Returns the number of methods. + * + * @return integer + */ + public function getNumMethods() + { + return $this->numMethods; + } + + /** + * Returns the number of tested methods. + * + * @return integer + */ + public function getNumTestedMethods() + { + return $this->numTestedMethods; + } + + /** + * Renders this node. + * + * @param string $target + * @param string $title + * @param string $charset + * @param integer $lowUpperBound + * @param integer $highLowerBound + */ + public function render($target, $title, $charset = 'ISO-8859-1', $lowUpperBound = 35, $highLowerBound = 70) + { + if ($this->yui) { + $template = new PHPUnit_Util_Template( + PHPUnit_Util_Report::$templatePath . 'file.html' + ); + + $yuiTemplate = new PHPUnit_Util_Template( + PHPUnit_Util_Report::$templatePath . 'yui_item.js' + ); + } else { + $template = new PHPUnit_Util_Template( + PHPUnit_Util_Report::$templatePath . 'file_no_yui.html' + ); + } + + $i = 1; + $lines = ''; + $ignore = FALSE; + + foreach ($this->codeLines as $line) { + if (strpos($line, '@codeCoverageIgnoreStart') !== FALSE) { + $ignore = TRUE; + } + + else if (strpos($line, '@codeCoverageIgnoreEnd') !== FALSE) { + $ignore = FALSE; + } + + $css = ''; + + if (!$ignore && isset($this->executedLines[$i])) { + $count = ''; + + // Array: Line is executable and was executed. + // count(Array) = Number of tests that hit this line. + if (is_array($this->executedLines[$i])) { + $color = 'lineCov'; + $numTests = count($this->executedLines[$i]); + $count = sprintf('%8d', $numTests); + + if ($this->yui) { + $buffer = ''; + $testCSS = ''; + + foreach ($this->executedLines[$i] as $test) { + if (!isset($test->__liHtml)) { + $test->__liHtml = ''; + + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + $testName = $test->toString(); + + if ($test instanceof PHPUnit_Framework_TestCase) { + switch ($test->getStatus()) { + case PHPUnit_Runner_BaseTestRunner::STATUS_PASSED: { + $testCSS = ' class=\"testPassed\"'; + } + break; + + case PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE: { + $testCSS = ' class=\"testFailure\"'; + } + break; + + case PHPUnit_Runner_BaseTestRunner::STATUS_ERROR: { + $testCSS = ' class=\"testError\"'; + } + break; + + case PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE: + case PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED: { + $testCSS = ' class=\"testIncomplete\"'; + } + break; + + default: { + $testCSS = ''; + } + } + } + } + + $test->__liHtml .= sprintf( + '%s', + + $testCSS, + addslashes(htmlspecialchars($testName)) + ); + } + + $buffer .= $test->__liHtml; + } + + if ($numTests > 1) { + $header = $numTests . ' tests cover'; + } else { + $header = '1 test covers'; + } + + $header .= ' line ' . $i; + + $yuiTemplate->setVar( + array( + 'line' => $i, + 'header' => $header, + 'tests' => $buffer + ), + FALSE + ); + + $this->yuiPanelJS .= $yuiTemplate->render(); + } + } + + // -1: Line is executable and was not executed. + else if ($this->executedLines[$i] == -1) { + $color = 'lineNoCov'; + $count = sprintf('%8d', 0); + } + + // -2: Line is dead code. + else { + $color = 'lineDeadCode'; + $count = ' '; + } + + $css = sprintf( + ' %s : ', + + $color, + $count + ); + } + + $fillup = array_shift($this->codeLinesFillup); + + if ($fillup > 0) { + $line .= str_repeat(' ', $fillup); + } + + $lines .= sprintf( + '%8d %s%s%s' . "\n", + + $i, + $i, + $i, + $i, + $i, + !empty($css) ? $css : ' : ', + !$this->highlight ? htmlspecialchars($line) : $line, + !empty($css) ? '' : '' + ); + + $i++; + } + + $items = ''; + + foreach ($this->classes as $className => $classData) { + if ($classData['executedLines'] == $classData['executableLines']) { + $numTestedClasses = 1; + $testedClassesPercent = 100; + } else { + $numTestedClasses = 0; + $testedClassesPercent = 0; + } + + $numTestedMethods = 0; + $numMethods = count($classData['methods']); + + foreach ($classData['methods'] as $method) { + if ($method['executedLines'] == $method['executableLines']) { + $numTestedMethods++; + } + } + + $items .= $this->doRenderItem( + array( + 'name' => sprintf( + '%s', + + $classData['startLine'], + $className + ), + 'numClasses' => 1, + 'numTestedClasses' => $numTestedClasses, + 'testedClassesPercent' => sprintf('%01.2f', $testedClassesPercent), + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'testedMethodsPercent' => $this->calculatePercent( + $numTestedMethods, $numMethods + ), + 'numExecutableLines' => $classData['executableLines'], + 'numExecutedLines' => $classData['executedLines'], + 'executedLinesPercent' => $this->calculatePercent( + $classData['executedLines'], $classData['executableLines'] + ) + ), + $lowUpperBound, + $highLowerBound + ); + + foreach ($classData['methods'] as $methodName => $methodData) { + if ($methodData['executedLines'] == $methodData['executableLines']) { + $numTestedMethods = 1; + $testedMethodsPercent = 100; + } else { + $numTestedMethods = 0; + $testedMethodsPercent = 0; + } + + $items .= $this->doRenderItem( + array( + 'name' => sprintf( + ' %s', + + $methodData['startLine'], + $methodData['signature'] + ), + 'numClasses' => '', + 'numTestedClasses' => '', + 'testedClassesPercent' => '', + 'numMethods' => 1, + 'numTestedMethods' => $numTestedMethods, + 'testedMethodsPercent' => sprintf('%01.2f', $testedMethodsPercent), + 'numExecutableLines' => $methodData['executableLines'], + 'numExecutedLines' => $methodData['executedLines'], + 'executedLinesPercent' => $this->calculatePercent( + $methodData['executedLines'], $methodData['executableLines'] + ) + ), + $lowUpperBound, + $highLowerBound, + 'method_item.html' + ); + } + } + + $this->setTemplateVars($template, $title, $charset); + + $template->setVar( + array( + 'lines' => $lines, + 'total_item' => $this->renderTotalItem($lowUpperBound, $highLowerBound, FALSE), + 'items' => $items, + 'yuiPanelJS' => $this->yuiPanelJS + ) + ); + + $cleanId = PHPUnit_Util_Filesystem::getSafeFilename($this->getId()); + $template->renderTo($target . $cleanId . '.html'); + + $this->yuiPanelJS = ''; + $this->executedLines = array(); + } + + /** + * Calculates coverage statistics for the file. + * + */ + protected function calculateStatistics() + { + $this->processClasses(); + $this->processFunctions(); + + $ignoreStart = -1; + $lineNumber = 1; + + foreach ($this->codeLines as $line) { + if (isset($this->startLines[$lineNumber])) { + // Start line of a class. + if (isset($this->startLines[$lineNumber]['methods'])) { + $currentClass = &$this->startLines[$lineNumber]; + } + + // Start line of a method. + else { + $currentMethod = &$this->startLines[$lineNumber]; + } + } + + if (strpos($line, '@codeCoverageIgnore') !== FALSE) { + if (strpos($line, '@codeCoverageIgnoreStart') !== FALSE) { + $ignoreStart = $lineNumber; + } + + else if (strpos($line, '@codeCoverageIgnoreEnd') !== FALSE) { + $ignoreStart = -1; + } + } + + if (isset($this->executedLines[$lineNumber])) { + // Array: Line is executable and was executed. + if (is_array($this->executedLines[$lineNumber])) { + if (isset($currentClass)) { + $currentClass['executableLines']++; + $currentClass['executedLines']++; + } + + if (isset($currentMethod)) { + $currentMethod['executableLines']++; + $currentMethod['executedLines']++; + } + + $this->numExecutableLines++; + $this->numExecutedLines++; + } + + // -1: Line is executable and was not executed. + else if ($this->executedLines[$lineNumber] == -1) { + if (isset($currentClass)) { + $currentClass['executableLines']++; + } + + if (isset($currentMethod)) { + $currentMethod['executableLines']++; + } + + $this->numExecutableLines++; + + if ($ignoreStart != -1 && $lineNumber > $ignoreStart) { + if (isset($currentClass)) { + $currentClass['executedLines']++; + } + + if (isset($currentMethod)) { + $currentMethod['executedLines']++; + } + + $this->numExecutedLines++; + } + } + } + + if (isset($this->endLines[$lineNumber])) { + // End line of a class. + if (isset($this->endLines[$lineNumber]['methods'])) { + unset($currentClass); + } + + // End line of a method. + else { + unset($currentMethod); + } + } + + $lineNumber++; + } + + foreach ($this->classes as $className => $class) { + foreach ($class['methods'] as $method) { + if ($method['executedLines'] == $method['executableLines']) { + $this->numTestedMethods++; + } + } + + if ($className != '*') { + if ($class['executedLines'] == $class['executableLines']) { + $this->numTestedClasses++; + } + } + } + } + + /** + * @author Aidan Lister + * @author Sebastian Bergmann + * @param string $file + * @return array + */ + protected function loadFile($file) + { + $lines = explode("\n", str_replace("\t", ' ', file_get_contents($file))); + $result = array(); + + if (count($lines) == 0) { + return $result; + } + + $lines = array_map('rtrim', $lines); + $linesLength = array_map('strlen', $lines); + $width = max($linesLength); + + foreach ($linesLength as $line => $length) { + $this->codeLinesFillup[$line] = $width - $length; + } + + if (!$this->highlight) { + unset($lines[count($lines)-1]); + return $lines; + } + + $tokens = token_get_all(file_get_contents($file)); + $stringFlag = FALSE; + $i = 0; + $result[$i] = ''; + + foreach ($tokens as $j => $token) { + if (is_string($token)) { + if ($token === '"' && $tokens[$j - 1] !== '\\') { + $result[$i] .= sprintf( + '%s', + + htmlspecialchars($token) + ); + + $stringFlag = !$stringFlag; + } else { + $result[$i] .= sprintf( + '%s', + + htmlspecialchars($token) + ); + } + + continue; + } + + list ($token, $value) = $token; + + $value = str_replace( + array("\t", ' '), + array('    ', ' '), + htmlspecialchars($value) + ); + + if ($value === "\n") { + $result[++$i] = ''; + } else { + $lines = explode("\n", $value); + + foreach ($lines as $jj => $line) { + $line = trim($line); + + if ($line !== '') { + if ($stringFlag) { + $colour = 'string'; + } else { + switch ($token) { + case T_INLINE_HTML: { + $colour = 'html'; + } + break; + + case T_COMMENT: + case T_DOC_COMMENT: { + $colour = 'comment'; + } + break; + + case T_ABSTRACT: + case T_ARRAY: + case T_ARRAY_CAST: + case T_AS: + case T_BOOLEAN_AND: + case T_BOOLEAN_OR: + case T_BOOL_CAST: + case T_BREAK: + case T_CASE: + case T_CATCH: + case T_CLASS: + case T_CLONE: + case T_CONCAT_EQUAL: + case T_CONTINUE: + case T_DEFAULT: + case T_DOUBLE_ARROW: + case T_DOUBLE_CAST: + case T_ECHO: + case T_ELSE: + case T_ELSEIF: + case T_EMPTY: + case T_ENDDECLARE: + case T_ENDFOR: + case T_ENDFOREACH: + case T_ENDIF: + case T_ENDSWITCH: + case T_ENDWHILE: + case T_END_HEREDOC: + case T_EXIT: + case T_EXTENDS: + case T_FINAL: + case T_FOREACH: + case T_FUNCTION: + case T_GLOBAL: + case T_IF: + case T_INC: + case T_INCLUDE: + case T_INCLUDE_ONCE: + case T_INSTANCEOF: + case T_INT_CAST: + case T_ISSET: + case T_IS_EQUAL: + case T_IS_IDENTICAL: + case T_IS_NOT_IDENTICAL: + case T_IS_SMALLER_OR_EQUAL: + case T_NEW: + case T_OBJECT_CAST: + case T_OBJECT_OPERATOR: + case T_PAAMAYIM_NEKUDOTAYIM: + case T_PRIVATE: + case T_PROTECTED: + case T_PUBLIC: + case T_REQUIRE: + case T_REQUIRE_ONCE: + case T_RETURN: + case T_SL: + case T_SL_EQUAL: + case T_SR: + case T_SR_EQUAL: + case T_START_HEREDOC: + case T_STATIC: + case T_STRING_CAST: + case T_THROW: + case T_TRY: + case T_UNSET_CAST: + case T_VAR: + case T_WHILE: { + $colour = 'keyword'; + } + break; + + default: { + $colour = 'default'; + } + } + } + + $result[$i] .= sprintf( + '%s', + + $colour, + $line + ); + } + + if (isset($lines[$jj + 1])) { + $result[++$i] = ''; + } + } + } + } + + unset($result[count($result)-1]); + + return $result; + } + + protected function processClasses() + { + $classes = PHPUnit_Util_File::getClassesInFile($this->getPath()); + + foreach ($classes as $className => $class) { + $this->classes[$className] = array( + 'methods' => array(), + 'startLine' => $class['startLine'], + 'executableLines' => 0, + 'executedLines' => 0 + ); + + $this->startLines[$class['startLine']] = &$this->classes[$className]; + $this->endLines[$class['endLine']] = &$this->classes[$className]; + + foreach ($class['methods'] as $methodName => $method) { + $this->classes[$className]['methods'][$methodName] = array( + 'signature' => $method['signature'], + 'startLine' => $method['startLine'], + 'executableLines' => 0, + 'executedLines' => 0 + ); + + $this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName]; + $this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName]; + + $this->numMethods++; + } + + $this->numClasses++; + } + } + + protected function processFunctions() + { + $functions = PHPUnit_Util_File::getFunctionsInFile($this->getPath()); + + if (count($functions) > 0 && !isset($this->classes['*'])) { + $this->classes['*'] = array( + 'methods' => array(), + 'startLine' => 0, + 'executableLines' => 0, + 'executedLines' => 0 + ); + } + + foreach ($functions as $functionName => $function) { + $this->classes['*']['methods'][$functionName] = array( + 'signature' => $function['signature'], + 'startLine' => $function['startLine'], + 'executableLines' => 0, + 'executedLines' => 0 + ); + + $this->startLines[$function['startLine']] = &$this->classes['*']['methods'][$functionName]; + $this->endLines[$function['endLine']] = &$this->classes['*']['methods'][$functionName]; + + $this->numMethods++; + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/butter.png b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/butter.png new file mode 100644 index 00000000..3c7e36f2 Binary files /dev/null and b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/butter.png differ diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/chameleon.png b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/chameleon.png new file mode 100644 index 00000000..68046070 Binary files /dev/null and b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/chameleon.png differ diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/close12_1.gif b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/close12_1.gif new file mode 100644 index 00000000..e2f67d72 Binary files /dev/null and b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/close12_1.gif differ diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/container-min.js b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/container-min.js new file mode 100644 index 00000000..d36255e2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/container-min.js @@ -0,0 +1,19 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.8.0r4 +*/ +(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.value);}},getConfig:function(){var D={},F=this.config,G,E;for(G in F){if(B.hasOwnProperty(F,G)){E=F[G];if(E&&E.event){D[G]=E.value;}}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.value=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0;L0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Module=function(R,Q){if(R){this.init(R,Q);}else{}};var F=YAHOO.util.Dom,D=YAHOO.util.Config,N=YAHOO.util.Event,M=YAHOO.util.CustomEvent,G=YAHOO.widget.Module,I=YAHOO.env.ua,H,P,O,E,A={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTROY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"},J={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true},"APPEND_TO_DOCUMENT_BODY":{key:"appendtodocumentbody",value:false}};G.IMG_ROOT=null;G.IMG_ROOT_SSL=null;G.CSS_MODULE="yui-module";G.CSS_HEADER="hd";G.CSS_BODY="bd";G.CSS_FOOTER="ft";G.RESIZE_MONITOR_SECURE_URL="javascript:false;";G.RESIZE_MONITOR_BUFFER=1;G.textResizeEvent=new M("textResize");G.forceDocumentRedraw=function(){var Q=document.documentElement;if(Q){Q.className+=" ";Q.className=YAHOO.lang.trim(Q.className);}};function L(){if(!H){H=document.createElement("div");H.innerHTML=('
'+'
');P=H.firstChild;O=P.nextSibling;E=O.nextSibling;}return H;}function K(){if(!P){L();}return(P.cloneNode(false));}function B(){if(!O){L();}return(O.cloneNode(false));}function C(){if(!E){L();}return(E.cloneNode(false));}G.prototype={constructor:G,element:null,header:null,body:null,footer:null,id:null,imageRoot:G.IMG_ROOT,initEvents:function(){var Q=M.LIST; +this.beforeInitEvent=this.createEvent(A.BEFORE_INIT);this.beforeInitEvent.signature=Q;this.initEvent=this.createEvent(A.INIT);this.initEvent.signature=Q;this.appendEvent=this.createEvent(A.APPEND);this.appendEvent.signature=Q;this.beforeRenderEvent=this.createEvent(A.BEFORE_RENDER);this.beforeRenderEvent.signature=Q;this.renderEvent=this.createEvent(A.RENDER);this.renderEvent.signature=Q;this.changeHeaderEvent=this.createEvent(A.CHANGE_HEADER);this.changeHeaderEvent.signature=Q;this.changeBodyEvent=this.createEvent(A.CHANGE_BODY);this.changeBodyEvent.signature=Q;this.changeFooterEvent=this.createEvent(A.CHANGE_FOOTER);this.changeFooterEvent.signature=Q;this.changeContentEvent=this.createEvent(A.CHANGE_CONTENT);this.changeContentEvent.signature=Q;this.destroyEvent=this.createEvent(A.DESTROY);this.destroyEvent.signature=Q;this.beforeShowEvent=this.createEvent(A.BEFORE_SHOW);this.beforeShowEvent.signature=Q;this.showEvent=this.createEvent(A.SHOW);this.showEvent.signature=Q;this.beforeHideEvent=this.createEvent(A.BEFORE_HIDE);this.beforeHideEvent.signature=Q;this.hideEvent=this.createEvent(A.HIDE);this.hideEvent.signature=Q;},platform:function(){var Q=navigator.userAgent.toLowerCase();if(Q.indexOf("windows")!=-1||Q.indexOf("win32")!=-1){return"windows";}else{if(Q.indexOf("macintosh")!=-1){return"mac";}else{return false;}}}(),browser:function(){var Q=navigator.userAgent.toLowerCase();if(Q.indexOf("opera")!=-1){return"opera";}else{if(Q.indexOf("msie 7")!=-1){return"ie7";}else{if(Q.indexOf("msie")!=-1){return"ie";}else{if(Q.indexOf("safari")!=-1){return"safari";}else{if(Q.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty(J.VISIBLE.key,{handler:this.configVisible,value:J.VISIBLE.value,validator:J.VISIBLE.validator});this.cfg.addProperty(J.EFFECT.key,{suppressEvent:J.EFFECT.suppressEvent,supercedes:J.EFFECT.supercedes});this.cfg.addProperty(J.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:J.MONITOR_RESIZE.value});this.cfg.addProperty(J.APPEND_TO_DOCUMENT_BODY.key,{value:J.APPEND_TO_DOCUMENT_BODY.value});},init:function(V,U){var S,W;this.initEvents();this.beforeInitEvent.fire(G);this.cfg=new D(this);if(this.isSecure){this.imageRoot=G.IMG_ROOT_SSL;}if(typeof V=="string"){S=V;V=document.getElementById(V);if(!V){V=(L()).cloneNode(false);V.id=S;}}this.id=F.generateId(V);this.element=V;W=this.element.firstChild;if(W){var R=false,Q=false,T=false;do{if(1==W.nodeType){if(!R&&F.hasClass(W,G.CSS_HEADER)){this.header=W;R=true;}else{if(!Q&&F.hasClass(W,G.CSS_BODY)){this.body=W;Q=true;}else{if(!T&&F.hasClass(W,G.CSS_FOOTER)){this.footer=W;T=true;}}}}}while((W=W.nextSibling));}this.initDefaultConfig();F.addClass(this.element,G.CSS_MODULE);if(U){this.cfg.applyConfig(U,true);}if(!D.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}this.initEvent.fire(G);},initResizeMonitor:function(){var R=(I.gecko&&this.platform=="windows");if(R){var Q=this;setTimeout(function(){Q._initResizeMonitor();},0);}else{this._initResizeMonitor();}},_initResizeMonitor:function(){var Q,S,U;function W(){G.textResizeEvent.fire();}if(!I.opera){S=F.get("_yuiResizeMonitor");var V=this._supportsCWResize();if(!S){S=document.createElement("iframe");if(this.isSecure&&G.RESIZE_MONITOR_SECURE_URL&&I.ie){S.src=G.RESIZE_MONITOR_SECURE_URL;}if(!V){U=[" + + + + + + + + + + + + + + + +
{title}
+ + + + + + + + + +
Current file:{link}
Legend: + executed + not executed + dead code +
+
+ +
+ +
+ + + + + + + + + + + +{total_item}{items} +
 Coverage
 ClassesFunctions / MethodsLines
+
+ +
+ + + + + + + + +

+
+{lines}
+
+
+ + + + +
Generated by PHPUnit {phpunit_version} and Xdebug {xdebug_version} using PHP {php_version} at {date}.
+ +
+ + + + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/file_item.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/file_item.html.dist new file mode 100644 index 00000000..9b78f14c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/file_item.html.dist @@ -0,0 +1,31 @@ + + {name} + + + + + +
{classes_tested_percent}{classes_tested_percent}
+ + {classes_tested_percent} + {classes_number} + + + + + +
{methods_tested_percent}{methods_tested_percent}
+ + {methods_tested_percent} + {methods_number} + + + + + +
{lines_executed_percent}{lines_executed_percent}
+ + {lines_executed_percent} + {num_executed_lines} / {num_executable_lines} + + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/file_no_yui.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/file_no_yui.html.dist new file mode 100644 index 00000000..4c12e384 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/file_no_yui.html.dist @@ -0,0 +1,79 @@ + + + + + + {title} + + + + + + + + + + + + + + + +
{title}
+ + + + + + + + + +
Current file:{link}
Legend: + executed + not executed + dead code +
+
+ +
+ +
+ + + + + + + + + + + +{total_item}{items} +
 Coverage
 ClassesFunctions / MethodsLines
+
+ +
+ + + + + + + + +

+
+{lines}
+
+
+ + + + +
Generated by PHPUnit {phpunit_version} and Xdebug {xdebug_version} at {date}.
+ +
+ + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/glass.png b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/glass.png new file mode 100644 index 00000000..e1abc006 Binary files /dev/null and b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/glass.png differ diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/method_item.html.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/method_item.html.dist new file mode 100644 index 00000000..ef5624e5 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/method_item.html.dist @@ -0,0 +1,22 @@ + + {name} + + + + + +
{methods_tested_percent}{methods_tested_percent}
+ + {methods_tested_percent} + {methods_number} + + + + + +
{lines_executed_percent}{lines_executed_percent}
+ + {lines_executed_percent} + {num_executed_lines} / {num_executable_lines} + + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/scarlet_red.png b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/scarlet_red.png new file mode 100644 index 00000000..a879424d Binary files /dev/null and b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/scarlet_red.png differ diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/snow.png b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/snow.png new file mode 100644 index 00000000..2cdae107 Binary files /dev/null and b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/snow.png differ diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/style.css b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/style.css new file mode 100644 index 00000000..b7af596d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/style.css @@ -0,0 +1,450 @@ +/* All views: initial background and text color */ +body +{ + background-color: #fff; + color: #2e3436; + font-family: arial, helvetica, sans-serif; + font-size: 12px; + margin: 0 auto; + width: 100%; +} + +/* All views: standard link format*/ +a:link +{ + color: #2e3436; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #2e3436; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #2e3436; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding: 10px; + font-family: sans-serif; + font-style: italic; + font-weight: bold; + font-size: 1.6em; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + font-family: sans-serif; + font-weight: bold; +} + +/* All views: header legend item format */ +td.legendItem +{ + text-align: right; + padding-right: 6px; + padding-top: 10px; + padding-bottom: 2px; + font-family: sans-serif; + font-weight: bold; +} + +/* All views: header legend item value format */ +td.legendValue +{ + text-align: left; + padding-top: 10px; + padding-bottom: 2px; + color: #2e3436; + font-family: sans-serif; + font-weight: bold; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #d3d7cf; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: +table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #555753; + font-family: sans-serif; + font-weight: bold; +} + +/* Directory view/File view (all): filename entry format */ +td.coverItem, td.coverDirectory, td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + background-color: #d3d7cf; + font-family: monospace; +} + +td.coverDirectory +{ + font-weight: bold; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #d3d7cf; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #2e3436; +} + +/* Directory view/File view (all): percentage entry for files with +no coverage rate */ +td.coverPerNone +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #d3d7cf; + font-weight: bold; +} + +/* Directory view/File view (all): line count entry for files with +no coverage rate */ +td.coverNumNone +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #d3d7cf; + white-space: nowrap; +} + +/* Directory view/File view (all): percentage entry for files with +high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #8ae234; + font-weight: bold; +} + +/* Directory view/File view (all): line count entry for files with +high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #8ae234; + white-space: nowrap; +} + +/* Directory view/File view (all): legend entry for high coverage +rate */ +span.coverLegendHi +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + background-color: #8ae234; +} + +/* Directory view/File view (all): percentage entry for files with +medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #fce94f; + font-weight: bold; +} + +/* Directory view/File view (all): line count entry for files with +medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #fce94f; + white-space: nowrap; +} + +/* Directory view/File view (all): legend entry for medium coverage +rate */ +span.coverLegendMed +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + margin-top: 5px; + margin-bottom: 5px; + margin-right: 2px; + background-color: #fce94f; +} + +/* Directory view/File view (all): percentage entry for files with +low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #f57900; + font-weight: bold; +} + +/* Directory view/File view (all): line count entry for files with +low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #f57900; + white-space: nowrap; +} + +/* Directory view/File view (all): legend entry for low coverage +rate */ +span.coverLegendLo +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + margin-right: 2px; + background-color: #f57900; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #ffffff; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #ffffff; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; +} + +/* File view (detail): test name table headline format */ +td.testNameHead +{ + text-align: left; + padding-left: 10px; + background-color: #729fcf; + font-family: sans-serif; + font-weight: bold; +} + +/* File view (detail): test lines table headline format */ +td.testLinesHead +{ + text-align: center; + background-color: #729fcf; + font-family: sans-serif; + font-weight: bold; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: left; + padding-left: 10px; + background-color: #729fcf; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + vertical-align: top; + padding-left: 10px; + padding-right: 10px; + background-color: #729fcf; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + vertical-align: top; + padding-left: 10px; + padding-right: 10px; + background-color: #729fcf; + white-space: nowrap; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #729fcf; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #d3d7cf; +} + +span.lineNum a { + text-decoration: none; +} + +/* Source code view: format for lines which were executed */ +span.lineCov +{ + background-color: #8ae234; +} + +/* Source code view: format for Cov legend */ +span.LegendCov +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + margin-right: 2px; + background-color: #8ae234; +} + +/* Source code view: format for lines which were not executed */ +span.lineNoCov +{ + background-color: #f57900; +} + +/* Source code view: format for NoCov legend */ +span.LegendNoCov +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + margin-right: 2px; + background-color: #f57900; +} + +/* Source code view: format for lines which are dead code */ +span.lineDeadCode +{ + background-color: #d3d7cf; +} + +/* Source code view: format for NoCov legend */ +span.LegendDeadCode +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + margin-right: 2px; + background-color: #d3d7cf; +} + +/* Test view: format for tests which have passed */ +li.testPassed +{ +} + +/* Test view: format for tests which failed */ +li.testFailure +{ + background-color: #f57900; +} + +/* Test view: format for tests which failed with an error */ +li.testError +{ + background-color: #f57900; +} + +/* Test view: format for incomplete and skipped tests */ +li.testIncomplete +{ + background-color: #fcaf3e; +} + +pre span.comment { + color: #888a85; +} + +pre span.default { + color: #2e3436; +} + +pre span.html { + color: #888a85; +} + +pre span.keyword { + color: #2e3436; + font-weight: bold; +} + +pre span.string { + color: #2e3436; +} diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/yahoo-dom-event.js b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/yahoo-dom-event.js new file mode 100644 index 00000000..68586b2a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Report/Template/yahoo-dom-event.js @@ -0,0 +1,14 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.8.0r4 +*/ +if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C0)?B.dump(I[K],N-1):Q);}else{P.push(I[K]);}P.push(O);}if(P.length>1){P.pop();}P.push("]");}else{P.push("{");for(K in I){if(B.hasOwnProperty(I,K)){P.push(K+L);if(B.isObject(I[K])){P.push((N>0)?B.dump(I[K],N-1):Q);}else{P.push(I[K]);}P.push(O);}}if(P.length>1){P.pop();}P.push("}");}return P.join("");},substitute:function(Y,J,R){var N,M,L,U,V,X,T=[],K,O="dump",S=" ",I="{",W="}",Q,P;for(;;){N=Y.lastIndexOf(I);if(N<0){break;}M=Y.indexOf(W,N);if(N+1>=M){break;}K=Y.substring(N+1,M);U=K;X=null;L=U.indexOf(S);if(L>-1){X=U.substring(L+1);U=U.substring(0,L);}V=J[U];if(R){V=R(U,V,X);}if(B.isObject(V)){if(B.isArray(V)){V=B.dump(V,parseInt(X,10));}else{X=X||"";Q=X.indexOf(O);if(Q>-1){X=X.substring(4);}P=V.toString();if(P===G||Q>-1){V=B.dump(V,parseInt(X,10));}else{V=P;}}}else{if(!B.isString(V)&&!B.isNumber(V)){V="~-"+T.length+"-~";T[T.length]=K;}}Y=Y.substring(0,N)+V+Y.substring(M+1);}for(N=T.length-1;N>=0;N=N-1){Y=Y.replace(new RegExp("~-"+N+"-~"),"{"+T[N]+"}","g");}return Y;},trim:function(I){try{return I.replace(/^\s+|\s+$/g,"");}catch(J){return I;}},merge:function(){var L={},J=arguments,I=J.length,K;for(K=0;K519)?true:false);while((G=G[u])){z[0]+=G[b];z[1]+=G[P];if(AC){z=E.Dom._calcBorders(G,z);}}if(E.Dom._getStyle(y,p)!==f){G=y;while((G=G[Z])&&G[C]){AA=G[i];AB=G[O];if(H&&(E.Dom._getStyle(G,"overflow")!=="visible")){z=E.Dom._calcBorders(G,z);}if(AA||AB){z[0]-=AB;z[1]-=AA;}}z[0]+=x;z[1]+=Y;}else{if(D){z[0]-=x;z[1]-=Y;}else{if(I||H){z[0]+=x;z[1]+=Y;}}}z[0]=Math.floor(z[0]);z[1]=Math.floor(z[1]);}else{}return z;};}}(),getX:function(G){var Y=function(x){return E.Dom.getXY(x)[0];};return E.Dom.batch(G,Y,E.Dom,true);},getY:function(G){var Y=function(x){return E.Dom.getXY(x)[1];};return E.Dom.batch(G,Y,E.Dom,true);},setXY:function(G,x,Y){E.Dom.batch(G,E.Dom._setXY,{pos:x,noRetry:Y});},_setXY:function(G,z){var AA=E.Dom._getStyle(G,p),y=E.Dom.setStyle,AD=z.pos,Y=z.noRetry,AB=[parseInt(E.Dom.getComputedStyle(G,j),10),parseInt(E.Dom.getComputedStyle(G,o),10)],AC,x;if(AA=="static"){AA=V;y(G,p,AA);}AC=E.Dom._getXY(G);if(!AD||AC===false){return false;}if(isNaN(AB[0])){AB[0]=(AA==V)?0:G[b];}if(isNaN(AB[1])){AB[1]=(AA==V)?0:G[P];}if(AD[0]!==null){y(G,j,AD[0]-AC[0]+AB[0]+"px");}if(AD[1]!==null){y(G,o,AD[1]-AC[1]+AB[1]+"px");}if(!Y){x=E.Dom._getXY(G);if((AD[0]!==null&&x[0]!=AD[0])||(AD[1]!==null&&x[1]!=AD[1])){E.Dom._setXY(G,{pos:AD,noRetry:true});}}},setX:function(Y,G){E.Dom.setXY(Y,[G,null]);},setY:function(G,Y){E.Dom.setXY(G,[null,Y]);},getRegion:function(G){var Y=function(x){var y=false;if(E.Dom._canPosition(x)){y=E.Region.getRegion(x);}else{}return y;};return E.Dom.batch(G,Y,E.Dom,true);},getClientWidth:function(){return E.Dom.getViewportWidth();},getClientHeight:function(){return E.Dom.getViewportHeight();},getElementsByClassName:function(AB,AF,AC,AE,x,AD){AF=AF||"*";AC=(AC)?E.Dom.get(AC):null||K;if(!AC){return[];}var Y=[],G=AC.getElementsByTagName(AF),z=E.Dom.hasClass;for(var y=0,AA=G.length;y-1;}}else{}return G;},addClass:function(Y,G){return E.Dom.batch(Y,E.Dom._addClass,G);},_addClass:function(x,Y){var G=false,y;if(x&&Y){y=E.Dom._getAttribute(x,F)||J;if(!E.Dom._hasClass(x,Y)){E.Dom.setAttribute(x,F,A(y+B+Y));G=true;}}else{}return G;},removeClass:function(Y,G){return E.Dom.batch(Y,E.Dom._removeClass,G);},_removeClass:function(y,x){var Y=false,AA,z,G;if(y&&x){AA=E.Dom._getAttribute(y,F)||J;E.Dom.setAttribute(y,F,AA.replace(E.Dom._getClassRegex(x),J));z=E.Dom._getAttribute(y,F);if(AA!==z){E.Dom.setAttribute(y,F,A(z));Y=true;if(E.Dom._getAttribute(y,F)===""){G=(y.hasAttribute&&y.hasAttribute(g))?g:F; +y.removeAttribute(G);}}}else{}return Y;},replaceClass:function(x,Y,G){return E.Dom.batch(x,E.Dom._replaceClass,{from:Y,to:G});},_replaceClass:function(y,x){var Y,AB,AA,G=false,z;if(y&&x){AB=x.from;AA=x.to;if(!AA){G=false;}else{if(!AB){G=E.Dom._addClass(y,x.to);}else{if(AB!==AA){z=E.Dom._getAttribute(y,F)||J;Y=(B+z.replace(E.Dom._getClassRegex(AB),B+AA)).split(E.Dom._getClassRegex(AA));Y.splice(1,0,B+AA);E.Dom.setAttribute(y,F,A(Y.join(J)));G=true;}}}}else{}return G;},generateId:function(G,x){x=x||"yui-gen";var Y=function(y){if(y&&y.id){return y.id;}var z=x+YAHOO.env._id_counter++;if(y){if(y[e]&&y[e].getElementById(z)){return E.Dom.generateId(y,z+x);}y.id=z;}return z;};return E.Dom.batch(G,Y,E.Dom,true)||Y.apply(E.Dom,arguments);},isAncestor:function(Y,x){Y=E.Dom.get(Y);x=E.Dom.get(x);var G=false;if((Y&&x)&&(Y[l]&&x[l])){if(Y.contains&&Y!==x){G=Y.contains(x);}else{if(Y.compareDocumentPosition){G=!!(Y.compareDocumentPosition(x)&16);}}}else{}return G;},inDocument:function(G,Y){return E.Dom._inDoc(E.Dom.get(G),Y);},_inDoc:function(Y,x){var G=false;if(Y&&Y[C]){x=x||Y[e];G=E.Dom.isAncestor(x[v],Y);}else{}return G;},getElementsBy:function(Y,AF,AB,AD,y,AC,AE){AF=AF||"*";AB=(AB)?E.Dom.get(AB):null||K;if(!AB){return[];}var x=[],G=AB.getElementsByTagName(AF);for(var z=0,AA=G.length;z=8&&K.documentElement.hasAttribute){E.Dom.DOT_ATTRIBUTES.type=true;}})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this.y=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this.x=B;this[0]=B; +this.width=this.right-this.left;this.height=this.bottom-this.top;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top),D=Math.min(this.right,E.right),A=Math.min(this.bottom,E.bottom),B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototype.union=function(E){var C=Math.min(this.top,E.top),D=Math.max(this.right,E.right),A=Math.max(this.bottom,E.bottom),B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+", height: "+this.height+", width: "+this.width+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D),C=F[1],E=F[0]+D.offsetWidth,A=F[1]+D.offsetHeight,B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}YAHOO.util.Point.superclass.constructor.call(this,B,A,B,A);};YAHOO.extend(YAHOO.util.Point,YAHOO.util.Region);(function(){var B=YAHOO.util,A="clientTop",F="clientLeft",J="parentNode",K="right",W="hasLayout",I="px",U="opacity",L="auto",D="borderLeftWidth",G="borderTopWidth",P="borderRightWidth",V="borderBottomWidth",S="visible",Q="transparent",N="height",E="width",H="style",T="currentStyle",R=/^width|height$/,O=/^(\d[.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz|%){1}?/i,M={get:function(X,Z){var Y="",a=X[T][Z];if(Z===U){Y=B.Dom.getStyle(X,U);}else{if(!a||(a.indexOf&&a.indexOf(I)>-1)){Y=a;}else{if(B.Dom.IE_COMPUTED[Z]){Y=B.Dom.IE_COMPUTED[Z](X,Z);}else{if(O.test(a)){Y=B.Dom.IE.ComputedStyle.getPixel(X,Z);}else{Y=a;}}}}return Y;},getOffset:function(Z,e){var b=Z[T][e],X=e.charAt(0).toUpperCase()+e.substr(1),c="offset"+X,Y="pixel"+X,a="",d;if(b==L){d=Z[c];if(d===undefined){a=0;}a=d;if(R.test(e)){Z[H][e]=d;if(Z[c]>d){a=d-(Z[c]-d);}Z[H][e]=L;}}else{if(!Z[H][Y]&&!Z[H][e]){Z[H][e]=b;}a=Z[H][Y];}return a+I;},getBorderWidth:function(X,Z){var Y=null;if(!X[T][W]){X[H].zoom=1;}switch(Z){case G:Y=X[A];break;case V:Y=X.offsetHeight-X.clientHeight-X[A];break;case D:Y=X[F];break;case P:Y=X.offsetWidth-X.clientWidth-X[F];break;}return Y+I;},getPixel:function(Y,X){var a=null,b=Y[T][K],Z=Y[T][X];Y[H][K]=Z;a=Y[H].pixelRight;Y[H][K]=b;return a+I;},getMargin:function(Y,X){var Z;if(Y[T][X]==L){Z=0+I;}else{Z=B.Dom.IE.ComputedStyle.getPixel(Y,X);}return Z;},getVisibility:function(Y,X){var Z;while((Z=Y[T])&&Z[X]=="inherit"){Y=Y[J];}return(Z)?Z[X]:S;},getColor:function(Y,X){return B.Dom.Color.toRGB(Y[T][X])||Q;},getBorderColor:function(Y,X){var Z=Y[T],a=Z[X]||Z.color;return B.Dom.Color.toRGB(B.Dom.Color.toHex(a));}},C={};C.top=C.right=C.bottom=C.left=C[E]=C[N]=M.getOffset;C.color=M.getColor;C[G]=C[P]=C[V]=C[D]=M.getBorderWidth;C.marginTop=C.marginRight=C.marginBottom=C.marginLeft=M.getMargin;C.visibility=M.getVisibility;C.borderColor=C.borderTopColor=C.borderRightColor=C.borderBottomColor=C.borderLeftColor=M.getBorderColor;B.Dom.IE_COMPUTED=C;B.Dom.IE_ComputedStyle=M;})();(function(){var C="toString",A=parseInt,B=RegExp,D=YAHOO.util;D.Dom.Color={KEYWORDS:{black:"000",silver:"c0c0c0",gray:"808080",white:"fff",maroon:"800000",red:"f00",purple:"800080",fuchsia:"f0f",green:"008000",lime:"0f0",olive:"808000",yellow:"ff0",navy:"000080",blue:"00f",teal:"008080",aqua:"0ff"},re_RGB:/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,re_hex:/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,re_hex3:/([0-9A-F])/gi,toRGB:function(E){if(!D.Dom.Color.re_RGB.test(E)){E=D.Dom.Color.toHex(E);}if(D.Dom.Color.re_hex.exec(E)){E="rgb("+[A(B.$1,16),A(B.$2,16),A(B.$3,16)].join(", ")+")";}return E;},toHex:function(H){H=D.Dom.Color.KEYWORDS[H]||H;if(D.Dom.Color.re_RGB.exec(H)){var G=(B.$1.length===1)?"0"+B.$1:Number(B.$1),F=(B.$2.length===1)?"0"+B.$2:Number(B.$2),E=(B.$3.length===1)?"0"+B.$3:Number(B.$3);H=[G[C](16),F[C](16),E[C](16)].join("");}if(H.length<6){H=H.replace(D.Dom.Color.re_hex3,"$1$1");}if(H!=="transparent"&&H.indexOf("#")<0){H="#"+H;}return H.toLowerCase();}};}());YAHOO.register("dom",YAHOO.util.Dom,{version:"2.8.0r4",build:"2449"});YAHOO.util.CustomEvent=function(D,C,B,A,E){this.type=D;this.scope=C||window;this.silent=B;this.fireOnce=E;this.fired=false;this.firedWith=null;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var F="_YUICEOnSubscribe";if(D!==F){this.subscribeEvent=new YAHOO.util.CustomEvent(F,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,D){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,D);}var A=new YAHOO.util.Subscriber(B,C,D);if(this.fireOnce&&this.fired){this.notify(A,this.firedWith);}else{this.subscribers.push(A);}},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B0){H=C[0];}try{B=F.fn.call(E,H,F.obj);}catch(G){this.lastError=G;if(A){throw G;}}}else{try{B=F.fn.call(E,this.type,C,F.obj);}catch(D){this.lastError=D;if(A){throw D;}}}return B;},unsubscribeAll:function(){var A=this.subscribers.length,B;for(B=A-1;B>-1;B--){this._delete(B);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"context: "+this.scope;}};YAHOO.util.Subscriber=function(A,B,C){this.fn=A;this.obj=YAHOO.lang.isUndefined(B)?null:B;this.overrideContext=C;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.overrideContext){if(this.overrideContext===true){return this.obj;}else{return this.overrideContext;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", overrideContext: "+(this.overrideContext||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var G=false,H=[],J=[],A=0,E=[],B=0,C={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9},D=YAHOO.env.ua.ie,F="focusin",I="focusout";return{POLL_RETRYS:500,POLL_INTERVAL:40,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,CAPTURE:7,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:D,_interval:null,_dri:null,_specialTypes:{focusin:(D?"focusin":"focus"),focusout:(D?"focusout":"blur")},DOMReady:false,throwErrors:false,startInterval:function(){if(!this._interval){this._interval=YAHOO.lang.later(this.POLL_INTERVAL,this,this._tryPreloadAttach,null,true);}},onAvailable:function(Q,M,O,P,N){var K=(YAHOO.lang.isString(Q))?[Q]:Q;for(var L=0;L-1;M--){S=(this.removeListener(L[M],K,R)&&S);}return S;}}if(!R||!R.call){return this.purgeElement(L,false,K);}if("unload"==K){for(M=J.length-1;M>-1;M--){U=J[M];if(U&&U[0]==L&&U[1]==K&&U[2]==R){J.splice(M,1);return true;}}return false;}var N=null;var O=arguments[3];if("undefined"===typeof O){O=this._getCacheIndex(H,L,K,R);}if(O>=0){N=H[O];}if(!L||!N){return false;}var T=N[this.CAPTURE]===true?true:false;try{this._simpleRemove(L,K,N[this.WFN],T);}catch(Q){this.lastError=Q;return false;}delete H[O][this.WFN];delete H[O][this.FN];H.splice(O,1);return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(L){try{if(L&&3==L.nodeType){return L.parentNode;}}catch(K){}return L;},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];},getRelatedTarget:function(L){var K=L.relatedTarget;if(!K){if(L.type=="mouseout"){K=L.toElement; +}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in C)){K=C[K];}return K;},_getCacheIndex:function(M,P,Q,O){for(var N=0,L=M.length;N0&&E.length>0);}var P=[];var R=function(T,U){var S=T;if(U.overrideContext){if(U.overrideContext===true){S=U.obj;}else{S=U.overrideContext;}}U.fn.call(S,U.obj);};var L,K,O,N,M=[];for(L=0,K=E.length;L-1;L--){O=E[L];if(!O||!O.id){E.splice(L,1);}}this.startInterval();}else{if(this._interval){this._interval.cancel();this._interval=null;}}this.locked=false;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=Q.length-1;N>-1;N--){var L=Q[N];this.removeListener(M,L.type,L.fn);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N-1;N--){M=H[N];if(M){L.removeListener(M[L.EL],M[L.TYPE],M[L.FN],N);}}M=null;}L._simpleRemove(window,"unload",L._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent){return function(M,N,L,K){M.attachEvent("on"+N,L);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;EU.onFocus=EU.addFocusListener;EU.onBlur=EU.addBlurListener; +/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller/Diego Perini */ +if(EU.isIE){if(self!==self.top){document.onreadystatechange=function(){if(document.readyState=="complete"){document.onreadystatechange=null;EU._ready();}};}else{YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({fn:C,obj:F,overrideContext:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A); +},createEvent:function(B,G){this.__yui_events=this.__yui_events||{};var E=G||{},D=this.__yui_events,F;if(D[B]){}else{F=new YAHOO.util.CustomEvent(B,E.scope||this,E.silent,YAHOO.util.CustomEvent.FLAT,E.fireOnce);D[B]=F;if(E.onSubscribeCallback){F.subscribeEvent.subscribe(E.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var A=this.__yui_subscribers[B];if(A){for(var C=0;C{tests}", + "footer": "" + }, diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton.php new file mode 100644 index 00000000..0cedcd61 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton.php @@ -0,0 +1,153 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.1.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Class.php'; +require_once 'PHPUnit/Util/Template.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generator for skeletons. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +abstract class PHPUnit_Util_Skeleton +{ + /** + * @var array + */ + protected $inClassName; + + /** + * @var string + */ + protected $inSourceFile; + + /** + * @var array + */ + protected $outClassName; + + /** + * @var string + */ + protected $outSourceFile; + + /** + * Constructor. + * + * @param string $inClassName + * @param string $inSourceFile + * @param string $outClassName + * @param string $outSourceFile + * @since Method available since Release 3.4.0 + */ + public function __construct($inClassName, $inSourceFile = '', $outClassName = '', $outSourceFile = '') + { + $this->inClassName = PHPUnit_Util_Class::parseFullyQualifiedClassName( + $inClassName + ); + + $this->outClassName = PHPUnit_Util_Class::parseFullyQualifiedClassName( + $outClassName + ); + + $this->inSourceFile = str_replace( + $this->inClassName['fullyQualifiedClassName'], + $this->inClassName['className'], + $inSourceFile + ); + + $this->outSourceFile = str_replace( + $this->outClassName['fullyQualifiedClassName'], + $this->outClassName['className'], + $outSourceFile + ); + } + + /** + * @return string + */ + public function getOutClassName() + { + return $this->outClassName['fullyQualifiedClassName']; + } + + /** + * @return string + */ + public function getOutSourceFile() + { + return $this->outSourceFile; + } + + /** + * Generates the code and writes it to a source file. + * + * @param string $file + */ + public function write($file = '') + { + if ($file == '') { + $file = $this->outSourceFile; + } + + if ($fp = @fopen($file, 'wt')) { + @fwrite($fp, $this->generate()); + @fclose($fp); + } + } + + abstract public function generate(); +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Class.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Class.php new file mode 100644 index 00000000..55acdfce --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Class.php @@ -0,0 +1,325 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/File.php'; +require_once 'PHPUnit/Util/Template.php'; +require_once 'PHPUnit/Util/Skeleton.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generator for class skeletons from test classes. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Util_Skeleton_Class extends PHPUnit_Util_Skeleton +{ + /** + * Constructor. + * + * @param string $inClassName + * @param string $inSourceFile + * @param string $outClassName + * @param string $outSourceFile + * @throws RuntimeException + */ + public function __construct($inClassName, $inSourceFile = '', $outClassName = '', $outSourceFile = '') + { + if (empty($inSourceFile)) { + $inSourceFile = $inClassName . '.php'; + } + + if (!is_file($inSourceFile)) { + throw new PHPUnit_Framework_Exception( + sprintf( + '"%s" could not be opened.', + + $inSourceFile + ) + ); + } + + if (empty($outClassName)) { + $outClassName = substr($inClassName, 0, strlen($inClassName) - 4); + } + + if (empty($outSourceFile)) { + $outSourceFile = dirname($inSourceFile) . DIRECTORY_SEPARATOR . + $outClassName . '.php'; + } + + parent::__construct( + $inClassName, $inSourceFile, $outClassName, $outSourceFile + ); + } + + /** + * Generates the class' source. + * + * @return mixed + */ + public function generate() + { + $methods = ''; + + foreach ($this->findTestedMethods() as $method) { + $methodTemplate = new PHPUnit_Util_Template( + sprintf( + '%s%sTemplate%sMethod.tpl', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ) + ); + + $methodTemplate->setVar( + array( + 'methodName' => $method, + ) + ); + + $methods .= $methodTemplate->render(); + } + + $classTemplate = new PHPUnit_Util_Template( + sprintf( + '%s%sTemplate%sClass.tpl', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ) + ); + + $classTemplate->setVar( + array( + 'className' => $this->outClassName['fullyQualifiedClassName'], + 'methods' => $methods, + 'date' => date('Y-m-d'), + 'time' => date('H:i:s') + ) + ); + + return $classTemplate->render(); + } + + /** + * Returns the methods of the class under test + * that are called from the test methods. + * + * @return array + */ + protected function findTestedMethods() + { + $setUpVariables = array(); + $testedMethods = array(); + $classes = PHPUnit_Util_File::getClassesInFile( + $this->inSourceFile + ); + $testMethods = $classes[$this->inClassName['fullyQualifiedClassName']]['methods']; + unset($classes); + + foreach ($testMethods as $name => $testMethod) { + if (strtolower($name) == 'setup') { + $setUpVariables = $this->findVariablesThatReferenceClass( + $testMethod['tokens'] + ); + + break; + } + } + + foreach ($testMethods as $name => $testMethod) { + $argVariables = array(); + + if (strtolower($name) == 'setup') { + continue; + } + + $start = strpos($testMethod['signature'], '(') + 1; + $end = strlen($testMethod['signature']) - $start - 1; + $args = substr($testMethod['signature'], $start, $end); + + foreach (explode(',', $args) as $arg) { + list($type, $var) = explode(' ', $arg); + + if ($type == $this->outClassName['fullyQualifiedClassName']) { + $argVariables[] = $var; + } + } + + $variables = array_unique( + array_merge( + $setUpVariables, + $argVariables, + $this->findVariablesThatReferenceClass($testMethod['tokens']) + ) + ); + + foreach ($testMethod['tokens'] as $i => $token) { + // Class::method() + if (is_array($token) && $token[0] == T_DOUBLE_COLON && + is_array($testMethod['tokens'][$i-1]) && + $testMethod['tokens'][$i-1][0] == T_STRING && + $testMethod['tokens'][$i-1][1] == $this->outClassName['fullyQualifiedClassName'] && + is_array($testMethod['tokens'][$i+1]) && + $testMethod['tokens'][$i+1][0] == T_STRING && + $testMethod['tokens'][$i+2] == '(') { + $testedMethods[] = $testMethod['tokens'][$i+1][1]; + } + + // $this->object->method() + else if (is_array($token) && $token[0] == T_OBJECT_OPERATOR && + in_array($this->findVariableName($testMethod['tokens'], $i), $variables) && + is_array($testMethod['tokens'][$i+2]) && + $testMethod['tokens'][$i+2][0] == T_OBJECT_OPERATOR && + is_array($testMethod['tokens'][$i+3]) && + $testMethod['tokens'][$i+3][0] == T_STRING && + $testMethod['tokens'][$i+4] == '(') { + $testedMethods[] = $testMethod['tokens'][$i+3][1]; + } + + // $object->method() + else if (is_array($token) && $token[0] == T_OBJECT_OPERATOR && + in_array($this->findVariableName($testMethod['tokens'], $i), $variables) && + is_array($testMethod['tokens'][$i+1]) && + $testMethod['tokens'][$i+1][0] == T_STRING && + $testMethod['tokens'][$i+2] == '(') { + $testedMethods[] = $testMethod['tokens'][$i+1][1]; + } + } + } + + $testedMethods = array_unique($testedMethods); + sort($testedMethods); + + return $testedMethods; + } + + /** + * Returns the variables used in test methods + * that reference the class under test. + * + * @param array $tokens + * @return array + */ + protected function findVariablesThatReferenceClass(array $tokens) + { + $inNew = FALSE; + $variables = array(); + + foreach ($tokens as $i => $token) { + if (is_string($token)) { + if (trim($token) == ';') { + $inNew = FALSE; + } + + continue; + } + + list ($token, $value) = $token; + + switch ($token) { + case T_NEW: { + $inNew = TRUE; + } + break; + + case T_STRING: { + if ($inNew) { + if ($value == $this->outClassName['fullyQualifiedClassName']) { + $variables[] = $this->findVariableName( + $tokens, $i + ); + } + } + + $inNew = FALSE; + } + break; + } + } + + return $variables; + } + + /** + * Finds the variable name of the object for the method call + * that is currently being processed. + * + * @param array $tokens + * @param integer $start + * @return mixed + */ + protected function findVariableName(array $tokens, $start) + { + for ($i = $start - 1; $i >= 0; $i--) { + if (is_array($tokens[$i]) && $tokens[$i][0] == T_VARIABLE) { + $variable = $tokens[$i][1]; + + if (is_array($tokens[$i+1]) && + $tokens[$i+1][0] == T_OBJECT_OPERATOR && + $tokens[$i+2] != '(' && + $tokens[$i+3] != '(') { + $variable .= '->' . $tokens[$i+2][1]; + } + + return $variable; + } + } + + return FALSE; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/Class.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/Class.tpl.dist new file mode 100644 index 00000000..2a29e5e0 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/Class.tpl.dist @@ -0,0 +1,7 @@ + diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/IncompleteTestMethod.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/IncompleteTestMethod.tpl.dist new file mode 100644 index 00000000..d89f90ee --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/IncompleteTestMethod.tpl.dist @@ -0,0 +1,11 @@ + + /** + * @todo Implement test{methodName}(). + */ + public function test{methodName}() + { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/Method.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/Method.tpl.dist new file mode 100644 index 00000000..dd3b0449 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/Method.tpl.dist @@ -0,0 +1,9 @@ + + /** + * @todo Implement {methodName}(). + */ + public function {methodName}() + { + // Remove the following line when you implement this method. + throw new RuntimeException('Not yet implemented.'); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestClass.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestClass.tpl.dist new file mode 100644 index 00000000..754b2d7d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestClass.tpl.dist @@ -0,0 +1,32 @@ +object = new {className}; + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + } +{methods}} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethod.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethod.tpl.dist new file mode 100644 index 00000000..68acf2b7 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethod.tpl.dist @@ -0,0 +1,11 @@ + + /** + * Generated from @assert {annotation}. + */ + public function test{methodName}() + { + $this->assert{assertion}( + {expected}, + $this->object->{origMethodName}({arguments}) + ); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodBool.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodBool.tpl.dist new file mode 100644 index 00000000..483a2729 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodBool.tpl.dist @@ -0,0 +1,10 @@ + + /** + * Generated from @assert {annotation}. + */ + public function test{methodName}() + { + $this->assert{assertion}( + $this->object->{origMethodName}({arguments}) + ); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodBoolStatic.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodBoolStatic.tpl.dist new file mode 100644 index 00000000..f46d84da --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodBoolStatic.tpl.dist @@ -0,0 +1,10 @@ + + /** + * Generated from @assert {annotation}. + */ + public function test{methodName}() + { + $this->assert{assertion}( + {className}::{origMethodName}({arguments}) + ); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodException.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodException.tpl.dist new file mode 100644 index 00000000..75c02b0f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodException.tpl.dist @@ -0,0 +1,9 @@ + + /** + * Generated from @assert {annotation}. + * @expectedException {expected} + */ + public function test{methodName}() + { + $this->object->{origMethodName}({arguments}); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodExceptionStatic.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodExceptionStatic.tpl.dist new file mode 100644 index 00000000..5f27729e --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodExceptionStatic.tpl.dist @@ -0,0 +1,9 @@ + + /** + * Generated from @assert {annotation}. + * @expectedException {expected} + */ + public function test{methodName}() + { + {className}::{origMethodName}({arguments}); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodStatic.tpl.dist b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodStatic.tpl.dist new file mode 100644 index 00000000..b4fe571b --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Template/TestMethodStatic.tpl.dist @@ -0,0 +1,11 @@ + + /** + * Generated from @assert {annotation}. + */ + public function test{methodName}() + { + $this->assert{assertion}( + {expected}, + {className}::{origMethodName}({arguments}) + ); + } diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Test.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Test.php new file mode 100644 index 00000000..601941b2 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Skeleton/Test.php @@ -0,0 +1,385 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.3.0 + */ + +require_once 'PHPUnit/Util/Filesystem.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/Skeleton.php'; +require_once 'PHPUnit/Util/Template.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Generator for test class skeletons from classes. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Util_Skeleton_Test extends PHPUnit_Util_Skeleton +{ + /** + * @var array + */ + protected $methodNameCounter = array(); + + /** + * Constructor. + * + * @param string $inClassName + * @param string $inSourceFile + * @param string $outClassName + * @param string $outSourceFile + * @throws RuntimeException + */ + public function __construct($inClassName, $inSourceFile = '', $outClassName = '', $outSourceFile = '') + { + if (class_exists($inClassName)) { + $reflector = new ReflectionClass($inClassName); + $inSourceFile = $reflector->getFileName(); + + if ($inSourceFile !== FALSE) { + $inSourceFile = ''; + } + + unset($reflector); + } else { + if (empty($inSourceFile)) { + $possibleFilenames = array( + $inClassName . '.php', + PHPUnit_Util_Filesystem::classNameToFilename($inClassName) + ); + + foreach ($possibleFilenames as $possibleFilename) { + if (is_file($possibleFilename)) { + $inSourceFile = $possibleFilename; + } + } + } + + if (empty($inSourceFile)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Neither "%s" nor "%s" could be opened.', + $possibleFilenames[0], + $possibleFilenames[1] + ) + ); + } + + if (!is_file($inSourceFile)) { + throw new PHPUnit_Framework_Exception( + sprintf( + '"%s" could not be opened.', + + $inSourceFile + ) + ); + } + + $inSourceFile = realpath($inSourceFile); + include_once $inSourceFile; + + if (!class_exists($inClassName)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not find class "%s" in "%s".', + + $inClassName, + $inSourceFile + ) + ); + } + } + + if (empty($outClassName)) { + $outClassName = $inClassName . 'Test'; + } + + if (empty($outSourceFile)) { + $outSourceFile = dirname($inSourceFile) . DIRECTORY_SEPARATOR . $outClassName . '.php'; + } + + parent::__construct( + $inClassName, $inSourceFile, $outClassName, $outSourceFile + ); + } + + /** + * Generates the test class' source. + * + * @param boolean $verbose + * @return mixed + */ + public function generate($verbose = FALSE) + { + $class = new ReflectionClass( + $this->inClassName['fullyQualifiedClassName'] + ); + $methods = ''; + $incompleteMethods = ''; + + foreach ($class->getMethods() as $method) { + if (!$method->isConstructor() && + !$method->isAbstract() && + $method->isPublic() && + $method->getDeclaringClass()->getName() == $this->inClassName['fullyQualifiedClassName']) { + $assertAnnotationFound = FALSE; + + if (preg_match_all('/@assert(.*)$/Um', $method->getDocComment(), $annotations)) { + foreach ($annotations[1] as $annotation) { + if (preg_match('/\((.*)\)\s+([^\s]*)\s+(.*)/', $annotation, $matches)) { + switch ($matches[2]) { + case '==': { + $assertion = 'Equals'; + } + break; + + case '!=': { + $assertion = 'NotEquals'; + } + break; + + case '===': { + $assertion = 'Same'; + } + break; + + case '!==': { + $assertion = 'NotSame'; + } + break; + + case '>': { + $assertion = 'GreaterThan'; + } + break; + + case '>=': { + $assertion = 'GreaterThanOrEqual'; + } + break; + + case '<': { + $assertion = 'LessThan'; + } + break; + + case '<=': { + $assertion = 'LessThanOrEqual'; + } + break; + + case 'throws': { + $assertion = 'exception'; + } + break; + + default: { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Token "%s" could not be parsed in @assert annotation.', + $matches[2] + ) + ); + } + } + + if ($assertion == 'exception') { + $template = 'TestMethodException'; + } + + else if ($assertion == 'Equals' && + strtolower($matches[3]) == 'true') { + $assertion = 'True'; + $template = 'TestMethodBool'; + } + + else if ($assertion == 'NotEquals' && + strtolower($matches[3]) == 'true') { + $assertion = 'False'; + $template = 'TestMethodBool'; + } + + else if ($assertion == 'Equals' && + strtolower($matches[3]) == 'false') { + $assertion = 'False'; + $template = 'TestMethodBool'; + } + + else if ($assertion == 'NotEquals' && + strtolower($matches[3]) == 'false') { + $assertion = 'True'; + $template = 'TestMethodBool'; + } + + else { + $template = 'TestMethod'; + } + + if ($method->isStatic()) { + $template .= 'Static'; + } + + $methodTemplate = new PHPUnit_Util_Template( + sprintf( + '%s%sTemplate%s%s.tpl', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + $template + ) + ); + + $origMethodName = $method->getName(); + $methodName = ucfirst($origMethodName); + + if (isset($this->methodNameCounter[$methodName])) { + $this->methodNameCounter[$methodName]++; + } else { + $this->methodNameCounter[$methodName] = 1; + } + + if ($this->methodNameCounter[$methodName] > 1) { + $methodName .= $this->methodNameCounter[$methodName]; + } + + $methodTemplate->setVar( + array( + 'annotation' => trim($annotation), + 'arguments' => $matches[1], + 'assertion' => isset($assertion) ? $assertion : '', + 'expected' => $matches[3], + 'origMethodName' => $origMethodName, + 'className' => $this->inClassName['fullyQualifiedClassName'], + 'methodName' => $methodName + ) + ); + + $methods .= $methodTemplate->render(); + + $assertAnnotationFound = TRUE; + } + } + } + + if (!$assertAnnotationFound) { + $methodTemplate = new PHPUnit_Util_Template( + sprintf( + '%s%sTemplate%sIncompleteTestMethod.tpl', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ) + ); + + $methodTemplate->setVar( + array( + 'methodName' => ucfirst($method->getName()) + ) + ); + + $incompleteMethods .= $methodTemplate->render(); + } + } + } + + $classTemplate = new PHPUnit_Util_Template( + sprintf( + '%s%sTemplate%sTestClass.tpl', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ) + ); + + if ($this->inSourceFile != '') { + $requireClassFile = sprintf( + "\n\nrequire_once '%s';", + + $this->inSourceFile + ); + } else { + $requireClassFile = ''; + } + + if ($this->outClassName['namespace'] != '') { + $namespace = "\nnamespace " . + $this->outClassName['namespace'] . ";\n"; + } else { + $namespace = ''; + } + + $classTemplate->setVar( + array( + 'namespace' => $namespace, + 'namespaceSeparator' => !empty($namespace) ? '\\' : '', + 'className' => $this->inClassName['className'], + 'testClassName' => $this->outClassName['className'], + 'requireClassFile' => $requireClassFile, + 'methods' => $methods . $incompleteMethods, + 'date' => date('Y-m-d'), + 'time' => date('H:i:s') + ) + ); + + if (!$verbose) { + return $classTemplate->render(); + } else { + return array( + 'code' => $classTemplate->render(), + 'incomplete' => empty($methods) + ); + } + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Template.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Template.php new file mode 100644 index 00000000..38d91f09 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Template.php @@ -0,0 +1,180 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Template +{ + /** + * @var string + */ + protected static $date = ''; + + /** + * @var string + */ + protected $template = ''; + + /** + * @var array + */ + protected $values = array(); + + /** + * Constructor. + * + * @param string $file + * @throws InvalidArgumentException + */ + public function __construct($file = '') + { + $this->setFile($file); + } + + /** + * Sets the template file. + * + * @param string $file + * @throws InvalidArgumentException + */ + public function setFile($file) + { + $distFile = $file . '.dist'; + + if (file_exists($file)) { + $this->template = file_get_contents($file); + } + + else if (file_exists($distFile)) { + $this->template = file_get_contents($distFile); + } + + else { + throw new InvalidArgumentException( + 'Template file could not be loaded.' + ); + } + } + + /** + * Sets one or more template variables. + * + * @param array $values + * @param boolean $merge + */ + public function setVar(array $values, $merge = TRUE) + { + if (!$merge || empty($this->values)) { + $this->values = $values; + } else { + $this->values = array_merge($this->values, $values); + } + } + + /** + * Renders the template and returns the result. + * + * @return string + */ + public function render() + { + $keys = array(); + + foreach ($this->values as $key => $value) { + $keys[] = '{' . $key . '}'; + } + + return str_replace($keys, $this->values, $this->template); + } + + /** + * Renders the template and writes the result to a file. + * + * @param string $target + */ + public function renderTo($target) + { + $fp = @fopen($target, 'wt'); + + if ($fp) { + fwrite($fp, $this->render()); + fclose($fp); + } else { + throw new PHPUnit_Framework_Exception( + 'Could not write to ' . $target . '.' + ); + } + } + + /** + * Returns the cached result of date('D M j G:i:s T Y'). + * + * @return string + * @since Method available since Release 3.0.1 + */ + public static function getDate() + { + if (self::$date == '') { + self::$date = date('D M j G:i:s T Y'); + } + + return self::$date; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Test.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Test.php new file mode 100644 index 00000000..4103713f --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Test.php @@ -0,0 +1,656 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Test helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Test +{ + const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\]+)/'; + const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m'; + + private static $annotationCache = array(); + + protected static $templateMethods = array( + 'setUp', 'assertPreConditions', 'assertPostConditions', 'tearDown' + ); + + /** + * @param PHPUnit_Framework_Test $test + * @param boolean $asString + * @return mixed + */ + public static function describe(PHPUnit_Framework_Test $test, $asString = TRUE) + { + if ($asString) { + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + return $test->toString(); + } else { + return get_class($test); + } + } else { + if ($test instanceof PHPUnit_Framework_TestCase) { + return array( + get_class($test), $test->getName() + ); + } + + else if ($test instanceof PHPUnit_Framework_SelfDescribing) { + return array('', $test->toString()); + } + + else { + return array('', get_class($test)); + } + } + } + + /** + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_TestResult $result + * @return mixed + */ + public static function lookupResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result) + { + $testName = self::describe($test); + + foreach ($result->errors() as $error) { + if ($testName == self::describe($error->failedTest())) { + return $error; + } + } + + foreach ($result->failures() as $failure) { + if ($testName == self::describe($failure->failedTest())) { + return $failure; + } + } + + foreach ($result->notImplemented() as $notImplemented) { + if ($testName == self::describe($notImplemented->failedTest())) { + return $notImplemented; + } + } + + foreach ($result->skipped() as $skipped) { + if ($testName == self::describe($skipped->failedTest())) { + return $skipped; + } + } + + return PHPUnit_Runner_BaseTestRunner::STATUS_PASSED; + } + + /** + * Returns the files and lines a test method wants to cover. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.2.0 + */ + public static function getLinesToBeCovered($className, $methodName) + { + $codeToCoverList = array(); + $result = array(); + + if (($pos = strpos($methodName, ' ')) !== FALSE) { + $methodName = substr($methodName, 0, $pos); + } + + $class = new ReflectionClass($className); + + if (!$class->hasMethod($methodName)) { + return $result; + } + + $method = new ReflectionMethod($className, $methodName); + $docComment = $class->getDocComment() . $method->getDocComment(); + + foreach (self::$templateMethods as $templateMethod) { + if ($class->hasMethod($templateMethod)) { + $reflector = $class->getMethod($templateMethod); + $docComment .= $reflector->getDocComment(); + unset($reflector); + } + } + + $annotations = self::parseAnnotations($docComment); + + if (isset($annotations['covers'])) { + foreach ($annotations['covers'] as $coveredElement) { + $codeToCoverList = array_merge( + $codeToCoverList, + self::resolveCoversToReflectionObjects($coveredElement) + ); + } + + foreach ($codeToCoverList as $codeToCover) { + $fileName = $codeToCover->getFileName(); + $startLine = $codeToCover->getStartLine(); + $endLine = $codeToCover->getEndLine(); + + if (!isset($result[$fileName])) { + $result[$fileName] = array(); + } + + $result[$fileName] = array_unique( + array_merge( + $result[$fileName], range($startLine, $endLine) + ) + ); + } + } + + return $result; + } + + /** + * Returns the expected exception for a test. + * + * @param string $docComment + * @return array + * @since Method available since Release 3.3.6 + */ + public static function getExpectedException($docComment) + { + if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) { + $class = $matches[1]; + $code = 0; + $message = ''; + + if (isset($matches[2])) { + $message = trim($matches[2]); + } + + if (isset($matches[3])) { + $code = (int)$matches[3]; + } + + return array( + 'class' => $class, 'code' => $code, 'message' => $message + ); + } + + return FALSE; + } + + /** + * Returns the provided data for a method. + * + * @param string $className + * @param string $methodName + * @param string $docComment + * @return array + * @throws ReflectionException + * @since Method available since Release 3.2.0 + */ + public static function getProvidedData($className, $methodName) + { + $reflector = new ReflectionMethod($className, $methodName); + $docComment = $reflector->getDocComment(); + + if (preg_match(self::REGEX_DATA_PROVIDER, $docComment, $matches)) { + try { + $dataProviderMethodNameNamespace = explode('\\', $matches[1]); + $leaf = explode('::', array_pop($dataProviderMethodNameNamespace)); + $dataProviderMethodName = array_pop($leaf); + + if (!empty($dataProviderMethodNameNamespace)) { + $dataProviderMethodNameNamespace = join('\\', $dataProviderMethodNameNamespace) . '\\'; + } else { + $dataProviderMethodNameNamespace = ''; + } + + if (!empty($leaf)) { + $dataProviderClassName = $dataProviderMethodNameNamespace . array_pop($leaf); + } else { + $dataProviderClassName = $className; + } + + $dataProviderClass = new ReflectionClass($dataProviderClassName); + $dataProviderMethod = $dataProviderClass->getMethod( + $dataProviderMethodName + ); + + if ($dataProviderMethod->isStatic()) { + $object = NULL; + } else { + $object = $dataProviderClass->newInstance(); + } + + if ($dataProviderMethod->getNumberOfParameters() == 0) { + return $dataProviderMethod->invoke($object); + } else { + return $dataProviderMethod->invoke($object, $methodName); + } + } + + catch (ReflectionException $e) { + } + } + } + + /** + * @param string $coveredElement + * @return array + */ + private static function resolveCoversToReflectionObjects($coveredElement) + { + $codeToCoverList = array(); + + if (strpos($coveredElement, '::') !== FALSE) { + list($className, $methodName) = explode('::', $coveredElement); + + if ($methodName{0} == '<') { + $classes = array($className); + + foreach ($classes as $className) + { + if (!class_exists($className) && + !interface_exists($className)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Trying to @cover not existing class or ' . + 'interface "%s".', + $className + ) + ); + } + + $class = new ReflectionClass($className); + $methods = $class->getMethods(); + $inverse = isset($methodName{1}) && $methodName{1} == '!'; + + if (strpos($methodName, 'protected')) { + $visibility = 'isProtected'; + } + + else if (strpos($methodName, 'private')) { + $visibility = 'isPrivate'; + } + + else if (strpos($methodName, 'public')) { + $visibility = 'isPublic'; + } + + foreach ($methods as $method) { + if ($inverse && !$method->$visibility()) { + $codeToCoverList[] = $method; + } + + else if (!$inverse && $method->$visibility()) { + $codeToCoverList[] = $method; + } + } + } + } else { + $classes = array($className); + + foreach ($classes as $className) { + if (!((class_exists($className) || + interface_exists($className)) && + method_exists($className, $methodName))) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Trying to @cover not existing method "%s::%s".', + $className, + $methodName + ) + ); + } + + $codeToCoverList[] = new ReflectionMethod( + $className, $methodName + ); + } + } + } else { + $extended = FALSE; + + if (strpos($coveredElement, '') !== FALSE) { + $coveredElement = str_replace( + '', '', $coveredElement + ); + + $extended = TRUE; + } + + $classes = array($coveredElement); + + if ($extended) { + $classes = array_merge( + $classes, + class_implements($coveredElement), + class_parents($coveredElement) + ); + } + + foreach ($classes as $className) { + if (!class_exists($className) && + !interface_exists($className)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Trying to @cover not existing class or ' . + 'interface "%s".', + $className + ) + ); + } + + $codeToCoverList[] = new ReflectionClass($className); + } + } + + return $codeToCoverList; + } + + /** + * @param string $className + * @param string $methodName + * @return array + * @throws ReflectionException + * @since Method available since Release 3.4.0 + */ + public static function parseTestMethodAnnotations($className, $methodName = '') + { + if (!isset(self::$annotationCache[$className])) { + $class = new ReflectionClass($className); + self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment()); + } + + if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) { + $method = new ReflectionMethod($className, $methodName); + self::$annotationCache[$className . '::' . $methodName] = self::parseAnnotations($method->getDocComment()); + } + + return array( + 'class' => self::$annotationCache[$className], + 'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : array() + ); + } + + /** + * @param string $docblock + * @return array + * @since Method available since Release 3.4.0 + */ + private static function parseAnnotations($docblock) + { + $annotations = array(); + + if (preg_match_all('/@(?P[A-Za-z_-]+)(?:[ \t]+(?P.*?))?[ \t]*\r?$/m', $docblock, $matches)) { + $numMatches = count($matches[0]); + + for ($i = 0; $i < $numMatches; ++$i) { + $annotations[$matches['name'][$i]][] = $matches['value'][$i]; + } + } + + return $annotations; + } + + /** + * Returns the backup settings for a test. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.4.0 + */ + public static function getBackupSettings($className, $methodName) + { + return array( + 'backupGlobals' => self::getBooleanAnnotationSetting( + $className, $methodName, 'backupGlobals' + ), + 'backupStaticAttributes' => self::getBooleanAnnotationSetting( + $className, $methodName, 'backupStaticAttributes' + ) + ); + } + + /** + * Returns the dependencies for a test class or method. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.4.0 + */ + public static function getDependencies($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, $methodName + ); + + $dependencies = array(); + + if (isset($annotations['class']['depends'])) { + $dependencies = $annotations['class']['depends']; + } + + if (isset($annotations['method']['depends'])) { + $dependencies = array_merge( + $dependencies, $annotations['method']['depends'] + ); + } + + return array_unique($dependencies); + } + + /** + * Returns the error handler settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.0 + */ + public static function getErrorHandlerSettings($className, $methodName) + { + return self::getBooleanAnnotationSetting( + $className, $methodName, 'errorHandler' + ); + } + + /** + * Returns the groups for a test class or method. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.2.0 + */ + public static function getGroups($className, $methodName = '') + { + $annotations = self::parseTestMethodAnnotations( + $className, $methodName + ); + + $groups = array(); + + if (isset($annotations['class']['group'])) { + $groups = $annotations['class']['group']; + } + + if (isset($annotations['method']['group'])) { + $groups = array_merge($groups, $annotations['method']['group']); + } + + return array_unique($groups); + } + + /** + * Returns the tickets for a test class or method. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.4.0 + */ + public static function getTickets($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, $methodName + ); + + $tickets = array(); + + if (isset($annotations['class']['ticket'])) { + $tickets = $annotations['class']['ticket']; + } + + if (isset($annotations['method']['ticket'])) { + $tickets = array_merge($tickets, $annotations['method']['ticket']); + } + + return array_unique($tickets); + } + + /** + * Returns the output buffering settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.0 + */ + public static function getOutputBufferingSettings($className, $methodName) + { + return self::getBooleanAnnotationSetting( + $className, $methodName, 'outputBuffering' + ); + } + + /** + * Returns the process isolation settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.1 + */ + public static function getProcessIsolationSettings($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, $methodName + ); + + if (isset($annotations['class']['runTestsInSeparateProcesses']) || + isset($annotations['method']['runInSeparateProcess'])) { + return TRUE; + } else { + return FALSE; + } + } + + /** + * Returns the preserve global state settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.0 + */ + public static function getPreserveGlobalStateSettings($className, $methodName) + { + return self::getBooleanAnnotationSetting( + $className, $methodName, 'preserveGlobalState' + ); + } + + /** + * @param string $className + * @param string $methodName + * @param string $settingName + * @return boolean + * @since Method available since Release 3.4.0 + */ + private static function getBooleanAnnotationSetting($className, $methodName, $settingName) + { + $annotations = self::parseTestMethodAnnotations( + $className, $methodName + ); + + $result = NULL; + + if (isset($annotations['class'][$settingName])) { + if ($annotations['class'][$settingName][0] == 'enabled') { + $result = TRUE; + } + + else if ($annotations['class'][$settingName][0] == 'disabled') { + $result = FALSE; + } + } + + if (isset($annotations['method'][$settingName])) { + if ($annotations['method'][$settingName][0] == 'enabled') { + $result = TRUE; + } + + else if ($annotations['method'][$settingName][0] == 'disabled') { + $result = FALSE; + } + } + + return $result; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/NamePrettifier.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/NamePrettifier.php new file mode 100644 index 00000000..6e0c9c50 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/NamePrettifier.php @@ -0,0 +1,183 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Prettifies class and method names for use in TestDox documentation. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_TestDox_NamePrettifier +{ + /** + * @var string + */ + protected $prefix = 'Test'; + + /** + * @var string + */ + protected $suffix = 'Test'; + + /** + * @var array + */ + protected $strings = array(); + + /** + * Prettifies the name of a test class. + * + * @param string $name + * @return string + */ + public function prettifyTestClass($name) + { + $title = $name; + + if ($this->suffix !== NULL && + $this->suffix == substr($name, -1 * strlen($this->suffix))) { + $title = substr($title, 0, strripos($title, $this->suffix)); + } + + if ($this->prefix !== NULL && + $this->prefix == substr($name, 0, strlen($this->prefix))) { + $title = substr($title, strlen($this->prefix)); + } + + return $title; + } + + /** + * Prettifies the name of a test method. + * + * @param string $name + * @return string + */ + public function prettifyTestMethod($name) + { + $buffer = ''; + + if (!is_string($name) || strlen($name) == 0) { + return $buffer; + } + + $string = preg_replace('#\d+$#', '', $name); + + if (in_array($string, $this->strings)) { + $name = $string; + } else { + $this->strings[] = $string; + } + + if (strpos($name, '_') !== FALSE) { + return str_replace('_', ' ', $name); + } + + $max = strlen($name); + + if (substr($name, 0, 4) == 'test') { + $offset = 4; + } else { + $offset = 0; + $name[0] = strtoupper($name[0]); + } + + $wasNumeric = FALSE; + + for ($i = $offset; $i < $max; $i++) { + if ($i > $offset && + ord($name[$i]) >= 65 && + ord($name[$i]) <= 90) { + $buffer .= ' ' . strtolower($name[$i]); + } else { + $isNumeric = is_numeric($name[$i]); + + if (!$wasNumeric && $isNumeric) { + $buffer .= ' '; + $wasNumeric = TRUE; + } + + if ($wasNumeric && !$isNumeric) { + $wasNumeric = FALSE; + } + + $buffer .= $name[$i]; + } + } + + return $buffer; + } + + /** + * Sets the prefix of test names. + * + * @param string $prefix + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Sets the suffix of test names. + * + * @param string $prefix + */ + public function setSuffix($suffix) + { + $this->suffix = $suffix; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter.php new file mode 100644 index 00000000..bce08a5c --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter.php @@ -0,0 +1,338 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/TestDox/NamePrettifier.php'; +require_once 'PHPUnit/Util/Printer.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Base class for printers of TestDox documentation. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + * @abstract + */ +abstract class PHPUnit_Util_TestDox_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var PHPUnit_Util_TestDox_NamePrettifier + */ + protected $prettifier; + + /** + * @var string + */ + protected $testClass = ''; + + /** + * @var integer + */ + protected $testStatus = FALSE; + + /** + * @var array + */ + protected $tests = array(); + + protected $successful = 0; + protected $failed = 0; + protected $skipped = 0; + protected $incomplete = 0; + protected $testTypeOfInterest = 'PHPUnit_Framework_TestCase'; + + /** + * @var string + */ + protected $currentTestClassPrettified; + + /** + * @var string + */ + protected $currentTestMethodPrettified; + + /** + * Constructor. + * + * @param resource $out + */ + public function __construct($out = NULL) + { + parent::__construct($out); + + $this->prettifier = new PHPUnit_Util_TestDox_NamePrettifier; + $this->startRun(); + } + + /** + * Flush buffer and close output. + * + */ + public function flush() + { + $this->doEndClass(); + $this->endRun(); + + parent::flush(); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + $this->failed++; + } + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE; + $this->failed++; + } + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE; + $this->incomplete++; + } + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED; + $this->skipped++; + } + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if ($test instanceof $this->testTypeOfInterest) { + $class = get_class($test); + + if ($this->testClass != $class) { + if ($this->testClass != '') { + $this->doEndClass(); + } + + $this->currentTestClassPrettified = $this->prettifier->prettifyTestClass($class); + $this->startClass($class); + + $this->testClass = $class; + $this->tests = array(); + } + + $prettified = FALSE; + + if ($test instanceof PHPUnit_Framework_TestCase && + !$test instanceof PHPUnit_Framework_Warning) { + $annotations = $test->getAnnotations(); + + if (isset($annotations['method']['testdox'][0])) { + $this->currentTestMethodPrettified = $annotations['method']['testdox'][0]; + $prettified = TRUE; + } + } + + if (!$prettified) { + $this->currentTestMethodPrettified = $this->prettifier->prettifyTestMethod($test->getName(FALSE)); + } + + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED; + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + if (!isset($this->tests[$this->currentTestMethodPrettified])) { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $this->tests[$this->currentTestMethodPrettified]['success'] = 1; + $this->tests[$this->currentTestMethodPrettified]['failure'] = 0; + } else { + $this->tests[$this->currentTestMethodPrettified]['success'] = 0; + $this->tests[$this->currentTestMethodPrettified]['failure'] = 1; + } + } else { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $this->tests[$this->currentTestMethodPrettified]['success']++; + } else { + $this->tests[$this->currentTestMethodPrettified]['failure']++; + } + } + + $this->currentTestClassPrettified = NULL; + $this->currentTestMethodPrettified = NULL; + } + } + + /** + * @since Method available since Release 2.3.0 + */ + protected function doEndClass() + { + foreach ($this->tests as $name => $data) { + $this->onTest($name, $data['failure'] == 0); + } + + $this->endClass($this->testClass); + } + + /** + * Handler for 'start run' event. + * + */ + protected function startRun() + { + } + + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + */ + protected function onTest($name, $success = TRUE) + { + } + + /** + * Handler for 'end class' event. + * + * @param string $name + */ + protected function endClass($name) + { + } + + /** + * Handler for 'end run' event. + * + */ + protected function endRun() + { + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter/HTML.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter/HTML.php new file mode 100644 index 00000000..f1c27c21 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter/HTML.php @@ -0,0 +1,130 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/TestDox/ResultPrinter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Prints TestDox documentation in HTML format. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_TestDox_ResultPrinter_HTML extends PHPUnit_Util_TestDox_ResultPrinter +{ + /** + * @var boolean + */ + protected $printsHTML = TRUE; + + /** + * Handler for 'start run' event. + * + */ + protected function startRun() + { + $this->write(''); + } + + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + $this->write( + '

' . $this->currentTestClassPrettified . + '

    ' + ); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + */ + protected function onTest($name, $success = TRUE) + { + if (!$success) { + $strikeOpen = ''; + $strikeClose = ''; + } else { + $strikeOpen = ''; + $strikeClose = ''; + } + + $this->write('
  • ' . $strikeOpen . $name . $strikeClose . '
  • '); + } + + /** + * Handler for 'end class' event. + * + * @param string $name + */ + protected function endClass($name) + { + $this->write('
'); + } + + /** + * Handler for 'end run' event. + * + */ + protected function endRun() + { + $this->write(''); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter/Text.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter/Text.php new file mode 100644 index 00000000..52b1ecee --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestDox/ResultPrinter/Text.php @@ -0,0 +1,102 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 2.3.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; +require_once 'PHPUnit/Util/TestDox/ResultPrinter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Prints TestDox documentation in text format. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_TestDox_ResultPrinter_Text extends PHPUnit_Util_TestDox_ResultPrinter +{ + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + $this->write($this->currentTestClassPrettified . "\n"); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + */ + protected function onTest($name, $success = TRUE) + { + if ($success) { + $this->write(' [x] '); + } else { + $this->write(' [ ] '); + } + + $this->write($name . "\n"); + } + + /** + * Handler for 'end class' event. + * + * @param string $name + */ + protected function endClass($name) + { + $this->write("\n"); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestSuiteIterator.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestSuiteIterator.php new file mode 100644 index 00000000..aa1e3c10 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/TestSuiteIterator.php @@ -0,0 +1,154 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.1.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Iterator for test suites. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Util_TestSuiteIterator implements RecursiveIterator +{ + /** + * @var integer + */ + protected $position; + + /** + * @var PHPUnit_Framework_Test[] + */ + protected $tests; + + /** + * Constructor. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function __construct(PHPUnit_Framework_TestSuite $testSuite) + { + $this->tests = $testSuite->tests(); + } + + /** + * Rewinds the Iterator to the first element. + * + */ + public function rewind() + { + $this->position = 0; + } + + /** + * Checks if there is a current element after calls to rewind() or next(). + * + * @return boolean + */ + public function valid() + { + return $this->position < count($this->tests); + } + + /** + * Returns the key of the current element. + * + * @return integer + */ + public function key() + { + return $this->position; + } + + /** + * Returns the current element. + * + * @return PHPUnit_Framework_Test + */ + public function current() + { + return $this->valid() ? $this->tests[$this->position] : NULL; + } + + /** + * Moves forward to next element. + * + */ + public function next() + { + $this->position++; + } + + /** + * Returns the sub iterator for the current element. + * + * @return PHPUnit_Util_TestSuiteIterator + */ + public function getChildren() + { + return new PHPUnit_Util_TestSuiteIterator( + $this->tests[$this->position] + ); + } + + /** + * Checks whether the current element has children. + * + * @return boolean + */ + public function hasChildren() + { + return $this->tests[$this->position] instanceof PHPUnit_Framework_TestSuite; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Timer.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Timer.php new file mode 100644 index 00000000..665ee507 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Timer.php @@ -0,0 +1,130 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Utility class for timing. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Timer +{ + protected static $startTimes = array(); + + /** + * Starts the timer. + * + */ + public static function start() + { + array_push(self::$startTimes, microtime(TRUE)); + } + + /** + * Returns the currently elapsed time. + * + * @return float + */ + public static function current() + { + return microtime(TRUE) - self::$startTimes[count(self::$startTimes)-1]; + } + + /** + * Stops the timer and returns the elapsed time. + * + */ + public static function stop() + { + return microtime(TRUE) - array_pop(self::$startTimes); + } + + /** + * Formats elapsed time (in seconds) to a string. + * + * @param float $time + * @return float + */ + public static function secondsToTimeString($time) + { + $buffer = ''; + + $hours = sprintf('%02d', ($time >= 3600) ? floor($time / 3600) : 0); + $minutes = sprintf( + '%02d', + ($time >= 60) ? floor($time / 60) - 60 * $hours : 0 + ); + $seconds = sprintf('%02d', $time - 60 * 60 * $hours - 60 * $minutes); + + if ($hours == 0 && $minutes == 0) { + $seconds = sprintf('%1d', $seconds); + + $buffer .= $seconds . ' second'; + + if ($seconds != '1') { + $buffer .= 's'; + } + } else { + if ($hours > 0) { + $buffer = $hours . ':'; + } + + $buffer .= $minutes . ':' . $seconds; + } + + return $buffer; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Type.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Type.php new file mode 100644 index 00000000..2c5f1ae8 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/Type.php @@ -0,0 +1,197 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.0.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * Utility class for textual type (and value) representation. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Type +{ + public static function isType($type) + { + return in_array( + $type, + array( + 'numeric', + 'integer', + 'int', + 'float', + 'string', + 'boolean', + 'bool', + 'null', + 'array', + 'object', + 'resource', + 'scalar' + ) + ); + } + + public static function shortenedExport($value) + { + if (is_string($value)) { + return self::shortenedString($value); + } + + elseif (is_array($value)) { + if (count($value) == 0) { + return 'array()'; + } + + $a1 = array_slice($value, 0, 1, TRUE); + $k1 = key($a1); + $v1 = $a1[$k1]; + + if (is_string($v1)) { + $v1 = self::shortenedString($v1); + } + + elseif (is_array($v1)) { + $v1 = 'array(...)'; + } else { + $v1 = self::toString($v1); + } + + $a2 = FALSE; + + if (count($value) > 1) { + $a2 = array_slice($value, -1, 1, TRUE); + $k2 = key($a2); + $v2 = $a2[$k2]; + + if (is_string($v2)) { + $v2 = self::shortenedString($v2); + } + + elseif (is_array($v2)) { + $v2 = 'array(...)'; + } else { + $v2 = self::toString($v2); + } + } + + $text = 'array( ' . self::toString($k1) . ' => ' . $v1; + + if ($a2 !== FALSE) { + $text .= ', ..., ' . self::toString($k2) . ' => ' . $v2 . ' )'; + } else { + $text .= ' )'; + } + + return $text; + } + + elseif (is_object($value)) { + return get_class($value) . '(...)'; + } + + return self::toString($value); + } + + public static function shortenedString($string) + { + $string = preg_replace('#\n|\r\n|\r#', ' ', $string); + + if (strlen($string) > 14) { + return PHPUnit_Util_Type::toString( + substr($string, 0, 7) . '...' . substr($string, -7) + ); + } else { + return PHPUnit_Util_Type::toString($string); + } + } + + public static function toString($value, $short = FALSE) + { + if (is_array($value) || is_object($value)) { + if (!$short) { + return "\n" . print_r($value, TRUE); + } else { + if (is_array($value)) { + return ''; + } else { + return '<' . get_class($value) . '>'; + } + } + } + + if (is_string($value) && strpos($value, "\n") !== FALSE) { + return ''; + } + + if (!is_null($value)) { + $type = gettype($value) . ':'; + } else { + $type = ''; + $value = 'null'; + } + + if (is_bool($value)) { + if ($value === TRUE) { + $value = 'true'; + } + + else if ($value === FALSE) { + $value = 'false'; + } + } + + return '<' . $type . $value . '>'; + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/PHPUnit/Util/XML.php b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/XML.php new file mode 100644 index 00000000..1ee1c90d --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/PHPUnit/Util/XML.php @@ -0,0 +1,957 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @link http://www.phpunit.de/ + * @since File available since Release 3.2.0 + */ + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +/** + * XML helpers. + * + * @category Testing + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright 2002-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 3.4.9 + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_XML +{ + /** + * @param string $string + * @return string + * @author Kore Nordmann + * @since Method available since Release 3.4.6 + */ + public static function prepareString($string) + { + return preg_replace( + '([\\x00-\\x04\\x0b\\x0c\\x0e-\\x1f\\x7f])e', + 'sprintf( "&#x%02x;", ord( "\\1" ) )', + htmlspecialchars( + self::convertToUtf8($string), ENT_COMPAT, 'UTF-8' + ) + ); + } + + /** + * Converts a string to UTF-8 encoding. + * + * @param string $string + * @return string + * @since Method available since Release 3.2.19 + */ + protected static function convertToUtf8($string) + { + if (!self::isUtf8($string)) { + if (function_exists('mb_convert_encoding')) { + $string = mb_convert_encoding($string, 'UTF-8'); + } else { + $string = utf8_encode($string); + } + } + + return $string; + } + + /** + * Checks a string for UTF-8 encoding. + * + * @param string $string + * @return boolean + * @since Method available since Release 3.3.0 + */ + protected static function isUtf8($string) + { + $length = strlen($string); + + for ($i = 0; $i < $length; $i++) { + if (ord($string[$i]) < 0x80) { + $n = 0; + } + + else if ((ord($string[$i]) & 0xE0) == 0xC0) { + $n = 1; + } + + else if ((ord($string[$i]) & 0xF0) == 0xE0) { + $n = 2; + } + + else if ((ord($string[$i]) & 0xF0) == 0xF0) { + $n = 3; + } + + else { + return FALSE; + } + + for ($j = 0; $j < $n; $j++) { + if ((++$i == $length) || ((ord($string[$i]) & 0xC0) != 0x80)) { + return FALSE; + } + } + } + + return TRUE; + } + + /** + * Loads an XML (or HTML) file into a DOMDocument object. + * + * @param string $filename + * @param boolean $isHtml + * @return DOMDocument + * @since Method available since Release 3.3.0 + */ + public static function loadFile($filename, $isHtml = FALSE) + { + $reporting = error_reporting(0); + $contents = file_get_contents($filename); + error_reporting($reporting); + + if ($contents === FALSE) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not read "%s".', + $filename + ) + ); + } + + return self::load($contents, $isHtml, $filename); + } + + /** + * Load an $actual document into a DOMDocument. This is called + * from the selector assertions. + * + * If $actual is already a DOMDocument, it is returned with + * no changes. Otherwise, $actual is loaded into a new DOMDocument + * as either HTML or XML, depending on the value of $isHtml. + * + * Note: prior to PHPUnit 3.3.0, this method loaded a file and + * not a string as it currently does. To load a file into a + * DOMDocument, use loadFile() instead. + * + * @param string|DOMDocument $actual + * @param boolean $isHtml + * @param string $filename + * @return DOMDocument + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function load($actual, $isHtml = FALSE, $filename = '') + { + if ($actual instanceof DOMDocument) { + return $actual; + } + + $internal = libxml_use_internal_errors(TRUE); + $reporting = error_reporting(0); + $dom = new DOMDocument; + + if ($isHtml) { + $loaded = $dom->loadHTML($actual); + } else { + $loaded = $dom->loadXML($actual); + } + + libxml_use_internal_errors($internal); + error_reporting($reporting); + + if ($loaded === FALSE) { + $message = ''; + + foreach (libxml_get_errors() as $error) { + $message .= $error->message; + } + + if ($filename != '') { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not load "%s".%s', + + $filename, + $message != '' ? "\n" . $message : '' + ) + ); + } else { + throw new PHPUnit_Framework_Exception($message); + } + } + + return $dom; + } + + /** + * + * + * @param DOMNode $node + * @return string + * @since Method available since Release 3.4.0 + */ + public static function nodeToText(DOMNode $node) + { + $result = ''; + + foreach ($node->childNodes as $childNode) { + $result .= $node->ownerDocument->saveXML($childNode); + } + + return $result; + } + + /** + * + * + * @param DOMNode $node + * @since Method available since Release 3.3.0 + * @author Mattis Stordalen Flister + */ + public static function removeCharacterDataNodes(DOMNode $node) + { + if ($node->hasChildNodes()) { + for ($i = $node->childNodes->length - 1; $i >= 0; $i--) { + if (($child = $node->childNodes->item($i)) instanceof DOMCharacterData) { + $node->removeChild($child); + } + } + } + } + + /** + * "Convert" a DOMElement object into a PHP variable. + * + * @param DOMElement $element + * @return mixed + * @since Method available since Release 3.4.0 + */ + public static function xmlToVariable(DOMElement $element) + { + $variable = NULL; + + switch ($element->tagName) { + case 'array': { + $variable = array(); + + foreach ($element->getElementsByTagName('element') as $element) { + $value = self::xmlToVariable($element->childNodes->item(1)); + + if ($element->hasAttribute('key')) { + $variable[(string)$element->getAttribute('key')] = $value; + } else { + $variable[] = $value; + } + } + } + break; + + case 'object': { + $className = $element->getAttribute('class'); + + if ($element->hasChildNodes()) { + $arguments = $element->childNodes->item(1)->childNodes; + $constructorArgs = array(); + + foreach ($arguments as $argument) { + if ($argument instanceof DOMElement) { + $constructorArgs[] = self::xmlToVariable($argument); + } + } + + $class = new ReflectionClass($className); + $variable = $class->newInstanceArgs($constructorArgs); + } else { + $variable = new $className; + } + } + break; + + case 'boolean': { + $variable = $element->nodeValue == 'true' ? TRUE : FALSE; + } + break; + + case 'integer': + case 'double': + case 'string': { + $variable = $element->nodeValue; + + settype($variable, $element->tagName); + } + break; + } + + return $variable; + } + + /** + * Validate list of keys in the associative array. + * + * @param array $hash + * @param array $validKeys + * @return array + * @throws InvalidArgumentException + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertValidKeys(array $hash, array $validKeys) + { + $valids = array(); + + // Normalize validation keys so that we can use both indexed and + // associative arrays. + foreach ($validKeys as $key => $val) { + is_int($key) ? $valids[$val] = NULL : $valids[$key] = $val; + } + + $validKeys = array_keys($valids); + + // Check for invalid keys. + foreach ($hash as $key => $value) { + if (!in_array($key, $validKeys)) { + $unknown[] = $key; + } + } + + if (!empty($unknown)) { + throw new InvalidArgumentException( + 'Unknown key(s): ' . implode(', ', $unknown) + ); + } + + // Add default values for any valid keys that are empty. + foreach ($valids as $key => $value) { + if (!isset($hash[$key])) { + $hash[$key] = $value; + } + } + + return $hash; + } + + /** + * Parse a CSS selector into an associative array suitable for + * use with findNodes(). + * + * @param string $selector + * @param mixed $content + * @return array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function convertSelectToTag($selector, $content = TRUE) + { + $selector = trim(preg_replace("/\s+/", " ", $selector)); + + // substitute spaces within attribute value + while (preg_match('/\[[^\]]+"[^"]+\s[^"]+"\]/', $selector)) { + $selector = preg_replace( + '/(\[[^\]]+"[^"]+)\s([^"]+"\])/', "$1__SPACE__$2", $selector + ); + } + + if (strstr($selector, ' ')) { + $elements = explode(' ', $selector); + } else { + $elements = array($selector); + } + + $previousTag = array(); + + foreach (array_reverse($elements) as $element) { + $element = str_replace('__SPACE__', ' ', $element); + + // child selector + if ($element == '>') { + $previousTag = array('child' => $previousTag['descendant']); + continue; + } + + $tag = array(); + + // match element tag + preg_match("/^([^\.#\[]*)/", $element, $eltMatches); + + if (!empty($eltMatches[1])) { + $tag['tag'] = $eltMatches[1]; + } + + // match attributes (\[[^\]]*\]*), ids (#[^\.#\[]*), + // and classes (\.[^\.#\[]*)) + preg_match_all( + "/(\[[^\]]*\]*|#[^\.#\[]*|\.[^\.#\[]*)/", $element, $matches + ); + + if (!empty($matches[1])) { + $classes = array(); + $attrs = array(); + + foreach ($matches[1] as $match) { + // id matched + if (substr($match, 0, 1) == '#') { + $tag['id'] = substr($match, 1); + } + + // class matched + else if (substr($match, 0, 1) == '.') { + $classes[] = substr($match, 1); + } + + // attribute matched + else if (substr($match, 0, 1) == '[' && + substr($match, -1, 1) == ']') { + $attribute = substr($match, 1, strlen($match) - 2); + $attribute = str_replace('"', '', $attribute); + + // match single word + if (strstr($attribute, '~=')) { + list($key, $value) = explode('~=', $attribute); + $value = "regexp:/.*\b$value\b.*/"; + } + + // match substring + else if (strstr($attribute, '*=')) { + list($key, $value) = explode('*=', $attribute); + $value = "regexp:/.*$value.*/"; + } + + // exact match + else { + list($key, $value) = explode('=', $attribute); + } + + $attrs[$key] = $value; + } + } + + if ($classes) { + $tag['class'] = join(' ', $classes); + } + + if ($attrs) { + $tag['attributes'] = $attrs; + } + } + + // tag content + if (is_string($content)) { + $tag['content'] = $content; + } + + // determine previous child/descendants + if (!empty($previousTag['descendant'])) { + $tag['descendant'] = $previousTag['descendant']; + } + + else if (!empty($previousTag['child'])) { + $tag['child'] = $previousTag['child']; + } + + $previousTag = array('descendant' => $tag); + } + + return $tag; + } + + /** + * Parse an $actual document and return an array of DOMNodes + * matching the CSS $selector. If an error occurs, it will + * return FALSE. + * + * To only return nodes containing a certain content, give + * the $content to match as a string. Otherwise, setting + * $content to TRUE will return all nodes matching $selector. + * + * The $actual document may be a DOMDocument or a string + * containing XML or HTML, identified by $isHtml. + * + * @param array $selector + * @param string $content + * @param mixed $actual + * @param boolean $isHtml + * @return false|array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function cssSelect($selector, $content, $actual, $isHtml = TRUE) + { + $matcher = self::convertSelectToTag($selector, $content); + $dom = self::load($actual, $isHtml); + $tags = self::findNodes($dom, $matcher); + + return $tags; + } + + /** + * Parse out the options from the tag using DOM object tree. + * + * @param DOMDocument $dom + * @param array $options + * @param boolean $isHtml + * @return array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function findNodes(DOMDocument $dom, array $options, $isHtml = TRUE) + { + $valid = array( + 'id', 'class', 'tag', 'content', 'attributes', 'parent', + 'child', 'ancestor', 'descendant', 'children' + ); + + $filtered = array(); + $options = self::assertValidKeys($options, $valid); + + // find the element by id + if ($options['id']) { + $options['attributes']['id'] = $options['id']; + } + + if ($options['class']) { + $options['attributes']['class'] = $options['class']; + } + + // find the element by a tag type + if ($options['tag']) { + if ($isHtml) { + $elements = self::getElementsByCaseInsensitiveTagName( + $dom, $options['tag'] + ); + } else { + $elements = $dom->getElementsByTagName($options['tag']); + } + + foreach ($elements as $element) { + $nodes[] = $element; + } + + if (empty($nodes)) { + return FALSE; + } + } + + // no tag selected, get them all + else { + $tags = array( + 'a', 'abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo', + 'big', 'blockquote', 'body', 'br', 'button', 'caption', 'cite', + 'code', 'col', 'colgroup', 'dd', 'del', 'div', 'dfn', 'dl', + 'dt', 'em', 'fieldset', 'form', 'frame', 'frameset', 'h1', 'h2', + 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'i', 'iframe', + 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link', + 'map', 'meta', 'noframes', 'noscript', 'object', 'ol', 'optgroup', + 'option', 'p', 'param', 'pre', 'q', 'samp', 'script', 'select', + 'small', 'span', 'strong', 'style', 'sub', 'sup', 'table', + 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', + 'tr', 'tt', 'ul', 'var' + ); + + foreach ($tags as $tag) { + if ($isHtml) { + $elements = self::getElementsByCaseInsensitiveTagName( + $dom, $tag + ); + } else { + $elements = $dom->getElementsByTagName($tag); + } + + foreach ($elements as $element) { + $nodes[] = $element; + } + } + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by attributes + if ($options['attributes']) { + foreach ($nodes as $node) { + $invalid = FALSE; + + foreach ($options['attributes'] as $name => $value) { + // match by regexp if like "regexp:/foo/i" + if (preg_match('/^regexp\s*:\s*(.*)/i', $value, $matches)) { + if (!preg_match($matches[1], $node->getAttribute($name))) { + $invalid = TRUE; + } + } + + // class can match only a part + else if ($name == 'class') { + // split to individual classes + $findClasses = explode( + ' ', preg_replace("/\s+/", " ", $value) + ); + + $allClasses = explode( + ' ', + preg_replace("/\s+/", " ", $node->getAttribute($name)) + ); + + // make sure each class given is in the actual node + foreach ($findClasses as $findClass) { + if (!in_array($findClass, $allClasses)) { + $invalid = TRUE; + } + } + } + + // match by exact string + else { + if ($node->getAttribute($name) != $value) { + $invalid = TRUE; + } + } + } + + // if every attribute given matched + if (!$invalid) { + $filtered[] = $node; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by content + if ($options['content'] !== NULL) { + foreach ($nodes as $node) { + $invalid = FALSE; + + // match by regexp if like "regexp:/foo/i" + if (preg_match('/^regexp\s*:\s*(.*)/i', $options['content'], $matches)) { + if (!preg_match($matches[1], self::getNodeText($node))) { + $invalid = TRUE; + } + } + + // match by exact string + else if (strstr(self::getNodeText($node), $options['content']) === FALSE) { + $invalid = TRUE; + } + + if (!$invalid) { + $filtered[] = $node; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by parent node + if ($options['parent']) { + $parentNodes = self::findNodes($dom, $options['parent']); + $parentNode = isset($parentNodes[0]) ? $parentNodes[0] : NULL; + + foreach ($nodes as $node) { + if ($parentNode !== $node->parentNode) { + break; + } + + $filtered[] = $node; + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by child node + if ($options['child']) { + $childNodes = self::findNodes($dom, $options['child']); + $childNodes = !empty($childNodes) ? $childNodes : array(); + + foreach ($nodes as $node) { + foreach ($node->childNodes as $child) { + foreach ($childNodes as $childNode) { + if ($childNode === $child) { + $filtered[] = $node; + } + } + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by ancestor + if ($options['ancestor']) { + $ancestorNodes = self::findNodes($dom, $options['ancestor']); + $ancestorNode = isset($ancestorNodes[0]) ? $ancestorNodes[0] : NULL; + + foreach ($nodes as $node) { + $parent = $node->parentNode; + + while ($parent->nodeType != XML_HTML_DOCUMENT_NODE) { + if ($parent === $ancestorNode) { + $filtered[] = $node; + } + + $parent = $parent->parentNode; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by descendant + if ($options['descendant']) { + $descendantNodes = self::findNodes($dom, $options['descendant']); + $descendantNodes = !empty($descendantNodes) ? $descendantNodes : array(); + + foreach ($nodes as $node) { + foreach (self::getDescendants($node) as $descendant) { + foreach ($descendantNodes as $descendantNode) { + if ($descendantNode === $descendant) { + $filtered[] = $node; + } + } + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return FALSE; + } + } + + // filter by children + if ($options['children']) { + $validChild = array('count', 'greater_than', 'less_than', 'only'); + $childOptions = self::assertValidKeys( + $options['children'], $validChild + ); + + foreach ($nodes as $node) { + $childNodes = $node->childNodes; + + foreach ($childNodes as $childNode) { + if ($childNode->nodeType !== XML_CDATA_SECTION_NODE && + $childNode->nodeType !== XML_TEXT_NODE) { + $children[] = $childNode; + } + } + + // we must have children to pass this filter + if (!empty($children)) { + // exact count of children + if ($childOptions['count'] !== NULL) { + if (count($children) !== $childOptions['count']) { + break; + } + } + + // range count of children + else if ($childOptions['less_than'] !== NULL && + $childOptions['greater_than'] !== NULL) { + if (count($children) >= $childOptions['less_than'] || + count($children) <= $childOptions['greater_than']) { + break; + } + } + + // less than a given count + else if ($childOptions['less_than'] !== NULL) { + if (count($children) >= $childOptions['less_than']) { + break; + } + } + + // more than a given count + else if ($childOptions['greater_than'] !== NULL) { + if (count($children) <= $childOptions['greater_than']) { + break; + } + } + + // match each child against a specific tag + if ($childOptions['only']) { + $onlyNodes = self::findNodes( + $dom, $childOptions['only'] + ); + + // try to match each child to one of the 'only' nodes + foreach ($children as $child) { + $matched = FALSE; + + foreach ($onlyNodes as $onlyNode) { + if ($onlyNode === $child) { + $matched = TRUE; + } + } + + if (!$matched) { + break(2); + } + } + } + + $filtered[] = $node; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return; + } + } + + // return the first node that matches all criteria + return !empty($nodes) ? $nodes : array(); + } + + /** + * Recursively get flat array of all descendants of this node. + * + * @param DOMNode $node + * @return array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + protected static function getDescendants(DOMNode $node) + { + $allChildren = array(); + $childNodes = $node->childNodes ? $node->childNodes : array(); + + foreach ($childNodes as $child) { + if ($child->nodeType === XML_CDATA_SECTION_NODE || + $child->nodeType === XML_TEXT_NODE) { + continue; + } + + $children = self::getDescendants($child); + $allChildren = array_merge($allChildren, $children, array($child)); + } + + return isset($allChildren) ? $allChildren : array(); + } + + /** + * Gets elements by case insensitive tagname. + * + * @param DOMDocument $dom + * @param string $tag + * @return DOMNodeList + * @since Method available since Release 3.4.0 + */ + protected static function getElementsByCaseInsensitiveTagName(DOMDocument $dom, $tag) + { + $elements = $dom->getElementsByTagName(strtolower($tag)); + + if ($elements->length == 0) { + $elements = $dom->getElementsByTagName(strtoupper($tag)); + } + + return $elements; + } + + /** + * Get the text value of this node's child text node. + * + * @param DOMNode $node + * @return string + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + protected static function getNodeText(DOMNode $node) + { + if (!$node->childNodes instanceof DOMNodeList) { + return ''; + } + + $result = ''; + + foreach ($node->childNodes as $childNode) { + if ($childNode->nodeType === XML_TEXT_NODE) { + $result .= trim($childNode->data) . ' '; + } else { + $result .= self::getNodeText($childNode); + } + } + + return str_replace(' ', ' ', $result); + } +} +?> diff --git a/_unittests/PHPUnit-3.4.9/dbunit.bat b/_unittests/PHPUnit-3.4.9/dbunit.bat new file mode 100644 index 00000000..4cb0d14a --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/dbunit.bat @@ -0,0 +1,38 @@ +@echo off +REM PHPUnit +REM +REM Copyright (c) 2002-2010, Sebastian Bergmann . +REM All rights reserved. +REM +REM Redistribution and use in source and binary forms, with or without +REM modification, are permitted provided that the following conditions +REM are met: +REM +REM * Redistributions of source code must retain the above copyright +REM notice, this list of conditions and the following disclaimer. +REM +REM * Redistributions in binary form must reproduce the above copyright +REM notice, this list of conditions and the following disclaimer in +REM the documentation and/or other materials provided with the +REM distribution. +REM +REM * Neither the name of Sebastian Bergmann nor the names of his +REM contributors may be used to endorse or promote products derived +REM from this software without specific prior written permission. +REM +REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +REM "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +REM LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +REM FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +REM COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +REM INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +REM BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +REM LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC +REM LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +REM ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +REM POSSIBILITY OF SUCH DAMAGE. +REM + +set PHPBIN="@php_bin@" +"@php_bin@" "@bin_dir@\dbunit" %* diff --git a/_unittests/PHPUnit-3.4.9/dbunit.php b/_unittests/PHPUnit-3.4.9/dbunit.php new file mode 100755 index 00000000..fd06b820 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/dbunit.php @@ -0,0 +1,63 @@ +#!/usr/bin/env php +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +if (strpos('@php_bin@', '@php_bin') === 0) { + set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path()); +} + +if (isset($_ENV['PWD'])) { + chdir($_ENV['PWD']); +} + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +require_once 'PHPUnit/Extensions/Database/UI/Command.php'; +require_once 'PHPUnit/Extensions/Database/UI/ModeFactory.php'; +require_once 'PHPUnit/Extensions/Database/UI/Mediums/Text.php'; +require_once 'PHPUnit/Extensions/Database/UI/Context.php'; + +$command = new PHPUnit_Extensions_Database_UI_Command( + new PHPUnit_Extensions_Database_UI_ModeFactory() +); + +$command->main( + new PHPUnit_Extensions_Database_UI_Mediums_Text($_SERVER['argv']), + new PHPUnit_Extensions_Database_UI_Context() +); +?> diff --git a/_unittests/PHPUnit-3.4.9/phpunit.bat b/_unittests/PHPUnit-3.4.9/phpunit.bat new file mode 100644 index 00000000..03c113f8 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/phpunit.bat @@ -0,0 +1,38 @@ +@echo off +REM PHPUnit +REM +REM Copyright (c) 2002-2010, Sebastian Bergmann . +REM All rights reserved. +REM +REM Redistribution and use in source and binary forms, with or without +REM modification, are permitted provided that the following conditions +REM are met: +REM +REM * Redistributions of source code must retain the above copyright +REM notice, this list of conditions and the following disclaimer. +REM +REM * Redistributions in binary form must reproduce the above copyright +REM notice, this list of conditions and the following disclaimer in +REM the documentation and/or other materials provided with the +REM distribution. +REM +REM * Neither the name of Sebastian Bergmann nor the names of his +REM contributors may be used to endorse or promote products derived +REM from this software without specific prior written permission. +REM +REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +REM "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +REM LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +REM FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +REM COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +REM INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +REM BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +REM LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC +REM LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +REM ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +REM POSSIBILITY OF SUCH DAMAGE. +REM + +set PHPBIN="@php_bin@" +%PHPBIN% "@bin_dir@\phpunit" %* diff --git a/_unittests/PHPUnit-3.4.9/phpunit.php b/_unittests/PHPUnit-3.4.9/phpunit.php new file mode 100755 index 00000000..57a0f211 --- /dev/null +++ b/_unittests/PHPUnit-3.4.9/phpunit.php @@ -0,0 +1,55 @@ +#!/usr/bin/env php +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +if (extension_loaded('xdebug')) { + ini_set('xdebug.show_exception_trace', 0); +} + +if (strpos('@php_bin@', '@php_bin') === 0) { + set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path()); +} + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +require 'PHPUnit/TextUI/Command.php'; + +define('PHPUnit_MAIN_METHOD', 'PHPUnit_TextUI_Command::main'); + +PHPUnit_TextUI_Command::main(); +?> diff --git a/appleseed.framework.tmp/htaccess.original b/appleseed.framework.tmp/htaccess.original new file mode 100644 index 00000000..e44cbdbe --- /dev/null +++ b/appleseed.framework.tmp/htaccess.original @@ -0,0 +1,6 @@ +RewriteEngine On + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule (.*) system/initialize.php + diff --git a/foundations/default/default.conf b/foundations/default/default.conf new file mode 100644 index 00000000..81074e01 --- /dev/null +++ b/foundations/default/default.conf @@ -0,0 +1,6 @@ +# Inherit from parent foundation +# parent= + +# Routes +route[profile/]=profile/wall.php +route[profile/(.*)/messages]=profile/messages.php diff --git a/libraries/external/PHPMailer_v5.1/LICENSE b/libraries/external/PHPMailer_v5.1/LICENSE new file mode 100644 index 00000000..03851a33 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libraries/external/PHPMailer_v5.1/README b/libraries/external/PHPMailer_v5.1/README new file mode 100644 index 00000000..2d79f386 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/README @@ -0,0 +1,218 @@ +/******************************************************************* +* The http://phpmailer.codeworxtech.com/ website now carries a few * +* advertisements through the Google Adsense network. Please visit * +* the advertiser sites and help us offset some of our costs. * +* Thanks .... * +********************************************************************/ + +PHPMailer +Full Featured Email Transfer Class for PHP +========================================== + +Version 5.0.0 (April 02, 2009) + +With the release of this version, we are initiating a new version numbering +system to differentiate from the PHP4 version of PHPMailer. + +Most notable in this release is fully object oriented code. + +We now have available the PHPDocumentor (phpdocs) documentation. This is +separate from the regular download to keep file sizes down. Please see the +download area of http://phpmailer.codeworxtech.com. + +We also have created a new test script (see /test_script) that you can use +right out of the box. Copy the /test_script folder directly to your server (in +the same structure ... with class.phpmailer.php and class.smtp.php in the +folder above it. Then launch the test script with: +http://www.yourdomain.com/phpmailer/test_script/index.php +from this one script, you can test your server settings for mail(), sendmail (or +qmail), and SMTP. This will email you a sample email (using contents.html for +the email body) and two attachments. One of the attachments is used as an inline +image to demonstrate how PHPMailer will automatically detect if attachments are +the same source as inline graphics and only include one version. Once you click +the Submit button, the results will be displayed including any SMTP debug +information and send status. We will also display a version of the script that +you can cut and paste to include in your projects. Enjoy! + +Version 2.3 (November 08, 2008) + +We have removed the /phpdoc from the downloads. All documentation is now on +the http://phpmailer.codeworxtech.com website. + +The phpunit.php has been updated to support PHP5. + +For all other changes and notes, please see the changelog. + +Donations are accepted at PayPal with our id "paypal@worxteam.com". + +Version 2.2 (July 15 2008) + +- see the changelog. + +Version 2.1 (June 04 2008) + +With this release, we are announcing that the development of PHPMailer for PHP5 +will be our focus from this date on. We have implemented all the enhancements +and fixes from the latest release of PHPMailer for PHP4. + +Far more important, though, is that this release of PHPMailer (v2.1) is +fully tested with E_STRICT error checking enabled. + +** NOTE: WE HAVE A NEW LANGUAGE VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. + IF YOU CAN HELP WITH LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE + APPRECIATED. + +We have now added S/MIME functionality (ability to digitally sign emails). +BIG THANKS TO "sergiocambra" for posting this patch back in November 2007. +The "Signed Emails" functionality adds the Sign method to pass the private key +filename and the password to read it, and then email will be sent with +content-type multipart/signed and with the digital signature attached. + +A quick note on E_STRICT: + +- In about half the test environments the development version was subjected + to, an error was thrown for the date() functions (used at line 1565 and 1569). + This is NOT a PHPMailer error, it is the result of an incorrectly configured + PHP5 installation. The fix is to modify your 'php.ini' file and include the + date.timezone = America/New York + directive, (for your own server timezone) +- If you do get this error, and are unable to access your php.ini file, there is + a workaround. In your PHP script, add + date_default_timezone_set('America/Toronto'); + + * do NOT try to use + $myVar = date_default_timezone_get(); + as a test, it will throw an error. + +We have also included more example files to show the use of "sendmail", "mail()", +"smtp", and "gmail". + +We are also looking for more programmers to join the volunteer development team. +If you have an interest in this, please let us know. + +Enjoy! + + +Version 2.1.0beta1 & beta2 + +please note, this is BETA software +** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS +INTENDED STRICTLY FOR TESTING + +** NOTE: + +As of November 2007, PHPMailer has a new project team headed by industry +veteran Andy Prevost (codeworxtech). The first release in more than two +years will focus on fixes, adding ease-of-use enhancements, provide +basic compatibility with PHP4 and PHP5 using PHP5 backwards compatibility +features. A new release is planned before year-end 2007 that will provide +full compatiblity with PHP4 and PHP5, as well as more bug fixes. + +We are looking for project developers to assist in restoring PHPMailer to +its leadership position. Our goals are to simplify use of PHPMailer, provide +good documentation and examples, and retain backward compatibility to level +1.7.3 standards. + +If you are interested in helping out, visit http://sourceforge.net/projects/phpmailer +and indicate your interest. + +** + +http://phpmailer.sourceforge.net/ + +This software is licenced under the LGPL. Please read LICENSE for information on the +software availability and distribution. + +Class Features: +- Send emails with multiple TOs, CCs, BCCs and REPLY-TOs +- Redundant SMTP servers +- Multipart/alternative emails for mail clients that do not read HTML email +- Support for 8bit, base64, binary, and quoted-printable encoding +- Uses the same methods as the very popular AspEmail active server (COM) component +- SMTP authentication +- Native language support +- Word wrap, and more! + +Why you might need it: + +Many PHP developers utilize email in their code. The only PHP function +that supports this is the mail() function. However, it does not expose +any of the popular features that many email clients use nowadays like +HTML-based emails and attachments. There are two proprietary +development tools out there that have all the functionality built into +easy to use classes: AspEmail(tm) and AspMail. Both of these +programs are COM components only available on Windows. They are also a +little pricey for smaller projects. + +Since I do Linux development I�ve missed these tools for my PHP coding. +So I built a version myself that implements the same methods (object +calls) that the Windows-based components do. It is open source and the +LGPL license allows you to place the class in your proprietary PHP +projects. + + +Installation: + +Copy class.phpmailer.php into your php.ini include_path. If you are +using the SMTP mailer then place class.smtp.php in your path as well. +In the language directory you will find several files like +phpmailer.lang-en.php. If you look right before the .php extension +that there are two letters. These represent the language type of the +translation file. For instance "en" is the English file and "br" is +the Portuguese file. Chose the file that best fits with your language +and place it in the PHP include path. If your language is English +then you have nothing more to do. If it is a different language then +you must point PHPMailer to the correct translation. To do this, call +the PHPMailer SetLanguage method like so: + +// To load the Portuguese version +$mail->SetLanguage("br", "/optional/path/to/language/directory/"); + +That's it. You should now be ready to use PHPMailer! + + +A Simple Example: + +IsSMTP(); // set mailer to use SMTP +$mail->Host = "smtp1.example.com;smtp2.example.com"; // specify main and backup server +$mail->SMTPAuth = true; // turn on SMTP authentication +$mail->Username = "jswan"; // SMTP username +$mail->Password = "secret"; // SMTP password + +$mail->From = "from@example.com"; +$mail->FromName = "Mailer"; +$mail->AddAddress("josh@example.net", "Josh Adams"); +$mail->AddAddress("ellen@example.com"); // name is optional +$mail->AddReplyTo("info@example.com", "Information"); + +$mail->WordWrap = 50; // set word wrap to 50 characters +$mail->AddAttachment("/var/tmp/file.tar.gz"); // add attachments +$mail->AddAttachment("/tmp/image.jpg", "new.jpg"); // optional name +$mail->IsHTML(true); // set email format to HTML + +$mail->Subject = "Here is the subject"; +$mail->Body = "This is the HTML message body in bold!"; +$mail->AltBody = "This is the body in plain text for non-HTML mail clients"; + +if(!$mail->Send()) +{ + echo "Message could not be sent.

"; + echo "Mailer Error: " . $mail->ErrorInfo; + exit; +} + +echo "Message has been sent"; +?> + +CHANGELOG + +See ChangeLog.txt + +Download: http://sourceforge.net/project/showfiles.php?group_id=26031 + +Andy Prevost diff --git a/libraries/external/PHPMailer_v5.1/aboutus.html b/libraries/external/PHPMailer_v5.1/aboutus.html new file mode 100644 index 00000000..70f3e0fc --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/aboutus.html @@ -0,0 +1,169 @@ + + + + + + +

+
+
+The http://phpmailer.codeworxtech.com/ website now carries a few +advertisements through the Google Adsense network to help offset +some of our costs.
+Thanks ....
+
+

PHPMailer is the world's leading email transport class and downloaded an +average of more than 32,000 each month. In March 2009, PHPMailer was downloaded +more than 31,000 times -- that's an average of 1,000 downloads daily. Our thanks +to our new users and loyal users. We understand you have many choices available +to select from and we thank you for select our fast and stable tool for your +website and projects.

+

Credits:
+PHPMailer's original founder is Brent Matzelle. The current team is:
+Project Administrator: Andy Prevost (codeworxtech), + +codeworxtech@users.sourceforge.net
+Author: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net
+Author: Marcus Bointon (coolbru) +coolbru@users.sourceforge.net

+

PHPMailer is used in many projects ranging from Open Source to commercial +packages. Our LGPL licensing terms are very flexible and allow for including +PHPMailer to enhance projects of all types. If you discover PHPMailer being used +in a project, please let us know about it.

+

WHY USE OUR TOOLS & WHAT'S IN IT FOR YOU?

+

A valid question. We're developers too. We've been writing software, primarily for the internet, for more than 15 years. Along the way, there are two major things that had tremendous impact of our company: PHP and Open Source. PHP is without doubt the most popular platform for the internet. There has been more progress in this area of technology because of Open Source software than in any other IT segment. We have used many open source tools, some as learning tools, some as components in projects we were working on. To us, it's not about popularity ... we're committed to robust, stable, and efficient tools you can use to get your projects in your user's hands quickly. So the shorter answer: what's in it for you? rapid development and rapid deployment without fuss and with straight forward open source licensing.

+

Now, here's our team:

+ + + + + + + + + +
About Andy Prevost, AKA "codeworxtech".About Marcus Bointon, AKA "coolbru".
+

www.codeworxtech.com for more information.
+ Web design, web applications, forms: WorxStudio.com
+

+

Our company, Worx International Inc., is the publisher of several Open Source applications and developer tools as well as several commercial PHP applications. The Open Source applications are ttCMS and DCP Portal. The Open Source developer tools include QuickComponents (QuickSkin and QuickCache) and now PHPMailer. + We have staff and offices in the United States, Caribbean, the Middle + East, and our primary development center in Canada. Our company is represented by + agents and resellers globally.

+

Worx International Inc. is at the forefront of developing PHP applications. Our staff are all Zend Certified university educated and experts at object oriented programming. While Worx International Inc. can handle any project from trouble shooting programs written by others all the way to finished mission-critical applications, we specialize in taking projects from inception all the way through to implementation - on budget, and on time. If you need help with your projects, we're the team to get it done right at a reasonable price.

+

Over the years, there have been a number of tools that have been constant favorites in all of our projects. We have become the project administrators for most of these tools.

+

Our developer tools are all Open Source. Here's a brief description:

+
    +
  • PHPMailer. Originally authored by Brent Matzelle, PHPMailer is the leading "email transfer class" for PHP. PHPMailer is downloaded more than + 26000 times each and every month by developers looking for a fast, stable, simple email solution. We used it ourselves for years as our favorite tool. It's always been small (the entire footprint is + less than 100 Kb), stable, and as complete a solution as you can find. + Other tools are nowhere near as simple. Our thanks to Brent Matzelle for this superb tool - our commitment is to keep it lean, keep it focused, and compliant with standards. Visit the PHPMailer website at + http://phpmailer.codeworxtech.com/.
    + Please note: all of our focus is now on the PHPMailer for PHP5.
    + PS. While you are at it, please visit our sponsor's sites, click on their ads. + It helps offset some of our costs.
    + Want to help? We're looking for progressive developers to join our team of volunteer professionals working on PHPMailer. Our entire focus is on PHPMailer + for PHP5. If you are interested, let us know.
    +
    +
  • +
  • QuickCache. Originally authored by Jean Pierre Deckers as jpCache, QuickCache is an HTTP OpCode caching strategy that works on your entire site with only one line of code at the top of your script. The cached pages can be stored as files or as database objects. The benefits are absolutely astounding: bandwidth savings of up to 80% and screen display times increased by 8 - 10x. Visit the QuickCache website at + http://quickcache.codeworxtech.com/.
    +
    +
  • +
  • QuickSkin. Originally authored by Philipp v. Criegern and named "SmartTemplate". The project was taken over by Manuel 'EndelWar' Dalla Lana and now by "codeworxtech". QuickSkin is one of the truly outstanding templating engines available, but has always been confused with Smarty Templating Engine. QuickSkin is even more relevant today than when it was launched. It's a small footprint with big impact on your projects. It features a built in caching technology, token based substitution, and works on the concept of one single HTML file as the template. The HTML template file can contain variable information making it one small powerful tool for your developer tool kit. Visit the QuickSkin website at + http://quickskin.codeworxtech.com/.
    +
    +
  • +
+

We're committed to PHP and to the Open Source community.

+

Opportunities with Worx International Inc.:

+
    +
  • Resellers/Agents: We're always interested in talking with companies that + want to represent + Worx International Inc. in their markets. We also have private label programs for our commercial products (in certain circumstances).
  • +
  • Programmers/Developers: We are usually fully staffed, however, if you would like to be considered for a career with + Worx International Inc., we would be pleased to hear from you.
    + A few things to note:
    +
      +
    • experience level does not matter: from fresh out of college to multi-year experience - it's your + creative mind and a positive attitude we want
    • +
    • if you contact us looking for employment, include a cover letter, indicate what type of work/career you are looking for and expected compensation
    • +
    • if you are representing someone else looking for work, do not contact us. We have an exclusive relationship with a recruiting partner already and not interested in altering the arrangement. We will not hire your candidate under any circumstances unless they wish to approach us individually.
    • +
    • any contact that ignores any of these points will be discarded
    • +
  • +
  • Affiliates/Partnerships: We are interested in partnering with other firms who are leaders in their field. We clearly understand that successful companies are built on successful relationships in all industries world-wide. We currently have innovative relationships throughout the world that are mutually beneficial. Drop us a line and let's talk.
  • +
+ Regards,
+ Andy Prevost (aka, codeworxtech)
+ codeworxtech@users.sourceforge.net
+
+ We now also offer website design. hosting, and remote forms processing. Visit WorxStudio.com for more information.
+
+

Marcus is the technical director of Synchromedia Limited, a UK-based company providing online business services. Synchromedia's main services are:

+

Smartmessages.net

+

Smartmessages.net logo
Smartmessages.net
is Synchromedia's large-scale mailing list management system, providing email delivery services for a wide range of businesses, from sole traders to corporates. + We pride ourselves on personal service, and realise that every one of your subscribers is a precious asset to be handled with care. + We provide fast, reliable, high-volume delivery (some of our customers have lists of more than 1,000,000 subscribers) with fine-grained tracking while ensuring you stay fully compliant with UK, EC and US data protection laws. Smartmessages of course uses PHPMailer at its heart!

+

info@hand

+

info@hand logo
Synchromedia is the official UK distributor of info@hand, a class-leading open-source web-based CRM system. We provide licenses, hosting, planning, support and training for this very fully-featured system at very competitive prices. info@hand also uses PHPMailer!

+

How can we help you?

+

In addition to our headline services, we also provide consulting, development, hosting and sysadmin services, so if you just need a simple web hosting package, we can do that too. Not surprisingly, we know rather a lot about email, so you can talk to us about that too.

+

Please contact us if you'd like to know more.

+

Marcus is a regular attendee at PHP London, and occasionally speaks on email at technical conferences.

+
+
+
+ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/changelog.txt b/libraries/external/PHPMailer_v5.1/changelog.txt new file mode 100644 index 00000000..dc43a4b6 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/changelog.txt @@ -0,0 +1,408 @@ +ChangeLog + +NOTE: THIS VERSION OF PHPMAILER IS DESIGNED FOR PHP5/PHP6. + IT WILL NOT WORK WITH PHP4. + +Version 5.1 (October 20, 2009) +* fixed filename issue with AddStringAttachment (thanks to Tony) +* fixed "SingleTo" property, now works with Senmail, Qmail, and SMTP in + addition to PHP mail() +* added DKIM digital signing functionality + New properties: + - DKIM_domain (sets the domain name) + - DKIM_private (holds DKIM private key) + - DKIM_passphrase (holds your DKIM passphrase) + - DKIM_selector (holds the DKIM "selector") + - DKIM_identity (holds the identifying email address) +* added callback function support + - callback function parameters include: + result, to, cc, bcc, subject and body + * see the test/test_callback.php file for usage. +* added "auto" identity functionality + - can automatically add: + - Return-path (if Sender not set) + - Reply-To (if ReplyTo not set) + - can be disabled: + - $mail->SetFrom('yourname@yourdomain.com','First Last',false); + - or by adding the $mail->Sender and/or $mail->ReplyTo properties + Note: "auto" identity added to help with emails ending up in spam + or junk boxes because of missing headers + +Version 5.0.2 (May 24, 2009) +* Fix for missing attachments when inline graphics are present +* Fix for missing Cc in header when using SMTP (mail was sent, + but not displayed in header -- Cc receiver only saw email To: + line and no Cc line, but did get the email (To receiver + saw same) + +Version 5.0.1 (April 05, 2009) +* Temporary fix for missing attachments + +Version 5.0.0 (April 02, 2009) + +* With the release of this version, we are initiating a new version numbering + system to differentiate from the PHP4 version of PHPMailer. +* Most notable in this release is fully object oriented code. +class.smtp.php: +* Refactored class.smtp.php to support new exception handling + code size reduced from 29.2 Kb to 25.6 Kb +* Removed unnecessary functions from class.smtp.php: + public function Expand($name) { + public function Help($keyword="") { + public function Noop() { + public function Send($from) { + public function SendOrMail($from) { + public function Verify($name) { +class.phpmailer.php: +* Refactored class.phpmailer.php with new exception handling +* Changed processing functionality of Sendmail and Qmail so they cannot be + inadvertently used +* removed getFile() function, just became a simple wrapper for + file_get_contents() +* added check for PHP version (will gracefully exit if not at least PHP 5.0) +class.phpmailer.php enhancements +* enhanced code to check if an attachment source is the same as an embedded or + inline graphic source to eliminate duplicate attachments +New /test_script +* We have written a test script you can use to test the script as part of your + installation. Once you press submit, the test script will send a multi-mime + email with either the message you type in or an HTML email with an inline + graphic. Two attachments are included in the email (one of the attachments + is also the inline graphic so you can see that only one copy of the graphic + is sent in the email). The test script will also display the functional + script that you can copy/paste to your editor to duplicate the functionality. +New examples +* All new examples in both basic and advanced modes. Advanced examples show + Exception handling. +PHPDocumentator (phpdocs) documentation for PHPMailer version 5.0.0 +* all new documentation + +Please note: the website has been updated to reflect the changes in PHPMailer +version 5.0.0. http://phpmailer.codeworxtech.com/ + +Version 2.3 (November 06, 2008) + +* added Arabic language (many thanks to Bahjat Al Mostafa) +* removed English language from language files and made it a default within + class.phpmailer.php - if no language is found, it will default to use + the english language translation +* fixed public/private declarations +* corrected line 1728, $basedir to $directory +* added $sign_cert_file to avoid improper duplicate use of $sign_key_file +* corrected $this->Hello on line 612 to $this->Helo +* changed default of $LE to "\r\n" to comply with RFC 2822. Can be set by the user + if default is not acceptable +* removed trim() from return results in EncodeQP +* /test and three files it contained are removed from version 2.3 +* fixed phpunit.php for compliance with PHP5 +* changed $this->AltBody = $textMsg; to $this->AltBody = html_entity_decode($textMsg); +* We have removed the /phpdoc from the downloads. All documentation is now on + the http://phpmailer.codeworxtech.com website. + +Version 2.2.1 () July 19 2008 + +* fixed line 1092 in class.smtp.php (my apologies, error on my part) + +Version 2.2 () July 15 2008 + +* Fixed redirect issue (display of UTF-8 in thank you redirect) +* fixed error in getResponse function declaration (class.pop3.php) +* PHPMailer now PHP6 compliant +* fixed line 1092 in class.smtp.php (endless loop from missing = sign) + +Version 2.1 (Wed, June 04 2008) + +** NOTE: WE HAVE A NEW LANGUAGE VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. + IF YOU CAN HELP WITH LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE + APPRECIATED. + +* added S/MIME functionality (ability to digitally sign emails) + BIG THANKS TO "sergiocambra" for posting this patch back in November 2007. + The "Signed Emails" functionality adds the Sign method to pass the private key + filename and the password to read it, and then email will be sent with + content-type multipart/signed and with the digital signature attached. +* fully compatible with E_STRICT error level + - Please note: + In about half the test environments this development version was subjected + to, an error was thrown for the date() functions used (line 1565 and 1569). + This is NOT a PHPMailer error, it is the result of an incorrectly configured + PHP5 installation. The fix is to modify your 'php.ini' file and include the + date.timezone = America/New York + directive, to your own server timezone + - If you do get this error, and are unable to access your php.ini file: + In your PHP script, add + date_default_timezone_set('America/Toronto'); + - do not try to use + $myVar = date_default_timezone_get(); + as a test, it will throw an error. +* added ability to define path (mainly for embedded images) + function MsgHTML($message,$basedir='') ... where: + $basedir is the fully qualified path +* fixed MsgHTML() function: + - Embedded Images where images are specified by :// will not be altered or embedded +* fixed the return value of SMTP exit code ( pclose ) +* addressed issue of multibyte characters in subject line and truncating +* added ability to have user specified Message ID + (default is still that PHPMailer create a unique Message ID) +* corrected unidentified message type to 'application/octet-stream' +* fixed chunk_split() multibyte issue (thanks to Colin Brown, et al). +* added check for added attachments +* enhanced conversion of HTML to text in MsgHTML (thanks to "brunny") + +Version 2.1.0beta2 (Sun, Dec 02 2007) +* implemented updated EncodeQP (thanks to coolbru, aka Marcus Bointon) +* finished all testing, all known bugs corrected, enhancements tested +- note: will NOT work with PHP4. + +please note, this is BETA software +** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS +INTENDED STRICTLY FOR TESTING + +Version 2.1.0beta1 +please note, this is BETA software +** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS +INTENDED STRICTLY FOR TESTING + +Version 2.0.0 rc2 (Fri, Nov 16 2007), interim release +* implements new property to control VERP in class.smtp.php + example (requires instantiating class.smtp.php): + $mail->do_verp = true; +* POP-before-SMTP functionality included, thanks to Richard Davey + (see class.pop3.php & pop3_before_smtp_test.php for examples) +* included example showing how to use PHPMailer with GMAIL +* fixed the missing Cc in SendMail() and Mail() + +****************** +A note on sending bulk emails: + +If the email you are sending is not personalized, consider using the +"undisclosed-recipient:;" strategy. That is, put all of your recipients +in the Bcc field and set the To field to "undisclosed-recipients:;". +It's a lot faster (only one send) and saves quite a bit on resources. +Contrary to some opinions, this will not get you listed in spam engines - +it's a legitimate way for you to send emails. + +A partial example for use with PHPMailer: + +$mail->AddAddress("undisclosed-recipients:;"); +$mail->AddBCC("email1@anydomain.com,email2@anyotherdomain.com,email3@anyalternatedomain.com"); + +Many email service providers restrict the number of emails that can be sent +in any given time period. Often that is between 50 - 60 emails maximum +per hour or per send session. + +If that's the case, then break up your Bcc lists into chunks that are one +less than your limit, and put a pause in your script. +******************* + +Version 2.0.0 rc1 (Thu, Nov 08 2007), interim release +* dramatically simplified using inline graphics ... it's fully automated and requires no user input +* added automatic document type detection for attachments and pictures +* added MsgHTML() function to replace Body tag for HTML emails +* fixed the SendMail security issues (input validation vulnerability) +* enhanced the AddAddresses functionality so that the "Name" portion is used in the email address +* removed the need to use the AltBody method (set from the HTML, or default text used) +* set the PHP Mail() function as the default (still support SendMail, SMTP Mail) +* removed the need to set the IsHTML property (set automatically) +* added Estonian language file by Indrek Päri +* added header injection patch +* added "set" method to permit users to create their own pseudo-properties like 'X-Headers', etc. + example of use: + $mail->set('X-Priority', '3'); + $mail->set('X-MSMail-Priority', 'Normal'); +* fixed warning message in SMTP get_lines method +* added TLS/SSL SMTP support + example of use: + $mail = new PHPMailer(); + $mail->Mailer = "smtp"; + $mail->Host = "smtp.example.com"; + $mail->SMTPSecure = "tls"; // option + //$mail->SMTPSecure = "ssl"; // option + ... + $mail->Send(); +* PHPMailer has been tested with PHP4 (4.4.7) and PHP5 (5.2.7) +* Works with PHP installed as a module or as CGI-PHP +- NOTE: will NOT work with PHP5 in E_STRICT error mode + +Version 1.73 (Sun, Jun 10 2005) +* Fixed denial of service bug: http://www.cybsec.com/vuln/PHPMailer-DOS.pdf +* Now has a total of 20 translations +* Fixed alt attachments bug: http://tinyurl.com/98u9k + +Version 1.72 (Wed, May 25 2004) +* Added Dutch, Swedish, Czech, Norwegian, and Turkish translations. +* Received: Removed this method because spam filter programs like +SpamAssassin reject this header. +* Fixed error count bug. +* SetLanguage default is now "language/". +* Fixed magic_quotes_runtime bug. + +Version 1.71 (Tue, Jul 28 2003) +* Made several speed enhancements +* Added German and Italian translation files +* Fixed HELO/AUTH bugs on keep-alive connects +* Now provides an error message if language file does not load +* Fixed attachment EOL bug +* Updated some unclear documentation +* Added additional tests and improved others + +Version 1.70 (Mon, Jun 20 2003) +* Added SMTP keep-alive support +* Added IsError method for error detection +* Added error message translation support (SetLanguage) +* Refactored many methods to increase library performance +* Hello now sends the newer EHLO message before HELO as per RFC 2821 +* Removed the boundary class and replaced it with GetBoundary +* Removed queue support methods +* New $Hostname variable +* New Message-ID header +* Received header reformat +* Helo variable default changed to $Hostname +* Removed extra spaces in Content-Type definition (#667182) +* Return-Path should be set to Sender when set +* Adds Q or B encoding to headers when necessary +* quoted-encoding should now encode NULs \000 +* Fixed encoding of body/AltBody (#553370) +* Adds "To: undisclosed-recipients:;" when all recipients are hidden (BCC) +* Multiple bug fixes + +Version 1.65 (Fri, Aug 09 2002) +* Fixed non-visible attachment bug (#585097) for Outlook +* SMTP connections are now closed after each transaction +* Fixed SMTP::Expand return value +* Converted SMTP class documentation to phpDocumentor format + +Version 1.62 (Wed, Jun 26 2002) +* Fixed multi-attach bug +* Set proper word wrapping +* Reduced memory use with attachments +* Added more debugging +* Changed documentation to phpDocumentor format + +Version 1.60 (Sat, Mar 30 2002) +* Sendmail pipe and address patch (Christian Holtje) +* Added embedded image and read confirmation support (A. Ognio) +* Added unit tests +* Added SMTP timeout support (*nix only) +* Added possibly temporary PluginDir variable for SMTP class +* Added LE message line ending variable +* Refactored boundary and attachment code +* Eliminated SMTP class warnings +* Added SendToQueue method for future queuing support + +Version 1.54 (Wed, Dec 19 2001) +* Add some queuing support code +* Fixed a pesky multi/alt bug +* Messages are no longer forced to have "To" addresses + +Version 1.50 (Thu, Nov 08 2001) +* Fix extra lines when not using SMTP mailer +* Set WordWrap variable to int with a zero default + +Version 1.47 (Tue, Oct 16 2001) +* Fixed Received header code format +* Fixed AltBody order error +* Fixed alternate port warning + +Version 1.45 (Tue, Sep 25 2001) +* Added enhanced SMTP debug support +* Added support for multiple ports on SMTP +* Added Received header for tracing +* Fixed AddStringAttachment encoding +* Fixed possible header name quote bug +* Fixed wordwrap() trim bug +* Couple other small bug fixes + +Version 1.41 (Wed, Aug 22 2001) +* Fixed AltBody bug w/o attachments +* Fixed rfc_date() for certain mail servers + +Version 1.40 (Sun, Aug 12 2001) +* Added multipart/alternative support (AltBody) +* Documentation update +* Fixed bug in Mercury MTA + +Version 1.29 (Fri, Aug 03 2001) +* Added AddStringAttachment() method +* Added SMTP authentication support + +Version 1.28 (Mon, Jul 30 2001) +* Fixed a typo in SMTP class +* Fixed header issue with Imail (win32) SMTP server +* Made fopen() calls for attachments use "rb" to fix win32 error + +Version 1.25 (Mon, Jul 02 2001) +* Added RFC 822 date fix (Patrice) +* Added improved error handling by adding a $ErrorInfo variable +* Removed MailerDebug variable (obsolete with new error handler) + +Version 1.20 (Mon, Jun 25 2001) +* Added quoted-printable encoding (Patrice) +* Set Version as public and removed PrintVersion() +* Changed phpdoc to only display public variables and methods + +Version 1.19 (Thu, Jun 21 2001) +* Fixed MS Mail header bug +* Added fix for Bcc problem with mail(). *Does not work on Win32* + (See PHP bug report: http://www.php.net/bugs.php?id=11616) +* mail() no longer passes a fifth parameter when not needed + +Version 1.15 (Fri, Jun 15 2001) +[Note: these changes contributed by Patrice Fournier] +* Changed all remaining \n to \r\n +* Bcc: header no longer writen to message except +when sent directly to sendmail +* Added a small message to non-MIME compliant mail reader +* Added Sender variable to change the Sender email +used in -f for sendmail/mail and in 'MAIL FROM' for smtp mode +* Changed boundary setting to a place it will be set only once +* Removed transfer encoding for whole message when using multipart +* Message body now uses Encoding in multipart messages +* Can set encoding and type to attachments 7bit, 8bit +and binary attachment are sent as is, base64 are encoded +* Can set Encoding to base64 to send 8 bits body +through 7 bits servers + +Version 1.10 (Tue, Jun 12 2001) +* Fixed win32 mail header bug (printed out headers in message body) + +Version 1.09 (Fri, Jun 08 2001) +* Changed date header to work with Netscape mail programs +* Altered phpdoc documentation + +Version 1.08 (Tue, Jun 05 2001) +* Added enhanced error-checking +* Added phpdoc documentation to source + +Version 1.06 (Fri, Jun 01 2001) +* Added optional name for file attachments + +Version 1.05 (Tue, May 29 2001) +* Code cleanup +* Eliminated sendmail header warning message +* Fixed possible SMTP error + +Version 1.03 (Thu, May 24 2001) +* Fixed problem where qmail sends out duplicate messages + +Version 1.02 (Wed, May 23 2001) +* Added multiple recipient and attachment Clear* methods +* Added Sendmail public variable +* Fixed problem with loading SMTP library multiple times + +Version 0.98 (Tue, May 22 2001) +* Fixed problem with redundant mail hosts sending out multiple messages +* Added additional error handler code +* Added AddCustomHeader() function +* Added support for Microsoft mail client headers (affects priority) +* Fixed small bug with Mailer variable +* Added PrintVersion() function + +Version 0.92 (Tue, May 15 2001) +* Changed file names to class.phpmailer.php and class.smtp.php to match + current PHP class trend. +* Fixed problem where body not being printed when a message is attached +* Several small bug fixes + +Version 0.90 (Tue, April 17 2001) +* Intial public release diff --git a/libraries/external/PHPMailer_v5.1/class.phpmailer.php b/libraries/external/PHPMailer_v5.1/class.phpmailer.php new file mode 100644 index 00000000..09479239 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/class.phpmailer.php @@ -0,0 +1,2320 @@ +exceptions = ($exceptions == true); + } + + /** + * Sets message type to HTML. + * @param bool $ishtml + * @return void + */ + public function IsHTML($ishtml = true) { + if ($ishtml) { + $this->ContentType = 'text/html'; + } else { + $this->ContentType = 'text/plain'; + } + } + + /** + * Sets Mailer to send message using SMTP. + * @return void + */ + public function IsSMTP() { + $this->Mailer = 'smtp'; + } + + /** + * Sets Mailer to send message using PHP mail() function. + * @return void + */ + public function IsMail() { + $this->Mailer = 'mail'; + } + + /** + * Sets Mailer to send message using the $Sendmail program. + * @return void + */ + public function IsSendmail() { + if (!stristr(ini_get('sendmail_path'), 'sendmail')) { + $this->Sendmail = '/var/qmail/bin/sendmail'; + } + $this->Mailer = 'sendmail'; + } + + /** + * Sets Mailer to send message using the qmail MTA. + * @return void + */ + public function IsQmail() { + if (stristr(ini_get('sendmail_path'), 'qmail')) { + $this->Sendmail = '/var/qmail/bin/sendmail'; + } + $this->Mailer = 'sendmail'; + } + + ///////////////////////////////////////////////// + // METHODS, RECIPIENTS + ///////////////////////////////////////////////// + + /** + * Adds a "To" address. + * @param string $address + * @param string $name + * @return boolean true on success, false if address already used + */ + public function AddAddress($address, $name = '') { + return $this->AddAnAddress('to', $address, $name); + } + + /** + * Adds a "Cc" address. + * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. + * @param string $address + * @param string $name + * @return boolean true on success, false if address already used + */ + public function AddCC($address, $name = '') { + return $this->AddAnAddress('cc', $address, $name); + } + + /** + * Adds a "Bcc" address. + * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. + * @param string $address + * @param string $name + * @return boolean true on success, false if address already used + */ + public function AddBCC($address, $name = '') { + return $this->AddAnAddress('bcc', $address, $name); + } + + /** + * Adds a "Reply-to" address. + * @param string $address + * @param string $name + * @return boolean + */ + public function AddReplyTo($address, $name = '') { + return $this->AddAnAddress('ReplyTo', $address, $name); + } + + /** + * Adds an address to one of the recipient arrays + * Addresses that have been added already return false, but do not throw exceptions + * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' + * @param string $address The email address to send to + * @param string $name + * @return boolean true on success, false if address already used or invalid in some way + * @access private + */ + private function AddAnAddress($kind, $address, $name = '') { + if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) { + echo 'Invalid recipient array: ' . kind; + return false; + } + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!self::ValidateAddress($address)) { + $this->SetError($this->Lang('invalid_address').': '. $address); + if ($this->exceptions) { + throw new phpmailerException($this->Lang('invalid_address').': '.$address); + } + echo $this->Lang('invalid_address').': '.$address; + return false; + } + if ($kind != 'ReplyTo') { + if (!isset($this->all_recipients[strtolower($address)])) { + array_push($this->$kind, array($address, $name)); + $this->all_recipients[strtolower($address)] = true; + return true; + } + } else { + if (!array_key_exists(strtolower($address), $this->ReplyTo)) { + $this->ReplyTo[strtolower($address)] = array($address, $name); + return true; + } + } + return false; +} + +/** + * Set the From and FromName properties + * @param string $address + * @param string $name + * @return boolean + */ + public function SetFrom($address, $name = '',$auto=1) { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!self::ValidateAddress($address)) { + $this->SetError($this->Lang('invalid_address').': '. $address); + if ($this->exceptions) { + throw new phpmailerException($this->Lang('invalid_address').': '.$address); + } + echo $this->Lang('invalid_address').': '.$address; + return false; + } + $this->From = $address; + $this->FromName = $name; + if ($auto) { + if (empty($this->ReplyTo)) { + $this->AddAnAddress('ReplyTo', $address, $name); + } + if (empty($this->Sender)) { + $this->Sender = $address; + } + } + return true; + } + + /** + * Check that a string looks roughly like an email address should + * Static so it can be used without instantiation + * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator + * Conforms approximately to RFC2822 + * @link http://www.hexillion.com/samples/#Regex Original pattern found here + * @param string $address The email address to check + * @return boolean + * @static + * @access public + */ + public static function ValidateAddress($address) { + if (function_exists('filter_var')) { //Introduced in PHP 5.2 + if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) { + return false; + } else { + return true; + } + } else { + return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address); + } + } + + ///////////////////////////////////////////////// + // METHODS, MAIL SENDING + ///////////////////////////////////////////////// + + /** + * Creates message and assigns Mailer. If the message is + * not sent successfully then it returns false. Use the ErrorInfo + * variable to view description of the error. + * @return bool + */ + public function Send() { + try { + if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { + throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL); + } + + // Set whether the message is multipart/alternative + if(!empty($this->AltBody)) { + $this->ContentType = 'multipart/alternative'; + } + + $this->error_count = 0; // reset errors + $this->SetMessageType(); + $header = $this->CreateHeader(); + $body = $this->CreateBody(); + + if (empty($this->Body)) { + throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL); + } + + // digitally sign with DKIM if enabled + if ($this->DKIM_domain && $this->DKIM_private) { + $header_dkim = $this->DKIM_Add($header,$this->Subject,$body); + $header = str_replace("\r\n","\n",$header_dkim) . $header; + } + + // Choose the mailer and send through it + switch($this->Mailer) { + case 'sendmail': + return $this->SendmailSend($header, $body); + case 'smtp': + return $this->SmtpSend($header, $body); + default: + return $this->MailSend($header, $body); + } + + } catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } + echo $e->getMessage()."\n"; + return false; + } + } + + /** + * Sends mail using the $Sendmail program. + * @param string $header The message headers + * @param string $body The message body + * @access protected + * @return bool + */ + protected function SendmailSend($header, $body) { + if ($this->Sender != '') { + $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + } else { + $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); + } + if ($this->SingleTo === true) { + foreach ($this->SingleToArray as $key => $val) { + if(!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, "To: " . $val . "\n"); + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + // implement call back function if it exists + $isSent = ($result == 0) ? 1 : 0; + $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); + if($result != 0) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + } else { + if(!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + // implement call back function if it exists + $isSent = ($result == 0) ? 1 : 0; + $this->doCallback($isSent,$this->to,$this->cc,$this->bcc,$this->Subject,$body); + if($result != 0) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + return true; + } + + /** + * Sends mail using the PHP mail() function. + * @param string $header The message headers + * @param string $body The message body + * @access protected + * @return bool + */ + protected function MailSend($header, $body) { + $toArr = array(); + foreach($this->to as $t) { + $toArr[] = $this->AddrFormat($t); + } + $to = implode(', ', $toArr); + + $params = sprintf("-oi -f %s", $this->Sender); + if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) { + $old_from = ini_get('sendmail_from'); + ini_set('sendmail_from', $this->Sender); + if ($this->SingleTo === true && count($toArr) > 1) { + foreach ($toArr as $key => $val) { + $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); + } + } else { + $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); + } + } else { + if ($this->SingleTo === true && count($toArr) > 1) { + foreach ($toArr as $key => $val) { + $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); + } + } else { + $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); + } + } + if (isset($old_from)) { + ini_set('sendmail_from', $old_from); + } + if(!$rt) { + throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL); + } + return true; + } + + /** + * Sends mail via SMTP using PhpSMTP + * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. + * @param string $header The message headers + * @param string $body The message body + * @uses SMTP + * @access protected + * @return bool + */ + protected function SmtpSend($header, $body) { + require_once $this->PluginDir . 'class.smtp.php'; + $bad_rcpt = array(); + + if(!$this->SmtpConnect()) { + throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL); + } + $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; + if(!$this->smtp->Mail($smtp_from)) { + throw new phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL); + } + + // Attempt to send attach all recipients + foreach($this->to as $to) { + if (!$this->smtp->Recipient($to[0])) { + $bad_rcpt[] = $to[0]; + // implement call back function if it exists + $isSent = 0; + $this->doCallback($isSent,$to[0],'','',$this->Subject,$body); + } else { + // implement call back function if it exists + $isSent = 1; + $this->doCallback($isSent,$to[0],'','',$this->Subject,$body); + } + } + foreach($this->cc as $cc) { + if (!$this->smtp->Recipient($cc[0])) { + $bad_rcpt[] = $cc[0]; + // implement call back function if it exists + $isSent = 0; + $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body); + } else { + // implement call back function if it exists + $isSent = 1; + $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body); + } + } + foreach($this->bcc as $bcc) { + if (!$this->smtp->Recipient($bcc[0])) { + $bad_rcpt[] = $bcc[0]; + // implement call back function if it exists + $isSent = 0; + $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body); + } else { + // implement call back function if it exists + $isSent = 1; + $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body); + } + } + + + if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses + $badaddresses = implode(', ', $bad_rcpt); + throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses); + } + if(!$this->smtp->Data($header . $body)) { + throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL); + } + if($this->SMTPKeepAlive == true) { + $this->smtp->Reset(); + } + return true; + } + + /** + * Initiates a connection to an SMTP server. + * Returns false if the operation failed. + * @uses SMTP + * @access public + * @return bool + */ + public function SmtpConnect() { + if(is_null($this->smtp)) { + $this->smtp = new SMTP(); + } + + $this->smtp->do_debug = $this->SMTPDebug; + $hosts = explode(';', $this->Host); + $index = 0; + $connection = $this->smtp->Connected(); + + // Retry while there is no connection + try { + while($index < count($hosts) && !$connection) { + $hostinfo = array(); + if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) { + $host = $hostinfo[1]; + $port = $hostinfo[2]; + } else { + $host = $hosts[$index]; + $port = $this->Port; + } + + $tls = ($this->SMTPSecure == 'tls'); + $ssl = ($this->SMTPSecure == 'ssl'); + + if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { + + $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname()); + $this->smtp->Hello($hello); + + if ($tls) { + if (!$this->smtp->StartTLS()) { + throw new phpmailerException($this->Lang('tls')); + } + + //We must resend HELO after tls negotiation + $this->smtp->Hello($hello); + } + + $connection = true; + if ($this->SMTPAuth) { + if (!$this->smtp->Authenticate($this->Username, $this->Password)) { + throw new phpmailerException($this->Lang('authenticate')); + } + } + } + $index++; + if (!$connection) { + throw new phpmailerException($this->Lang('connect_host')); + } + } + } catch (phpmailerException $e) { + $this->smtp->Reset(); + throw $e; + } + return true; + } + + /** + * Closes the active SMTP session if one exists. + * @return void + */ + public function SmtpClose() { + if(!is_null($this->smtp)) { + if($this->smtp->Connected()) { + $this->smtp->Quit(); + $this->smtp->Close(); + } + } + } + + /** + * Sets the language for all class error messages. + * Returns false if it cannot load the language file. The default language is English. + * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br") + * @param string $lang_path Path to the language file directory + * @access public + */ + function SetLanguage($langcode = 'en', $lang_path = 'language/') { + //Define full set of translatable strings + $PHPMAILER_LANG = array( + 'provide_address' => 'You must provide at least one recipient email address.', + 'mailer_not_supported' => ' mailer is not supported.', + 'execute' => 'Could not execute: ', + 'instantiate' => 'Could not instantiate mail function.', + 'authenticate' => 'SMTP Error: Could not authenticate.', + 'from_failed' => 'The following From address failed: ', + 'recipients_failed' => 'SMTP Error: The following recipients failed: ', + 'data_not_accepted' => 'SMTP Error: Data not accepted.', + 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', + 'file_access' => 'Could not access file: ', + 'file_open' => 'File Error: Could not open file: ', + 'encoding' => 'Unknown encoding: ', + 'signing' => 'Signing Error: ', + 'smtp_error' => 'SMTP server error: ', + 'empty_message' => 'Message body empty', + 'invalid_address' => 'Invalid address', + 'variable_set' => 'Cannot set or reset variable: ' + ); + //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"! + $l = true; + if ($langcode != 'en') { //There is no English translation file + $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php'; + } + $this->language = $PHPMAILER_LANG; + return ($l == true); //Returns false if language not found + } + + /** + * Return the current array of language strings + * @return array + */ + public function GetTranslations() { + return $this->language; + } + + ///////////////////////////////////////////////// + // METHODS, MESSAGE CREATION + ///////////////////////////////////////////////// + + /** + * Creates recipient headers. + * @access public + * @return string + */ + public function AddrAppend($type, $addr) { + $addr_str = $type . ': '; + $addresses = array(); + foreach ($addr as $a) { + $addresses[] = $this->AddrFormat($a); + } + $addr_str .= implode(', ', $addresses); + $addr_str .= $this->LE; + + return $addr_str; + } + + /** + * Formats an address correctly. + * @access public + * @return string + */ + public function AddrFormat($addr) { + if (empty($addr[1])) { + return $this->SecureHeader($addr[0]); + } else { + return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; + } + } + + /** + * Wraps message for use with mailers that do not + * automatically perform wrapping and for quoted-printable. + * Original written by philippe. + * @param string $message The message to wrap + * @param integer $length The line length to wrap to + * @param boolean $qp_mode Whether to run in Quoted-Printable mode + * @access public + * @return string + */ + public function WrapText($message, $length, $qp_mode = false) { + $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; + // If utf-8 encoding is used, we will need to make sure we don't + // split multibyte characters when we wrap + $is_utf8 = (strtolower($this->CharSet) == "utf-8"); + + $message = $this->FixEOL($message); + if (substr($message, -1) == $this->LE) { + $message = substr($message, 0, -1); + } + + $line = explode($this->LE, $message); + $message = ''; + for ($i=0 ;$i < count($line); $i++) { + $line_part = explode(' ', $line[$i]); + $buf = ''; + for ($e = 0; $e $length)) { + $space_left = $length - strlen($buf) - 1; + if ($e != 0) { + if ($space_left > 20) { + $len = $space_left; + if ($is_utf8) { + $len = $this->UTF8CharBoundary($word, $len); + } elseif (substr($word, $len - 1, 1) == "=") { + $len--; + } elseif (substr($word, $len - 2, 1) == "=") { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + $buf .= ' ' . $part; + $message .= $buf . sprintf("=%s", $this->LE); + } else { + $message .= $buf . $soft_break; + } + $buf = ''; + } + while (strlen($word) > 0) { + $len = $length; + if ($is_utf8) { + $len = $this->UTF8CharBoundary($word, $len); + } elseif (substr($word, $len - 1, 1) == "=") { + $len--; + } elseif (substr($word, $len - 2, 1) == "=") { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + + if (strlen($word) > 0) { + $message .= $part . sprintf("=%s", $this->LE); + } else { + $buf = $part; + } + } + } else { + $buf_o = $buf; + $buf .= ($e == 0) ? $word : (' ' . $word); + + if (strlen($buf) > $length and $buf_o != '') { + $message .= $buf_o . $soft_break; + $buf = $word; + } + } + } + $message .= $buf . $this->LE; + } + + return $message; + } + + /** + * Finds last character boundary prior to maxLength in a utf-8 + * quoted (printable) encoded string. + * Original written by Colin Brown. + * @access public + * @param string $encodedText utf-8 QP text + * @param int $maxLength find last character boundary prior to this length + * @return int + */ + public function UTF8CharBoundary($encodedText, $maxLength) { + $foundSplitPos = false; + $lookBack = 3; + while (!$foundSplitPos) { + $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); + $encodedCharPos = strpos($lastChunk, "="); + if ($encodedCharPos !== false) { + // Found start of encoded character byte within $lookBack block. + // Check the encoded byte value (the 2 chars after the '=') + $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); + $dec = hexdec($hex); + if ($dec < 128) { // Single byte character. + // If the encoded char was found at pos 0, it will fit + // otherwise reduce maxLength to start of the encoded char + $maxLength = ($encodedCharPos == 0) ? $maxLength : + $maxLength - ($lookBack - $encodedCharPos); + $foundSplitPos = true; + } elseif ($dec >= 192) { // First byte of a multi byte character + // Reduce maxLength to split at start of character + $maxLength = $maxLength - ($lookBack - $encodedCharPos); + $foundSplitPos = true; + } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back + $lookBack += 3; + } + } else { + // No encoded character found + $foundSplitPos = true; + } + } + return $maxLength; + } + + + /** + * Set the body wrapping. + * @access public + * @return void + */ + public function SetWordWrap() { + if($this->WordWrap < 1) { + return; + } + + switch($this->message_type) { + case 'alt': + case 'alt_attachments': + $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); + break; + default: + $this->Body = $this->WrapText($this->Body, $this->WordWrap); + break; + } + } + + /** + * Assembles message header. + * @access public + * @return string The assembled header + */ + public function CreateHeader() { + $result = ''; + + // Set the boundaries + $uniq_id = md5(uniqid(time())); + $this->boundary[1] = 'b1_' . $uniq_id; + $this->boundary[2] = 'b2_' . $uniq_id; + + $result .= $this->HeaderLine('Date', self::RFCDate()); + if($this->Sender == '') { + $result .= $this->HeaderLine('Return-Path', trim($this->From)); + } else { + $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); + } + + // To be created automatically by mail() + if($this->Mailer != 'mail') { + if ($this->SingleTo === true) { + foreach($this->to as $t) { + $this->SingleToArray[] = $this->AddrFormat($t); + } + } else { + if(count($this->to) > 0) { + $result .= $this->AddrAppend('To', $this->to); + } elseif (count($this->cc) == 0) { + $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); + } + } + } + + $from = array(); + $from[0][0] = trim($this->From); + $from[0][1] = $this->FromName; + $result .= $this->AddrAppend('From', $from); + + // sendmail and mail() extract Cc from the header before sending + if(count($this->cc) > 0) { + $result .= $this->AddrAppend('Cc', $this->cc); + } + + // sendmail and mail() extract Bcc from the header before sending + if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { + $result .= $this->AddrAppend('Bcc', $this->bcc); + } + + if(count($this->ReplyTo) > 0) { + $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); + } + + // mail() sets the subject itself + if($this->Mailer != 'mail') { + $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); + } + + if($this->MessageID != '') { + $result .= $this->HeaderLine('Message-ID',$this->MessageID); + } else { + $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); + } + $result .= $this->HeaderLine('X-Priority', $this->Priority); + $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (phpmailer.sourceforge.net)'); + + if($this->ConfirmReadingTo != '') { + $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); + } + + // Add custom headers + for($index = 0; $index < count($this->CustomHeader); $index++) { + $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); + } + if (!$this->sign_key_file) { + $result .= $this->HeaderLine('MIME-Version', '1.0'); + $result .= $this->GetMailMIME(); + } + + return $result; + } + + /** + * Returns the message MIME. + * @access public + * @return string + */ + public function GetMailMIME() { + $result = ''; + switch($this->message_type) { + case 'plain': + $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); + $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); + break; + case 'attachments': + case 'alt_attachments': + if($this->InlineImageExists()){ + $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); + } else { + $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); + } + break; + case 'alt': + $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + } + + if($this->Mailer != 'mail') { + $result .= $this->LE.$this->LE; + } + + return $result; + } + + /** + * Assembles the message body. Returns an empty string on failure. + * @access public + * @return string The assembled message body + */ + public function CreateBody() { + $body = ''; + + if ($this->sign_key_file) { + $body .= $this->GetMailMIME(); + } + + $this->SetWordWrap(); + + switch($this->message_type) { + case 'alt': + $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); + $body .= $this->EncodeString($this->AltBody, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->EndBoundary($this->boundary[1]); + break; + case 'plain': + $body .= $this->EncodeString($this->Body, $this->Encoding); + break; + case 'attachments': + $body .= $this->GetBoundary($this->boundary[1], '', '', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE; + $body .= $this->AttachAll(); + break; + case 'alt_attachments': + $body .= sprintf("--%s%s", $this->boundary[1], $this->LE); + $body .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); + $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body + $body .= $this->EncodeString($this->AltBody, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->EndBoundary($this->boundary[2]); + $body .= $this->AttachAll(); + break; + } + + if ($this->IsError()) { + $body = ''; + } elseif ($this->sign_key_file) { + try { + $file = tempnam('', 'mail'); + file_put_contents($file, $body); //TODO check this worked + $signed = tempnam("", "signed"); + if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) { + @unlink($file); + @unlink($signed); + $body = file_get_contents($signed); + } else { + @unlink($file); + @unlink($signed); + throw new phpmailerException($this->Lang("signing").openssl_error_string()); + } + } catch (phpmailerException $e) { + $body = ''; + if ($this->exceptions) { + throw $e; + } + } + } + + return $body; + } + + /** + * Returns the start of a message boundary. + * @access private + */ + private function GetBoundary($boundary, $charSet, $contentType, $encoding) { + $result = ''; + if($charSet == '') { + $charSet = $this->CharSet; + } + if($contentType == '') { + $contentType = $this->ContentType; + } + if($encoding == '') { + $encoding = $this->Encoding; + } + $result .= $this->TextLine('--' . $boundary); + $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet); + $result .= $this->LE; + $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); + $result .= $this->LE; + + return $result; + } + + /** + * Returns the end of a message boundary. + * @access private + */ + private function EndBoundary($boundary) { + return $this->LE . '--' . $boundary . '--' . $this->LE; + } + + /** + * Sets the message type. + * @access private + * @return void + */ + private function SetMessageType() { + if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { + $this->message_type = 'plain'; + } else { + if(count($this->attachment) > 0) { + $this->message_type = 'attachments'; + } + if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) { + $this->message_type = 'alt'; + } + if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) { + $this->message_type = 'alt_attachments'; + } + } + } + + /** + * Returns a formatted header line. + * @access public + * @return string + */ + public function HeaderLine($name, $value) { + return $name . ': ' . $value . $this->LE; + } + + /** + * Returns a formatted mail line. + * @access public + * @return string + */ + public function TextLine($value) { + return $value . $this->LE; + } + + ///////////////////////////////////////////////// + // CLASS METHODS, ATTACHMENTS + ///////////////////////////////////////////////// + + /** + * Adds an attachment from a path on the filesystem. + * Returns false if the file could not be found + * or accessed. + * @param string $path Path to the attachment. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @return bool + */ + public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { + try { + if ( !@is_file($path) ) { + throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE); + } + $filename = basename($path); + if ( $name == '' ) { + $name = $filename; + } + + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => 'attachment', + 7 => 0 + ); + + } catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } + echo $e->getMessage()."\n"; + if ( $e->getCode() == self::STOP_CRITICAL ) { + return false; + } + } + return true; + } + + /** + * Return the current array of attachments + * @return array + */ + public function GetAttachments() { + return $this->attachment; + } + + /** + * Attaches all fs, string, and binary attachments to the message. + * Returns an empty string on failure. + * @access private + * @return string + */ + private function AttachAll() { + // Return text of body + $mime = array(); + $cidUniq = array(); + $incl = array(); + + // Add all attachments + foreach ($this->attachment as $attachment) { + // Check for string attachment + $bString = $attachment[5]; + if ($bString) { + $string = $attachment[0]; + } else { + $path = $attachment[0]; + } + + if (in_array($attachment[0], $incl)) { continue; } + $filename = $attachment[1]; + $name = $attachment[2]; + $encoding = $attachment[3]; + $type = $attachment[4]; + $disposition = $attachment[6]; + $cid = $attachment[7]; + $incl[] = $attachment[0]; + if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; } + $cidUniq[$cid] = true; + + $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); + $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); + $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); + + if($disposition == 'inline') { + $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); + } + + $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); + + // Encode as string attachment + if($bString) { + $mime[] = $this->EncodeString($string, $encoding); + if($this->IsError()) { + return ''; + } + $mime[] = $this->LE.$this->LE; + } else { + $mime[] = $this->EncodeFile($path, $encoding); + if($this->IsError()) { + return ''; + } + $mime[] = $this->LE.$this->LE; + } + } + + $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); + + return join('', $mime); + } + + /** + * Encodes attachment in requested format. + * Returns an empty string on failure. + * @param string $path The full path to the file + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @see EncodeFile() + * @access private + * @return string + */ + private function EncodeFile($path, $encoding = 'base64') { + try { + if (!is_readable($path)) { + throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE); + } + if (function_exists('get_magic_quotes')) { + function get_magic_quotes() { + return false; + } + } + if (PHP_VERSION < 6) { + $magic_quotes = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + } + $file_buffer = file_get_contents($path); + $file_buffer = $this->EncodeString($file_buffer, $encoding); + if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); } + return $file_buffer; + } catch (Exception $e) { + $this->SetError($e->getMessage()); + return ''; + } + } + + /** + * Encodes string to requested format. + * Returns an empty string on failure. + * @param string $str The text to encode + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @access public + * @return string + */ + public function EncodeString ($str, $encoding = 'base64') { + $encoded = ''; + switch(strtolower($encoding)) { + case 'base64': + $encoded = chunk_split(base64_encode($str), 76, $this->LE); + break; + case '7bit': + case '8bit': + $encoded = $this->FixEOL($str); + //Make sure it ends with a line break + if (substr($encoded, -(strlen($this->LE))) != $this->LE) + $encoded .= $this->LE; + break; + case 'binary': + $encoded = $str; + break; + case 'quoted-printable': + $encoded = $this->EncodeQP($str); + break; + default: + $this->SetError($this->Lang('encoding') . $encoding); + break; + } + return $encoded; + } + + /** + * Encode a header string to best (shortest) of Q, B, quoted or none. + * @access public + * @return string + */ + public function EncodeHeader($str, $position = 'text') { + $x = 0; + + switch (strtolower($position)) { + case 'phrase': + if (!preg_match('/[\200-\377]/', $str)) { + // Can't use addslashes as we don't know what value has magic_quotes_sybase + $encoded = addcslashes($str, "\0..\37\177\\\""); + if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { + return ($encoded); + } else { + return ("\"$encoded\""); + } + } + $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); + break; + case 'comment': + $x = preg_match_all('/[()"]/', $str, $matches); + // Fall-through + case 'text': + default: + $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); + break; + } + + if ($x == 0) { + return ($str); + } + + $maxlen = 75 - 7 - strlen($this->CharSet); + // Try to select the encoding which should produce the shortest output + if (strlen($str)/3 < $x) { + $encoding = 'B'; + if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { + // Use a custom function which correctly encodes and wraps long + // multibyte strings without breaking lines within a character + $encoded = $this->Base64EncodeWrapMB($str); + } else { + $encoded = base64_encode($str); + $maxlen -= $maxlen % 4; + $encoded = trim(chunk_split($encoded, $maxlen, "\n")); + } + } else { + $encoding = 'Q'; + $encoded = $this->EncodeQ($str, $position); + $encoded = $this->WrapText($encoded, $maxlen, true); + $encoded = str_replace('='.$this->LE, "\n", trim($encoded)); + } + + $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); + $encoded = trim(str_replace("\n", $this->LE, $encoded)); + + return $encoded; + } + + /** + * Checks if a string contains multibyte characters. + * @access public + * @param string $str multi-byte text to wrap encode + * @return bool + */ + public function HasMultiBytes($str) { + if (function_exists('mb_strlen')) { + return (strlen($str) > mb_strlen($str, $this->CharSet)); + } else { // Assume no multibytes (we can't handle without mbstring functions anyway) + return false; + } + } + + /** + * Correctly encodes and wraps long multibyte strings for mail headers + * without breaking lines within a character. + * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php + * @access public + * @param string $str multi-byte text to wrap encode + * @return string + */ + public function Base64EncodeWrapMB($str) { + $start = "=?".$this->CharSet."?B?"; + $end = "?="; + $encoded = ""; + + $mb_length = mb_strlen($str, $this->CharSet); + // Each line must have length <= 75, including $start and $end + $length = 75 - strlen($start) - strlen($end); + // Average multi-byte ratio + $ratio = $mb_length / strlen($str); + // Base64 has a 4:3 ratio + $offset = $avgLength = floor($length * $ratio * .75); + + for ($i = 0; $i < $mb_length; $i += $offset) { + $lookBack = 0; + + do { + $offset = $avgLength - $lookBack; + $chunk = mb_substr($str, $i, $offset, $this->CharSet); + $chunk = base64_encode($chunk); + $lookBack++; + } + while (strlen($chunk) > $length); + + $encoded .= $chunk . $this->LE; + } + + // Chomp the last linefeed + $encoded = substr($encoded, 0, -strlen($this->LE)); + return $encoded; + } + + /** + * Encode string to quoted-printable. + * Only uses standard PHP, slow, but will always work + * @access public + * @param string $string the text to encode + * @param integer $line_max Number of chars allowed on a line before wrapping + * @return string + */ + public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) { + $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); + $lines = preg_split('/(?:\r\n|\r|\n)/', $input); + $eol = "\r\n"; + $escape = '='; + $output = ''; + while( list(, $line) = each($lines) ) { + $linlen = strlen($line); + $newline = ''; + for($i = 0; $i < $linlen; $i++) { + $c = substr( $line, $i, 1 ); + $dec = ord( $c ); + if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E + $c = '=2E'; + } + if ( $dec == 32 ) { + if ( $i == ( $linlen - 1 ) ) { // convert space at eol only + $c = '=20'; + } else if ( $space_conv ) { + $c = '=20'; + } + } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required + $h2 = floor($dec/16); + $h1 = floor($dec%16); + $c = $escape.$hex[$h2].$hex[$h1]; + } + if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted + $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay + $newline = ''; + // check if newline first character will be point or not + if ( $dec == 46 ) { + $c = '=2E'; + } + } + $newline .= $c; + } // end of for + $output .= $newline.$eol; + } // end of while + return $output; + } + + /** + * Encode string to RFC2045 (6.7) quoted-printable format + * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version + * Also results in same content as you started with after decoding + * @see EncodeQPphp() + * @access public + * @param string $string the text to encode + * @param integer $line_max Number of chars allowed on a line before wrapping + * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function + * @return string + * @author Marcus Bointon + */ + public function EncodeQP($string, $line_max = 76, $space_conv = false) { + if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3) + return quoted_printable_encode($string); + } + $filters = stream_get_filters(); + if (!in_array('convert.*', $filters)) { //Got convert stream filter? + return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation + } + $fp = fopen('php://temp/', 'r+'); + $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks + $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE); + $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params); + fputs($fp, $string); + rewind($fp); + $out = stream_get_contents($fp); + stream_filter_remove($s); + $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange + fclose($fp); + return $out; + } + + /** + * Encode string to q encoding. + * @link http://tools.ietf.org/html/rfc2047 + * @param string $str the text to encode + * @param string $position Where the text is going to be used, see the RFC for what that means + * @access public + * @return string + */ + public function EncodeQ ($str, $position = 'text') { + // There should not be any EOL in the string + $encoded = preg_replace('/[\r\n]*/', '', $str); + + switch (strtolower($position)) { + case 'phrase': + $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); + break; + case 'comment': + $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); + case 'text': + default: + // Replace every high ascii, control =, ? and _ characters + //TODO using /e (equivalent to eval()) is probably not a good idea + $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', + "'='.sprintf('%02X', ord('\\1'))", $encoded); + break; + } + + // Replace every spaces to _ (more readable than =20) + $encoded = str_replace(' ', '_', $encoded); + + return $encoded; + } + + /** + * Adds a string or binary attachment (non-filesystem) to the list. + * This method can be used to attach ascii or binary data, + * such as a BLOB record from a database. + * @param string $string String attachment data. + * @param string $filename Name of the attachment. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @return void + */ + public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $filename, + 2 => basename($filename), + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => 'attachment', + 7 => 0 + ); + } + + /** + * Adds an embedded attachment. This can include images, sounds, and + * just about any other document. Make sure to set the $type to an + * image type. For JPEG images use "image/jpeg" and for GIF images + * use "image/gif". + * @param string $path Path to the attachment. + * @param string $cid Content ID of the attachment. Use this to identify + * the Id for accessing the image in an HTML form. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @return bool + */ + public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { + + if ( !@is_file($path) ) { + $this->SetError($this->Lang('file_access') . $path); + return false; + } + + $filename = basename($path); + if ( $name == '' ) { + $name = $filename; + } + + // Append to $attachment array + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => 'inline', + 7 => $cid + ); + + return true; + } + + /** + * Returns true if an inline attachment is present. + * @access public + * @return bool + */ + public function InlineImageExists() { + foreach($this->attachment as $attachment) { + if ($attachment[6] == 'inline') { + return true; + } + } + return false; + } + + ///////////////////////////////////////////////// + // CLASS METHODS, MESSAGE RESET + ///////////////////////////////////////////////// + + /** + * Clears all recipients assigned in the TO array. Returns void. + * @return void + */ + public function ClearAddresses() { + foreach($this->to as $to) { + unset($this->all_recipients[strtolower($to[0])]); + } + $this->to = array(); + } + + /** + * Clears all recipients assigned in the CC array. Returns void. + * @return void + */ + public function ClearCCs() { + foreach($this->cc as $cc) { + unset($this->all_recipients[strtolower($cc[0])]); + } + $this->cc = array(); + } + + /** + * Clears all recipients assigned in the BCC array. Returns void. + * @return void + */ + public function ClearBCCs() { + foreach($this->bcc as $bcc) { + unset($this->all_recipients[strtolower($bcc[0])]); + } + $this->bcc = array(); + } + + /** + * Clears all recipients assigned in the ReplyTo array. Returns void. + * @return void + */ + public function ClearReplyTos() { + $this->ReplyTo = array(); + } + + /** + * Clears all recipients assigned in the TO, CC and BCC + * array. Returns void. + * @return void + */ + public function ClearAllRecipients() { + $this->to = array(); + $this->cc = array(); + $this->bcc = array(); + $this->all_recipients = array(); + } + + /** + * Clears all previously set filesystem, string, and binary + * attachments. Returns void. + * @return void + */ + public function ClearAttachments() { + $this->attachment = array(); + } + + /** + * Clears all custom headers. Returns void. + * @return void + */ + public function ClearCustomHeaders() { + $this->CustomHeader = array(); + } + + ///////////////////////////////////////////////// + // CLASS METHODS, MISCELLANEOUS + ///////////////////////////////////////////////// + + /** + * Adds the error message to the error container. + * @access protected + * @return void + */ + protected function SetError($msg) { + $this->error_count++; + if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { + $lasterror = $this->smtp->getError(); + if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { + $msg .= '

' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "

\n"; + } + } + $this->ErrorInfo = $msg; + } + + /** + * Returns the proper RFC 822 formatted date. + * @access public + * @return string + * @static + */ + public static function RFCDate() { + $tz = date('Z'); + $tzs = ($tz < 0) ? '-' : '+'; + $tz = abs($tz); + $tz = (int)($tz/3600)*100 + ($tz%3600)/60; + $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); + + return $result; + } + + /** + * Returns the server hostname or 'localhost.localdomain' if unknown. + * @access private + * @return string + */ + private function ServerHostname() { + if (!empty($this->Hostname)) { + $result = $this->Hostname; + } elseif (isset($_SERVER['SERVER_NAME'])) { + $result = $_SERVER['SERVER_NAME']; + } else { + $result = 'localhost.localdomain'; + } + + return $result; + } + + /** + * Returns a message in the appropriate language. + * @access private + * @return string + */ + private function Lang($key) { + if(count($this->language) < 1) { + $this->SetLanguage('en'); // set the default language + } + + if(isset($this->language[$key])) { + return $this->language[$key]; + } else { + return 'Language string failed to load: ' . $key; + } + } + + /** + * Returns true if an error occurred. + * @access public + * @return bool + */ + public function IsError() { + return ($this->error_count > 0); + } + + /** + * Changes every end of line from CR or LF to CRLF. + * @access private + * @return string + */ + private function FixEOL($str) { + $str = str_replace("\r\n", "\n", $str); + $str = str_replace("\r", "\n", $str); + $str = str_replace("\n", $this->LE, $str); + return $str; + } + + /** + * Adds a custom header. + * @access public + * @return void + */ + public function AddCustomHeader($custom_header) { + $this->CustomHeader[] = explode(':', $custom_header, 2); + } + + /** + * Evaluates the message and returns modifications for inline images and backgrounds + * @access public + * @return $message + */ + public function MsgHTML($message, $basedir = '') { + preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); + if(isset($images[2])) { + foreach($images[2] as $i => $url) { + // do not change urls for absolute images (thanks to corvuscorax) + if (!preg_match('#^[A-z]+://#',$url)) { + $filename = basename($url); + $directory = dirname($url); + ($directory == '.')?$directory='':''; + $cid = 'cid:' . md5($filename); + $ext = pathinfo($filename, PATHINFO_EXTENSION); + $mimeType = self::_mime_types($ext); + if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } + if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; } + if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) { + $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message); + } + } + } + } + $this->IsHTML(true); + $this->Body = $message; + $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); + if (!empty($textMsg) && empty($this->AltBody)) { + $this->AltBody = html_entity_decode($textMsg); + } + if (empty($this->AltBody)) { + $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; + } + } + + /** + * Gets the MIME type of the embedded or inline image + * @param string File extension + * @access public + * @return string MIME type of ext + * @static + */ + public static function _mime_types($ext = '') { + $mimes = array( + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'doc' => 'application/msword', + 'bin' => 'application/macbinary', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'class' => 'application/octet-stream', + 'psd' => 'application/octet-stream', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => 'application/zip', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'word' => 'application/msword', + 'xl' => 'application/excel', + 'eml' => 'message/rfc822' + ); + return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; + } + + /** + * Set (or reset) Class Objects (variables) + * + * Usage Example: + * $page->set('X-Priority', '3'); + * + * @access public + * @param string $name Parameter Name + * @param mixed $value Parameter Value + * NOTE: will not work with arrays, there are no arrays to set/reset + * @todo Should this not be using __set() magic function? + */ + public function set($name, $value = '') { + try { + if (isset($this->$name) ) { + $this->$name = $value; + } else { + throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL); + } + } catch (Exception $e) { + $this->SetError($e->getMessage()); + if ($e->getCode() == self::STOP_CRITICAL) { + return false; + } + } + return true; + } + + /** + * Strips newlines to prevent header injection. + * @access public + * @param string $str String + * @return string + */ + public function SecureHeader($str) { + $str = str_replace("\r", '', $str); + $str = str_replace("\n", '', $str); + return trim($str); + } + + /** + * Set the private key file and password to sign the message. + * + * @access public + * @param string $key_filename Parameter File Name + * @param string $key_pass Password for private key + */ + public function Sign($cert_filename, $key_filename, $key_pass) { + $this->sign_cert_file = $cert_filename; + $this->sign_key_file = $key_filename; + $this->sign_key_pass = $key_pass; + } + + /** + * Set the private key file and password to sign the message. + * + * @access public + * @param string $key_filename Parameter File Name + * @param string $key_pass Password for private key + */ + public function DKIM_QP($txt) { + $tmp=""; + $line=""; + for ($i=0;$iDKIM_private); + if ($this->DKIM_passphrase!='') { + $privKey = openssl_pkey_get_private($privKeyStr,$this->DKIM_passphrase); + } else { + $privKey = $privKeyStr; + } + if (openssl_sign($s, $signature, $privKey)) { + return base64_encode($signature); + } + } + + /** + * Generate DKIM Canonicalization Header + * + * @access public + * @param string $s Header + */ + public function DKIM_HeaderC($s) { + $s=preg_replace("/\r\n\s+/"," ",$s); + $lines=explode("\r\n",$s); + foreach ($lines as $key=>$line) { + list($heading,$value)=explode(":",$line,2); + $heading=strtolower($heading); + $value=preg_replace("/\s+/"," ",$value) ; // Compress useless spaces + $lines[$key]=$heading.":".trim($value) ; // Don't forget to remove WSP around the value + } + $s=implode("\r\n",$lines); + return $s; + } + + /** + * Generate DKIM Canonicalization Body + * + * @access public + * @param string $body Message Body + */ + public function DKIM_BodyC($body) { + if ($body == '') return "\r\n"; + // stabilize line endings + $body=str_replace("\r\n","\n",$body); + $body=str_replace("\n","\r\n",$body); + // END stabilize line endings + while (substr($body,strlen($body)-4,4) == "\r\n\r\n") { + $body=substr($body,0,strlen($body)-2); + } + return $body; + } + + /** + * Create the DKIM header, body, as new header + * + * @access public + * @param string $headers_line Header lines + * @param string $subject Subject + * @param string $body Body + */ + public function DKIM_Add($headers_line,$subject,$body) { + $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms + $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body + $DKIMquery = 'dns/txt'; // Query method + $DKIMtime = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) + $subject_header = "Subject: $subject"; + $headers = explode("\r\n",$headers_line); + foreach($headers as $header) { + if (strpos($header,'From:') === 0) { + $from_header=$header; + } elseif (strpos($header,'To:') === 0) { + $to_header=$header; + } + } + $from = str_replace('|','=7C',$this->DKIM_QP($from_header)); + $to = str_replace('|','=7C',$this->DKIM_QP($to_header)); + $subject = str_replace('|','=7C',$this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable + $body = $this->DKIM_BodyC($body); + $DKIMlen = strlen($body) ; // Length of body + $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body + $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";"; + $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n". + "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n". + "\th=From:To:Subject;\r\n". + "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n". + "\tz=$from\r\n". + "\t|$to\r\n". + "\t|$subject;\r\n". + "\tbh=" . $DKIMb64 . ";\r\n". + "\tb="; + $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs); + $signed = $this->DKIM_Sign($toSign); + return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n"; + } + + protected function doCallback($isSent,$to,$cc,$bcc,$subject,$body) { + if (!empty($this->action_function) && function_exists($this->action_function)) { + $params = array($isSent,$to,$cc,$bcc,$subject,$body); + call_user_func_array($this->action_function,$params); + } + } +} + +class phpmailerException extends Exception { + public function errorMessage() { + $errorMsg = '' . $this->getMessage() . "
\n"; + return $errorMsg; + } +} +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/class.pop3.php b/libraries/external/PHPMailer_v5.1/class.pop3.php new file mode 100644 index 00000000..f9fd3b2e --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/class.pop3.php @@ -0,0 +1,407 @@ +pop_conn = 0; + $this->connected = false; + $this->error = null; + } + + /** + * Combination of public events - connect, login, disconnect + * @access public + * @param string $host + * @param integer $port + * @param integer $tval + * @param string $username + * @param string $password + */ + public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) { + $this->host = $host; + + // If no port value is passed, retrieve it + if ($port == false) { + $this->port = $this->POP3_PORT; + } else { + $this->port = $port; + } + + // If no port value is passed, retrieve it + if ($tval == false) { + $this->tval = $this->POP3_TIMEOUT; + } else { + $this->tval = $tval; + } + + $this->do_debug = $debug_level; + $this->username = $username; + $this->password = $password; + + // Refresh the error log + $this->error = null; + + // Connect + $result = $this->Connect($this->host, $this->port, $this->tval); + + if ($result) { + $login_result = $this->Login($this->username, $this->password); + + if ($login_result) { + $this->Disconnect(); + + return true; + } + + } + + // We need to disconnect regardless if the login succeeded + $this->Disconnect(); + + return false; + } + + /** + * Connect to the POP3 server + * @access public + * @param string $host + * @param integer $port + * @param integer $tval + * @return boolean + */ + public function Connect ($host, $port = false, $tval = 30) { + // Are we already connected? + if ($this->connected) { + return true; + } + + /* + On Windows this will raise a PHP Warning error if the hostname doesn't exist. + Rather than supress it with @fsockopen, let's capture it cleanly instead + */ + + set_error_handler(array(&$this, 'catchWarning')); + + // Connect to the POP3 server + $this->pop_conn = fsockopen($host, // POP3 Host + $port, // Port # + $errno, // Error Number + $errstr, // Error Message + $tval); // Timeout (seconds) + + // Restore the error handler + restore_error_handler(); + + // Does the Error Log now contain anything? + if ($this->error && $this->do_debug >= 1) { + $this->displayErrors(); + } + + // Did we connect? + if ($this->pop_conn == false) { + // It would appear not... + $this->error = array( + 'error' => "Failed to connect to server $host on port $port", + 'errno' => $errno, + 'errstr' => $errstr + ); + + if ($this->do_debug >= 1) { + $this->displayErrors(); + } + + return false; + } + + // Increase the stream time-out + + // Check for PHP 4.3.0 or later + if (version_compare(phpversion(), '5.0.0', 'ge')) { + stream_set_timeout($this->pop_conn, $tval, 0); + } else { + // Does not work on Windows + if (substr(PHP_OS, 0, 3) !== 'WIN') { + socket_set_timeout($this->pop_conn, $tval, 0); + } + } + + // Get the POP3 server response + $pop3_response = $this->getResponse(); + + // Check for the +OK + if ($this->checkResponse($pop3_response)) { + // The connection is established and the POP3 server is talking + $this->connected = true; + return true; + } + + } + + /** + * Login to the POP3 server (does not support APOP yet) + * @access public + * @param string $username + * @param string $password + * @return boolean + */ + public function Login ($username = '', $password = '') { + if ($this->connected == false) { + $this->error = 'Not connected to POP3 server'; + + if ($this->do_debug >= 1) { + $this->displayErrors(); + } + } + + if (empty($username)) { + $username = $this->username; + } + + if (empty($password)) { + $password = $this->password; + } + + $pop_username = "USER $username" . $this->CRLF; + $pop_password = "PASS $password" . $this->CRLF; + + // Send the Username + $this->sendString($pop_username); + $pop3_response = $this->getResponse(); + + if ($this->checkResponse($pop3_response)) { + // Send the Password + $this->sendString($pop_password); + $pop3_response = $this->getResponse(); + + if ($this->checkResponse($pop3_response)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + /** + * Disconnect from the POP3 server + * @access public + */ + public function Disconnect () { + $this->sendString('QUIT'); + + fclose($this->pop_conn); + } + + ///////////////////////////////////////////////// + // Private Methods + ///////////////////////////////////////////////// + + /** + * Get the socket response back. + * $size is the maximum number of bytes to retrieve + * @access private + * @param integer $size + * @return string + */ + private function getResponse ($size = 128) { + $pop3_response = fgets($this->pop_conn, $size); + + return $pop3_response; + } + + /** + * Send a string down the open socket connection to the POP3 server + * @access private + * @param string $string + * @return integer + */ + private function sendString ($string) { + $bytes_sent = fwrite($this->pop_conn, $string, strlen($string)); + + return $bytes_sent; + } + + /** + * Checks the POP3 server response for +OK or -ERR + * @access private + * @param string $string + * @return boolean + */ + private function checkResponse ($string) { + if (substr($string, 0, 3) !== '+OK') { + $this->error = array( + 'error' => "Server reported an error: $string", + 'errno' => 0, + 'errstr' => '' + ); + + if ($this->do_debug >= 1) { + $this->displayErrors(); + } + + return false; + } else { + return true; + } + + } + + /** + * If debug is enabled, display the error message array + * @access private + */ + private function displayErrors () { + echo '
';
+
+    foreach ($this->error as $single_error) {
+      print_r($single_error);
+    }
+
+    echo '
'; + } + + /** + * Takes over from PHP for the socket warning handler + * @access private + * @param integer $errno + * @param string $errstr + * @param string $errfile + * @param integer $errline + */ + private function catchWarning ($errno, $errstr, $errfile, $errline) { + $this->error[] = array( + 'error' => "Connecting to the POP3 server raised a PHP warning: ", + 'errno' => $errno, + 'errstr' => $errstr + ); + } + + // End of class +} +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/class.smtp.php b/libraries/external/PHPMailer_v5.1/class.smtp.php new file mode 100644 index 00000000..c2ca1cb3 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/class.smtp.php @@ -0,0 +1,814 @@ +smtp_conn = 0; + $this->error = null; + $this->helo_rply = null; + + $this->do_debug = 0; + } + + ///////////////////////////////////////////////// + // CONNECTION FUNCTIONS + ///////////////////////////////////////////////// + + /** + * Connect to the server specified on the port specified. + * If the port is not specified use the default SMTP_PORT. + * If tval is specified then a connection will try and be + * established with the server for that number of seconds. + * If tval is not specified the default is 30 seconds to + * try on the connection. + * + * SMTP CODE SUCCESS: 220 + * SMTP CODE FAILURE: 421 + * @access public + * @return bool + */ + public function Connect($host, $port = 0, $tval = 30) { + // set the error val to null so there is no confusion + $this->error = null; + + // make sure we are __not__ connected + if($this->connected()) { + // already connected, generate error + $this->error = array("error" => "Already connected to a server"); + return false; + } + + if(empty($port)) { + $port = $this->SMTP_PORT; + } + + // connect to the smtp server + $this->smtp_conn = @fsockopen($host, // the host of the server + $port, // the port to use + $errno, // error number if any + $errstr, // error message if any + $tval); // give up after ? secs + // verify we connected properly + if(empty($this->smtp_conn)) { + $this->error = array("error" => "Failed to connect to server", + "errno" => $errno, + "errstr" => $errstr); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '
'; + } + return false; + } + + // SMTP server can take longer to respond, give longer timeout for first read + // Windows does not have support for this timeout function + if(substr(PHP_OS, 0, 3) != "WIN") + socket_set_timeout($this->smtp_conn, $tval, 0); + + // get any announcement + $announce = $this->get_lines(); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '
'; + } + + return true; + } + + /** + * Initiate a TLS communication with the server. + * + * SMTP CODE 220 Ready to start TLS + * SMTP CODE 501 Syntax error (no parameters allowed) + * SMTP CODE 454 TLS not available due to temporary reason + * @access public + * @return bool success + */ + public function StartTLS() { + $this->error = null; # to avoid confusion + + if(!$this->connected()) { + $this->error = array("error" => "Called StartTLS() without being connected"); + return false; + } + + fputs($this->smtp_conn,"STARTTLS" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 220) { + $this->error = + array("error" => "STARTTLS not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + // Begin encrypted connection + if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + return false; + } + + return true; + } + + /** + * Performs SMTP authentication. Must be run after running the + * Hello() method. Returns true if successfully authenticated. + * @access public + * @return bool + */ + public function Authenticate($username, $password) { + // Start authentication + fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "AUTH not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + // Send encoded username + fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "Username not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + // Send encoded password + fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 235) { + $this->error = + array("error" => "Password not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + return true; + } + + /** + * Returns true if connected to a server otherwise false + * @access public + * @return bool + */ + public function Connected() { + if(!empty($this->smtp_conn)) { + $sock_status = socket_get_status($this->smtp_conn); + if($sock_status["eof"]) { + // the socket is valid but we are not connected + if($this->do_debug >= 1) { + echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"; + } + $this->Close(); + return false; + } + return true; // everything looks good + } + return false; + } + + /** + * Closes the socket and cleans up the state of the class. + * It is not considered good to use this function without + * first trying to use QUIT. + * @access public + * @return void + */ + public function Close() { + $this->error = null; // so there is no confusion + $this->helo_rply = null; + if(!empty($this->smtp_conn)) { + // close the connection and cleanup + fclose($this->smtp_conn); + $this->smtp_conn = 0; + } + } + + ///////////////////////////////////////////////// + // SMTP COMMANDS + ///////////////////////////////////////////////// + + /** + * Issues a data command and sends the msg_data to the server + * finializing the mail transaction. $msg_data is the message + * that is to be send with the headers. Each header needs to be + * on a single line followed by a with the message headers + * and the message body being seperated by and additional . + * + * Implements rfc 821: DATA + * + * SMTP CODE INTERMEDIATE: 354 + * [data] + * . + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 552,554,451,452 + * SMTP CODE FAILURE: 451,554 + * SMTP CODE ERROR : 500,501,503,421 + * @access public + * @return bool + */ + public function Data($msg_data) { + $this->error = null; // so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Data() without being connected"); + return false; + } + + fputs($this->smtp_conn,"DATA" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 354) { + $this->error = + array("error" => "DATA command not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + /* the server is ready to accept data! + * according to rfc 821 we should not send more than 1000 + * including the CRLF + * characters on a single line so we will break the data up + * into lines by \r and/or \n then if needed we will break + * each of those into smaller lines to fit within the limit. + * in addition we will be looking for lines that start with + * a period '.' and append and additional period '.' to that + * line. NOTE: this does not count towards limit. + */ + + // normalize the line breaks so we know the explode works + $msg_data = str_replace("\r\n","\n",$msg_data); + $msg_data = str_replace("\r","\n",$msg_data); + $lines = explode("\n",$msg_data); + + /* we need to find a good way to determine is headers are + * in the msg_data or if it is a straight msg body + * currently I am assuming rfc 822 definitions of msg headers + * and if the first field of the first line (':' sperated) + * does not contain a space then it _should_ be a header + * and we can process all lines before a blank "" line as + * headers. + */ + + $field = substr($lines[0],0,strpos($lines[0],":")); + $in_headers = false; + if(!empty($field) && !strstr($field," ")) { + $in_headers = true; + } + + $max_line_length = 998; // used below; set here for ease in change + + while(list(,$line) = @each($lines)) { + $lines_out = null; + if($line == "" && $in_headers) { + $in_headers = false; + } + // ok we need to break this line up into several smaller lines + while(strlen($line) > $max_line_length) { + $pos = strrpos(substr($line,0,$max_line_length)," "); + + // Patch to fix DOS attack + if(!$pos) { + $pos = $max_line_length - 1; + $lines_out[] = substr($line,0,$pos); + $line = substr($line,$pos); + } else { + $lines_out[] = substr($line,0,$pos); + $line = substr($line,$pos + 1); + } + + /* if processing headers add a LWSP-char to the front of new line + * rfc 822 on long msg headers + */ + if($in_headers) { + $line = "\t" . $line; + } + } + $lines_out[] = $line; + + // send the lines to the server + while(list(,$line_out) = @each($lines_out)) { + if(strlen($line_out) > 0) + { + if(substr($line_out, 0, 1) == ".") { + $line_out = "." . $line_out; + } + } + fputs($this->smtp_conn,$line_out . $this->CRLF); + } + } + + // message data has been sent + fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 250) { + $this->error = + array("error" => "DATA not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + return true; + } + + /** + * Sends the HELO command to the smtp server. + * This makes sure that we and the server are in + * the same known state. + * + * Implements from rfc 821: HELO + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500, 501, 504, 421 + * @access public + * @return bool + */ + public function Hello($host = '') { + $this->error = null; // so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Hello() without being connected"); + return false; + } + + // if hostname for HELO was not specified send default + if(empty($host)) { + // determine appropriate default to send to server + $host = "localhost"; + } + + // Send extended hello first (RFC 2821) + if(!$this->SendHello("EHLO", $host)) { + if(!$this->SendHello("HELO", $host)) { + return false; + } + } + + return true; + } + + /** + * Sends a HELO/EHLO command. + * @access private + * @return bool + */ + private function SendHello($hello, $host) { + fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '
'; + } + + if($code != 250) { + $this->error = + array("error" => $hello . " not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + $this->helo_rply = $rply; + + return true; + } + + /** + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. + * + * Implements rfc 821: MAIL FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,421 + * @access public + * @return bool + */ + public function Mail($from) { + $this->error = null; // so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Mail() without being connected"); + return false; + } + + $useVerp = ($this->do_verp ? "XVERP" : ""); + fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 250) { + $this->error = + array("error" => "MAIL not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + return true; + } + + /** + * Sends the quit command to the server and then closes the socket + * if there is no error or the $close_on_error argument is true. + * + * Implements from rfc 821: QUIT + * + * SMTP CODE SUCCESS: 221 + * SMTP CODE ERROR : 500 + * @access public + * @return bool + */ + public function Quit($close_on_error = true) { + $this->error = null; // so there is no confusion + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Quit() without being connected"); + return false; + } + + // send the quit command to the server + fputs($this->smtp_conn,"quit" . $this->CRLF); + + // get any good-bye messages + $byemsg = $this->get_lines(); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '
'; + } + + $rval = true; + $e = null; + + $code = substr($byemsg,0,3); + if($code != 221) { + // use e as a tmp var cause Close will overwrite $this->error + $e = array("error" => "SMTP server rejected quit command", + "smtp_code" => $code, + "smtp_rply" => substr($byemsg,4)); + $rval = false; + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '
'; + } + } + + if(empty($e) || $close_on_error) { + $this->Close(); + } + + return $rval; + } + + /** + * Sends the command RCPT to the SMTP server with the TO: argument of $to. + * Returns true if the recipient was accepted false if it was rejected. + * + * Implements from rfc 821: RCPT TO: + * + * SMTP CODE SUCCESS: 250,251 + * SMTP CODE FAILURE: 550,551,552,553,450,451,452 + * SMTP CODE ERROR : 500,501,503,421 + * @access public + * @return bool + */ + public function Recipient($to) { + $this->error = null; // so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Recipient() without being connected"); + return false; + } + + fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 250 && $code != 251) { + $this->error = + array("error" => "RCPT not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + return true; + } + + /** + * Sends the RSET command to abort and transaction that is + * currently in progress. Returns true if successful false + * otherwise. + * + * Implements rfc 821: RSET + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500,501,504,421 + * @access public + * @return bool + */ + public function Reset() { + $this->error = null; // so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Reset() without being connected"); + return false; + } + + fputs($this->smtp_conn,"RSET" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 250) { + $this->error = + array("error" => "RSET failed", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + + return true; + } + + /** + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in and send them an email. + * + * Implements rfc 821: SAML FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + * @access public + * @return bool + */ + public function SendAndMail($from) { + $this->error = null; // so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called SendAndMail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + } + + if($code != 250) { + $this->error = + array("error" => "SAML not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + } + return false; + } + return true; + } + + /** + * This is an optional command for SMTP that this class does not + * support. This method is here to make the RFC821 Definition + * complete for this class and __may__ be implimented in the future + * + * Implements from rfc 821: TURN + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 502 + * SMTP CODE ERROR : 500, 503 + * @access public + * @return bool + */ + public function Turn() { + $this->error = array("error" => "This method, TURN, of the SMTP ". + "is not implemented"); + if($this->do_debug >= 1) { + echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '
'; + } + return false; + } + + /** + * Get the current error + * @access public + * @return array + */ + public function getError() { + return $this->error; + } + + ///////////////////////////////////////////////// + // INTERNAL FUNCTIONS + ///////////////////////////////////////////////// + + /** + * Read in as many lines as possible + * either before eof or socket timeout occurs on the operation. + * With SMTP we can tell if we have more lines to read if the + * 4th character is '-' symbol. If it is a space then we don't + * need to read anything else. + * @access private + * @return string + */ + private function get_lines() { + $data = ""; + while($str = @fgets($this->smtp_conn,515)) { + if($this->do_debug >= 4) { + echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
'; + echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
'; + } + $data .= $str; + if($this->do_debug >= 4) { + echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '
'; + } + // if 4th character is a space, we are done reading, break the loop + if(substr($str,3,1) == " ") { break; } + } + return $data; + } + +} + +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/docs/Callback_function_notes.txt b/libraries/external/PHPMailer_v5.1/docs/Callback_function_notes.txt new file mode 100644 index 00000000..7b98ce22 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/Callback_function_notes.txt @@ -0,0 +1,17 @@ +NEW CALLBACK FUNCTION: +====================== + +We have had requests for a method to process the results of sending emails +through PHPMailer. In this new release, we have implemented a callback +function that passes the results of each email sent (to, cc, and/or bcc). +We have provided an example that echos the results back to the screen. The +callback function can be used for any purpose. With minor modifications, the +callback function can be used to create CSV logs, post results to databases, +etc. + +Please review the test.php script for the example. + +It's pretty straight forward. + +Enjoy! +Andy diff --git a/libraries/external/PHPMailer_v5.1/docs/DomainKeys_notes.txt b/libraries/external/PHPMailer_v5.1/docs/DomainKeys_notes.txt new file mode 100644 index 00000000..e12a16aa --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/DomainKeys_notes.txt @@ -0,0 +1,55 @@ +CREATE DKIM KEYS and DNS Resource Record: +========================================= + +To create DomainKeys Identified Mail keys, visit: +http://dkim.worxware.com/ +... read the information, fill in the form, and download the ZIP file +containing the public key, private key, DNS Resource Record and instructions +to add to your DNS Zone Record, and the PHPMailer code to enable DKIM +digital signing. + +/*** PROTECT YOUR PRIVATE & PUBLIC KEYS ***/ + +You need to protect your DKIM private and public keys from being viewed or +accessed. Add protection to your .htaccess file as in this example: + +# secure htkeyprivate file + + order allow,deny + deny from all + + +# secure htkeypublic file + + order allow,deny + deny from all + + +(the actual .htaccess additions are in the ZIP file sent back to you from +http://dkim.worxware.com/ + +A few notes on using DomainKey Identified Mail (DKIM): + +You do not need to use PHPMailer to DKIM sign emails IF: +- you enable DomainKey support and add the DNS resource record +- you use your outbound mail server + +If you are a third-party emailer that works on behalf of domain owners to +send their emails from your own server: +- you absolutely have to DKIM sign outbound emails +- the domain owner has to add the DNS resource record to match the + private key, public key, selector, identity, and domain that you create +- use caution with the "selector" ... at least one "selector" will already + exist in the DNS Zone Record of the domain at the domain owner's server + you need to ensure that the "selector" you use is unique +Note: since the IP address will not match the domain owner's DNS Zone record +you can be certain that email providers that validate based on DomainKey will +check the domain owner's DNS Zone record for your DNS resource record. Before +sending out emails on behalf of domain owners, ensure they have entered the +DNS resource record you provided them. + +Enjoy! +Andy + +PS. if you need additional information about DKIM, please see: +http://www.dkim.org/info/dkim-faq.html diff --git a/libraries/external/PHPMailer_v5.1/docs/Note_for_SMTP_debugging.txt b/libraries/external/PHPMailer_v5.1/docs/Note_for_SMTP_debugging.txt new file mode 100644 index 00000000..3c756607 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/Note_for_SMTP_debugging.txt @@ -0,0 +1,23 @@ +If you are having problems connecting or sending emails through your SMTP server, please note: + +1. The new rewrite of class.smtp.php provides more information about the processing/errors taking place +2. Use the debug functionality of class.smtp.php. To do that, in your own script add the debug level you wish to use. An example of that is: + +$mail->SMTPDebug = 1; +$mail->IsSMTP(); // telling the class to use SMTP +$mail->SMTPAuth = true; // enable SMTP authentication +$mail->Port = 26; // set the SMTP port +$mail->Host = "mail.yourhost.com"; // SMTP server +$mail->Username = "name@yourhost.com"; // SMTP account username +$mail->Password = "your password"; // SMTP account password + +Notes on this: +$mail->SMTPDebug = 0; ... will disable debugging (you can also leave this out completely, 0 is the default +$mail->SMTPDebug = 1; ... will echo errors and messages +$mail->SMTPDebug = 2; ... will echo messages only +... and finally, the options are 0, 1, and 2 ... any number greater than 2 will be interpreted as 2 + +And finally, don't forget to disable debugging before going into production. + +Enjoy! +Andy \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/docs/extending.html b/libraries/external/PHPMailer_v5.1/docs/extending.html new file mode 100644 index 00000000..f7c3200a --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/extending.html @@ -0,0 +1,148 @@ + + +Examples using phpmailer + + + + +

Examples using phpmailer

+ +

1. Advanced Example

+

+ +This demonstrates sending out multiple email messages with binary attachments +from a MySQL database with multipart/alternative support.

+ + + + +
+
+require("class.phpmailer.php");
+
+$mail = new phpmailer();
+
+$mail->From     = "list@example.com";
+$mail->FromName = "List manager";
+$mail->Host     = "smtp1.example.com;smtp2.example.com";
+$mail->Mailer   = "smtp";
+
+@MYSQL_CONNECT("localhost","root","password");
+@mysql_select_db("my_company");
+$query  = "SELECT full_name, email, photo FROM employee WHERE id=$id";
+$result = @MYSQL_QUERY($query);
+
+while ($row = mysql_fetch_array ($result))
+{
+    // HTML body
+    $body  = "Hello <font size=\"4\">" . $row["full_name"] . "</font>, <p>";
+    $body .= "<i>Your</i> personal photograph to this message.<p>";
+    $body .= "Sincerely, <br>";
+    $body .= "phpmailer List manager";
+
+    // Plain text body (for mail clients that cannot read HTML)
+    $text_body  = "Hello " . $row["full_name"] . ", \n\n";
+    $text_body .= "Your personal photograph to this message.\n\n";
+    $text_body .= "Sincerely, \n";
+    $text_body .= "phpmailer List manager";
+
+    $mail->Body    = $body;
+    $mail->AltBody = $text_body;
+    $mail->AddAddress($row["email"], $row["full_name"]);
+    $mail->AddStringAttachment($row["photo"], "YourPhoto.jpg");
+
+    if(!$mail->Send())
+        echo "There has been a mail error sending to " . $row["email"] . "<br>";
+
+    // Clear all addresses and attachments for next loop
+    $mail->ClearAddresses();
+    $mail->ClearAttachments();
+}
+
+
+

+ +

2. Extending phpmailer

+

+ +Extending classes with inheritance is one of the most +powerful features of object-oriented +programming. It allows you to make changes to the +original class for your +own personal use without hacking the original +classes. Plus, it is very +easy to do. I've provided an example: + +

+Here's a class that extends the phpmailer class and sets the defaults +for the particular site:
+PHP include file: mail.inc.php +

+ + + + + +
+
+require("class.phpmailer.php");
+
+class my_phpmailer extends phpmailer {
+    // Set default variables for all new objects
+    var $From     = "from@example.com";
+    var $FromName = "Mailer";
+    var $Host     = "smtp1.example.com;smtp2.example.com";
+    var $Mailer   = "smtp";                         // Alternative to IsSMTP()
+    var $WordWrap = 75;
+
+    // Replace the default error_handler
+    function error_handler($msg) {
+        print("My Site Error");
+        print("Description:");
+        printf("%s", $msg);
+        exit;
+    }
+
+    // Create an additional function
+    function do_something($something) {
+        // Place your new code here
+    }
+}
+
+
+ +Now here's a normal PHP page in the site, which will have all the defaults set +above:
+Normal PHP file: mail_test.php +

+ + + + + +
+
+require("mail.inc.php");
+
+// Instantiate your new class
+$mail = new my_phpmailer;
+
+// Now you only need to add the necessary stuff
+$mail->AddAddress("josh@example.com", "Josh Adams");
+$mail->Subject = "Here is the subject";
+$mail->Body    = "This is the message body";
+$mail->AddAttachment("c:/temp/11-10-00.zip", "new_name.zip");  // optional name
+
+if(!$mail->Send())
+{
+   echo "There was an error sending the message";
+   exit;
+}
+
+echo "Message was sent successfully";
+
+
+

+ + + diff --git a/libraries/external/PHPMailer_v5.1/docs/faq.html b/libraries/external/PHPMailer_v5.1/docs/faq.html new file mode 100644 index 00000000..54ac1837 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/faq.html @@ -0,0 +1,67 @@ + + +PHPMailer FAQ + + + +
+
+

PHPMailer FAQ

+
    + +
  • Q: I'm using the SMTP mailer and I keep on getting a timeout message + well before the X seconds I set it for. What gives?
    + A: PHP versions 4.0.4pl1 and earlier have a bug in which sockets timeout + early. You can fix this by re-compiling PHP 4.0.4pl1 with this fix: + timeoutfix.diff. Otherwise you can wait for the new PHP release.

  • + +
  • Q: I am concerned that using include files will take up too much + processing time on my computer. How can I make it run faster?
    + A: PHP by itself is very fast. Much faster than ASP or JSP running on + the same type of server. This is because it has very little overhead compared + to its competitors and it pre-compiles all of + its code before it runs each script (in PHP4). However, all of + this compiling and re-compiling can take up a lot of valuable + computer resources. However, there are programs out there that compile + PHP code and store it in memory (or on mmaped files) to reduce the + processing immensely. Two of these: APC + (Alternative PHP Cache) and Afterburner + (Win32 download) + are excellent free tools that do just this. If you have the money + you might also try Zend Cache, it is + even faster than the open source varieties. All of these tools make your + scripts run faster while also reducing the load on your server. I have tried + them myself and they are quite stable too.

  • + +
  • Q: What mailer gives me the best performance?
    + A: On a single machine the sendmail (or Qmail) is fastest overall. + Next fastest is mail() to give you the best performance. Both do not have the overhead of SMTP. + If you have you have your mail server on a another machine then + SMTP is your only option, but you do get the benefit of redundant mail servers.
    + If you are running a mailing list with thousands of names, the fastest mailers in order are: SMTP, sendmail (or Qmail), mail().

  • + +
  • Q: When I try to attach a file with on my server I get a + "Could not find {file} on filesystem error". Why is this?
    + A: If you are using a Unix machine this is probably because the user + running your web server does not have read access to the directory in question. If you are using Windows, + then the problem probably is that you have used single backslashes to denote directories (\). + A single backslash has a special meaning to PHP so these are not + valid. Instead use double backslashes ("\\") or a single forward + slash ("/").

  • + +
+ +
+
+ + + diff --git a/libraries/external/PHPMailer_v5.1/docs/pop3_article.txt b/libraries/external/PHPMailer_v5.1/docs/pop3_article.txt new file mode 100644 index 00000000..379c44e8 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/pop3_article.txt @@ -0,0 +1,39 @@ +This is built for PHP Mailer 1.72 and was not tested with any previous version. It was developed under PHP 4.3.11 (E_ALL). It works under PHP 5 and 5.1 with E_ALL, but not in Strict mode due to var deprecation (but then neither does PHP Mailer either!). It follows the RFC 1939 standard explicitly and is fully commented. + +With that noted, here is how to implement it: +Install the class file + +I didn't want to modify the PHP Mailer classes at all, so you will have to include/require this class along with the base one. It can sit quite happily in the phpmailer-1.72 directory: +[geshi lang=php] require 'phpmailer-1.72/class.phpmailer.php'; require 'phpmailer-1.72/class.pop3.php'; [/geshi] +When you need it, create your POP3 object + +Right before I invoke PHP Mailer I activate the POP3 authorisation. POP3 before SMTP is a process whereby you login to your web hosts POP3 mail server BEFORE sending out any emails via SMTP. The POP3 logon 'verifies' your ability to send email by SMTP, which typically otherwise blocks you. On my web host (Pair Networks) a single POP3 logon is enough to 'verify' you for 90 minutes. Here is some sample PHP code that activates the POP3 logon and then sends an email via PHP Mailer: +[geshi lang=php] Authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1); $mail = new PHPMailer(); $mail->SMTPDebug = 2; $mail->IsSMTP(); $mail->IsHTML(false); $mail->Host = 'relay.example.com'; $mail->From = 'mailer@example.com'; $mail->FromName = 'Example Mailer'; $mail->Subject = 'My subject'; $mail->Body = 'Hello world'; $mail->AddAddress('rich@corephp.co.uk', 'Richard Davey'); if (!$mail->Send()) { echo $mail->ErrorInfo; } ?> [/geshi] + +The PHP Mailer parts of this code should be obvious to anyone who has used PHP Mailer before. One thing to note - you almost certainly will not need to use SMTP Authentication *and* POP3 before SMTP together. The Authorisation method is a proxy method to all of the others within that class. There are Connect, Logon and Disconnect methods available, but I wrapped them in the single Authorisation one to make things easier. +The Parameters + +The Authorise parameters are as follows: +[geshi lang=php]$pop->Authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1);[/geshi] + + 1. pop3.example.com - The POP3 Mail Server Name (hostname or IP address) + 2. 110 - The POP3 Port on which to connect (default is usually 110, but check with your host) + 3. 30 - A connection time-out value (in seconds) + 4. mailer - The POP3 Username required to logon + 5. password - The POP3 Password required to logon + 6. 1 - The class debug level (0 = off, 1+ = debug output is echoed to the browser) + +Final Comments + the Download + +1) This class does not support APOP connections. This is only because I did not have an APOP server to test with, but if you'd like to see that added just contact me. + +2) Opening and closing lots of POP3 connections can be quite a resource/network drain. If you need to send a whole batch of emails then just perform the authentication once at the start, and then loop through your mail sending script. Providing this process doesn't take longer than the verification period lasts on your POP3 server, you should be fine. With my host that period is 90 minutes, i.e. plenty of time. + +3) If you have heavy requirements for this script (i.e. send a LOT of email on a frequent basis) then I would advise seeking out an alternative sending method (direct SMTP ideally). If this isn't possible then you could modify this class so the 'last authorised' date is recorded somewhere (MySQL, Flat file, etc) meaning you only open a new connection if the old one has expired, saving you precious overhead. + +4) There are lots of other POP3 classes for PHP available. However most of them implement the full POP3 command set, where-as this one is purely for authentication, and much lighter as a result. However using any of the other POP3 classes to just logon to your server would have the same net result. At the end of the day, use whatever method you feel most comfortable with. +Download + +Here is the full class file plus my test script: POP_before_SMTP_PHPMailer.zip (4 KB) - Please note that it does not include PHPMailer itself. + +My thanks to Chris Ryan for the inspiration (even if indirectly, via his SMTP class) diff --git a/libraries/external/PHPMailer_v5.1/docs/use_gmail.txt b/libraries/external/PHPMailer_v5.1/docs/use_gmail.txt new file mode 100644 index 00000000..3669f5d2 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/docs/use_gmail.txt @@ -0,0 +1,45 @@ +getFile('contents.html'); +$body = eregi_replace("[\]",'',$body); + +$mail->IsSMTP(); +$mail->SMTPAuth = true; // enable SMTP authentication +$mail->SMTPSecure = "ssl"; // sets the prefix to the servier +$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server +$mail->Port = 465; // set the SMTP port + +$mail->Username = "yourname@gmail.com"; // GMAIL username +$mail->Password = "password"; // GMAIL password + +$mail->From = "replyto@yourdomain.com"; +$mail->FromName = "Webmaster"; +$mail->Subject = "This is the subject"; +$mail->AltBody = "This is the body when user views in plain text format"; //Text Body +$mail->WordWrap = 50; // set word wrap + +$mail->MsgHTML($body); + +$mail->AddReplyTo("replyto@yourdomain.com","Webmaster"); + +$mail->AddAttachment("/path/to/file.zip"); // attachment +$mail->AddAttachment("/path/to/image.jpg", "new.jpg"); // attachment + +$mail->AddAddress("username@domain.com","First Last"); + +$mail->IsHTML(true); // send as HTML + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message has been sent"; +} + +?> diff --git a/libraries/external/PHPMailer_v5.1/examples/contents.html b/libraries/external/PHPMailer_v5.1/examples/contents.html new file mode 100644 index 00000000..3d445ba4 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/contents.html @@ -0,0 +1,20 @@ + +
+

+
+ This is a test of PHPMailer.
+
+This particular example uses HTML, with a <div> tag and inline
+styles.
+
+Also note the use of the PHPMailer logo above with no specific code to handle +including it.
+Included are two attachments:
+phpmailer.gif is an attachment and used inline as a graphic (above)
+phpmailer_mini.gif is an attachment
+
+PHPMailer:
+Author: Andy Prevost (codeworxtech@users.sourceforge.net)
+Author: Marcus Bointon (coolbru@users.sourceforge.net)
+
+ diff --git a/libraries/external/PHPMailer_v5.1/examples/images/phpmailer.gif b/libraries/external/PHPMailer_v5.1/examples/images/phpmailer.gif new file mode 100644 index 00000000..5e269714 Binary files /dev/null and b/libraries/external/PHPMailer_v5.1/examples/images/phpmailer.gif differ diff --git a/libraries/external/PHPMailer_v5.1/examples/images/phpmailer_mini.gif b/libraries/external/PHPMailer_v5.1/examples/images/phpmailer_mini.gif new file mode 100644 index 00000000..dc7d7827 Binary files /dev/null and b/libraries/external/PHPMailer_v5.1/examples/images/phpmailer_mini.gif differ diff --git a/libraries/external/PHPMailer_v5.1/examples/index.html b/libraries/external/PHPMailer_v5.1/examples/index.html new file mode 100644 index 00000000..c81e35bc --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/index.html @@ -0,0 +1,49 @@ +This release of PHPMailer (v5.0.0) sets a new milestone in the development +cycle of PHPMailer. First, class.phpmailer.php has a small footprint (65.7 Kb), +while class.smtp.php is even smaller than before (at only 25.0 Kb).
+
+We have maintained all functionality and added Exception handling unique to +PHP 5/6.
+
+There is only one function that has been removed: that is getFile(). The reason +for this is that getFile() became a wrapper for the PHP function 'file_get_contents()' +and nothing more. Rather than burden the class with a function already available +in PHP, we decided to remove it.
+
+Our new Exception handling provides your own scripts far more power than ever.
+
+We have also enhanced the "packaging" of PHPMailer with an entirely new set of +examples. Included are both basic and advanced examples showing how you can take +advantage of PHP Exception handling to improve your own scripts.
+
+A few things to note about PHPMailer: +
    +
  • the use of $mail->AltBody is completely optional. If not used, PHPMailer + will use the HTML text with htmlentities().
    + We also highly recommend using HTML2Text authored by Jon Abernathy. The class description + and download can be viewed at: http://www.chuggnutt.com/html2text.php. +
  • +
  • there is no specific code to define image or attachment types ... that is handled + automatically by PHPMailer when it parses the images
  • +
+A note to users that want to use SMTP with PHPMailer. The most common problems are: +
    +
  • wrong port ... most ISP (Internet Service Providers) will not allow relaying through + their servers. If that's the case with your ISP, try using port 26. +
  • +
  • wrong authentication information (username and/or password) ... don't forget that + many servers require the account name to be in the format of the full email address. +
  • +
  • ... if these tips do not get your SMTP settings working, we have a debug mode + for helping you determine the problem. Insert this after $mail->IsSMTP();
    + $mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
    + note that a setting of 2 will display all errors and messages generated by the SMTP + server
    +
  • +
+Our examples all use an HTML file in the /examples folder. To see what the email SHOULD +look like in your HTML compatible email viewer: click here
+
+From the PHPMailer team:
+Author: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net (and Project Administrator)
+Author: Marcus Bointon (coolbru) coolbru@users.sourceforge.net
diff --git a/libraries/external/PHPMailer_v5.1/examples/test_db_smtp_basic.php b/libraries/external/PHPMailer_v5.1/examples/test_db_smtp_basic.php new file mode 100644 index 00000000..85d01f8d --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_db_smtp_basic.php @@ -0,0 +1,58 @@ + + +PHPMailer - MySQL Database - SMTP basic test with authentication + + + +IsSMTP(); // telling the class to use SMTP +$mail->Host = "smtp1.site.com;smtp2.site.com"; +$mail->SMTPAuth = true; // enable SMTP authentication +$mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent +$mail->Host = "mail.yourdomain.com"; // sets the SMTP server +$mail->Port = 26; // set the SMTP port for the GMAIL server +$mail->Username = "yourname@yourdomain"; // SMTP account username +$mail->Password = "yourpassword"; // SMTP account password +$mail->SetFrom('list@mydomain.com', 'List manager'); +$mail->AddReplyTo('list@mydomain.com', 'List manager'); + +$mail->Subject = "PHPMailer Test Subject via smtp, basic with authentication"; + +@MYSQL_CONNECT("localhost","root","password"); +@mysql_select_db("my_company"); +$query = "SELECT full_name, email, photo FROM employee WHERE id=$id"; +$result = @MYSQL_QUERY($query); + +while ($row = mysql_fetch_array ($result)) { + $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + $mail->MsgHTML($body); + $mail->AddAddress($row["email"], $row["full_name"]); + $mail->AddStringAttachment($row["photo"], "YourPhoto.jpg"); + + if(!$mail->Send()) { + echo "Mailer Error (" . str_replace("@", "@", $row["email"]) . ') ' . $mail->ErrorInfo . '
'; + } else { + echo "Message sent to :" . $row["full_name"] . ' (' . str_replace("@", "@", $row["email"]) . ')
'; + } + // Clear all addresses and attachments for next loop + $mail->ClearAddresses(); + $mail->ClearAttachments(); +} +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_mail_advanced.php b/libraries/external/PHPMailer_v5.1/examples/test_mail_advanced.php new file mode 100644 index 00000000..db0dd53b --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_mail_advanced.php @@ -0,0 +1,31 @@ + + +PHPMailer - Mail() advanced test + + + +AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->AddAddress('whoto@otherdomain.com', 'John Doe'); + $mail->SetFrom('name@yourdomain.com', 'First Last'); + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->Subject = 'PHPMailer Test Subject via mail(), advanced'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->Send(); + echo "Message Sent OK

\n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_mail_basic.php b/libraries/external/PHPMailer_v5.1/examples/test_mail_basic.php new file mode 100644 index 00000000..5db9f8fb --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_mail_basic.php @@ -0,0 +1,43 @@ + + +PHPMailer - Mail() basic test + + + +AddReplyTo("name@yourdomain.com","First Last"); + +$mail->SetFrom('name@yourdomain.com', 'First Last'); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$address = "whoto@otherdomain.com"; +$mail->AddAddress($address, "John Doe"); + +$mail->Subject = "PHPMailer Test Subject via mail(), basic"; + +$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + +$mail->MsgHTML($body); + +$mail->AddAttachment("images/phpmailer.gif"); // attachment +$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_pop_before_smtp_advanced.php b/libraries/external/PHPMailer_v5.1/examples/test_pop_before_smtp_advanced.php new file mode 100644 index 00000000..1828b30b --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_pop_before_smtp_advanced.php @@ -0,0 +1,40 @@ + + +POP before SMTP Test + + + +Authorise('pop3.yourdomain.com', 110, 30, 'username', 'password', 1); + +$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch + +$mail->IsSMTP(); + +try { + $mail->SMTPDebug = 2; + $mail->Host = 'pop3.yourdomain.com'; + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->AddAddress('whoto@otherdomain.com', 'John Doe'); + $mail->SetFrom('name@yourdomain.com', 'First Last'); + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->Subject = 'PHPMailer Test Subject via mail(), advanced'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->Send(); + echo "Message Sent OK

\n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_pop_before_smtp_basic.php b/libraries/external/PHPMailer_v5.1/examples/test_pop_before_smtp_basic.php new file mode 100644 index 00000000..3673436a --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_pop_before_smtp_basic.php @@ -0,0 +1,49 @@ + + +POP before SMTP Test + + + +Authorise('pop3.yourdomain.com', 110, 30, 'username', 'password', 1); + +$mail = new PHPMailer(); + +$body = file_get_contents('contents.html'); +$body = eregi_replace("[\]",'',$body); + +$mail->IsSMTP(); +$mail->SMTPDebug = 2; +$mail->Host = 'pop3.yourdomain.com'; + +$mail->SetFrom('name@yourdomain.com', 'First Last'); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$mail->Subject = "PHPMailer Test Subject via POP before SMTP, basic"; + +$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + +$mail->MsgHTML($body); + +$address = "whoto@otherdomain.com"; +$mail->AddAddress($address, "John Doe"); + +$mail->AddAttachment("images/phpmailer.gif"); // attachment +$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment + + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_sendmail_advanced.php b/libraries/external/PHPMailer_v5.1/examples/test_sendmail_advanced.php new file mode 100644 index 00000000..46024525 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_sendmail_advanced.php @@ -0,0 +1,34 @@ + + +PHPMailer - Sendmail advanced test + + + +IsSendmail(); // telling the class to use SendMail transport + +try { + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->AddAddress('whoto@otherdomain.com', 'John Doe'); + $mail->SetFrom('name@yourdomain.com', 'First Last'); + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->Subject = 'PHPMailer Test Subject via mail(), advanced'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->Send(); + echo "Message Sent OK

\n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_sendmail_basic.php b/libraries/external/PHPMailer_v5.1/examples/test_sendmail_basic.php new file mode 100644 index 00000000..46c05e39 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_sendmail_basic.php @@ -0,0 +1,45 @@ + + +PHPMailer - Sendmail basic test + + + +IsSendmail(); // telling the class to use SendMail transport + +$body = file_get_contents('contents.html'); +$body = eregi_replace("[\]",'',$body); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$mail->SetFrom('name@yourdomain.com', 'First Last'); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$address = "whoto@otherdomain.com"; +$mail->AddAddress($address, "John Doe"); + +$mail->Subject = "PHPMailer Test Subject via Sendmail, basic"; + +$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + +$mail->MsgHTML($body); + +$mail->AddAttachment("images/phpmailer.gif"); // attachment +$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_smtp_advanced.php b/libraries/external/PHPMailer_v5.1/examples/test_smtp_advanced.php new file mode 100644 index 00000000..71a8614a --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_smtp_advanced.php @@ -0,0 +1,43 @@ + + +PHPMailer - SMTP advanced test with authentication + + + +IsSMTP(); // telling the class to use SMTP + +try { + $mail->Host = "mail.yourdomain.com"; // SMTP server + $mail->SMTPDebug = 2; // enables SMTP debug information (for testing) + $mail->SMTPAuth = true; // enable SMTP authentication + $mail->Host = "mail.yourdomain.com"; // sets the SMTP server + $mail->Port = 26; // set the SMTP port for the GMAIL server + $mail->Username = "yourname@yourdomain"; // SMTP account username + $mail->Password = "yourpassword"; // SMTP account password + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->AddAddress('whoto@otherdomain.com', 'John Doe'); + $mail->SetFrom('name@yourdomain.com', 'First Last'); + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->Subject = 'PHPMailer Test Subject via mail(), advanced'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->Send(); + echo "Message Sent OK

\n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_smtp_advanced_no_auth.php b/libraries/external/PHPMailer_v5.1/examples/test_smtp_advanced_no_auth.php new file mode 100644 index 00000000..69b9b5d4 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_smtp_advanced_no_auth.php @@ -0,0 +1,37 @@ + + +PHPMailer - SMTP advanced test with no authentication + + + +IsSMTP(); // telling the class to use SMTP + +try { + $mail->Host = "mail.yourdomain.com"; // SMTP server + $mail->SMTPDebug = 2; // enables SMTP debug information (for testing) + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->AddAddress('whoto@otherdomain.com', 'John Doe'); + $mail->SetFrom('name@yourdomain.com', 'First Last'); + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->Subject = 'PHPMailer Test Subject via mail(), advanced'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->Send(); + echo "Message Sent OK

\n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_smtp_basic.php b/libraries/external/PHPMailer_v5.1/examples/test_smtp_basic.php new file mode 100644 index 00000000..f92c5313 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_smtp_basic.php @@ -0,0 +1,58 @@ + + +PHPMailer - SMTP basic test with authentication + + + +IsSMTP(); // telling the class to use SMTP +$mail->Host = "mail.yourdomain.com"; // SMTP server +$mail->SMTPDebug = 2; // enables SMTP debug information (for testing) + // 1 = errors and messages + // 2 = messages only +$mail->SMTPAuth = true; // enable SMTP authentication +$mail->Host = "mail.yourdomain.com"; // sets the SMTP server +$mail->Port = 26; // set the SMTP port for the GMAIL server +$mail->Username = "yourname@yourdomain"; // SMTP account username +$mail->Password = "yourpassword"; // SMTP account password + +$mail->SetFrom('name@yourdomain.com', 'First Last'); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$mail->Subject = "PHPMailer Test Subject via smtp, basic with authentication"; + +$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + +$mail->MsgHTML($body); + +$address = "whoto@otherdomain.com"; +$mail->AddAddress($address, "John Doe"); + +$mail->AddAttachment("images/phpmailer.gif"); // attachment +$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_smtp_basic_no_auth.php b/libraries/external/PHPMailer_v5.1/examples/test_smtp_basic_no_auth.php new file mode 100644 index 00000000..d96cda25 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_smtp_basic_no_auth.php @@ -0,0 +1,53 @@ + + +PHPMailer - SMTP basic test with no authentication + + + +IsSMTP(); // telling the class to use SMTP +$mail->Host = "mail.yourdomain.com"; // SMTP server +$mail->SMTPDebug = 2; // enables SMTP debug information (for testing) + // 1 = errors and messages + // 2 = messages only + +$mail->SetFrom('name@yourdomain.com', 'First Last'); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$mail->Subject = "PHPMailer Test Subject via smtp, basic with no authentication"; + +$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + +$mail->MsgHTML($body); + +$address = "whoto@otherdomain.com"; +$mail->AddAddress($address, "John Doe"); + +$mail->AddAttachment("images/phpmailer.gif"); // attachment +$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_smtp_gmail_advanced.php b/libraries/external/PHPMailer_v5.1/examples/test_smtp_gmail_advanced.php new file mode 100644 index 00000000..055cc618 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_smtp_gmail_advanced.php @@ -0,0 +1,43 @@ + + +PHPMailer - SMTP (Gmail) advanced test + + + +IsSMTP(); // telling the class to use SMTP + +try { + $mail->Host = "mail.yourdomain.com"; // SMTP server + $mail->SMTPDebug = 2; // enables SMTP debug information (for testing) + $mail->SMTPAuth = true; // enable SMTP authentication + $mail->SMTPSecure = "ssl"; // sets the prefix to the servier + $mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server + $mail->Port = 465; // set the SMTP port for the GMAIL server + $mail->Username = "yourusername@gmail.com"; // GMAIL username + $mail->Password = "yourpassword"; // GMAIL password + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->AddAddress('whoto@otherdomain.com', 'John Doe'); + $mail->SetFrom('name@yourdomain.com', 'First Last'); + $mail->AddReplyTo('name@yourdomain.com', 'First Last'); + $mail->Subject = 'PHPMailer Test Subject via mail(), advanced'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->Send(); + echo "Message Sent OK

\n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/examples/test_smtp_gmail_basic.php b/libraries/external/PHPMailer_v5.1/examples/test_smtp_gmail_basic.php new file mode 100644 index 00000000..3f578807 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/examples/test_smtp_gmail_basic.php @@ -0,0 +1,59 @@ + + +PHPMailer - SMTP (Gmail) basic test + + + +IsSMTP(); // telling the class to use SMTP +$mail->Host = "mail.yourdomain.com"; // SMTP server +$mail->SMTPDebug = 2; // enables SMTP debug information (for testing) + // 1 = errors and messages + // 2 = messages only +$mail->SMTPAuth = true; // enable SMTP authentication +$mail->SMTPSecure = "ssl"; // sets the prefix to the servier +$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server +$mail->Port = 465; // set the SMTP port for the GMAIL server +$mail->Username = "yourusername@gmail.com"; // GMAIL username +$mail->Password = "yourpassword"; // GMAIL password + +$mail->SetFrom('name@yourdomain.com', 'First Last'); + +$mail->AddReplyTo("name@yourdomain.com","First Last"); + +$mail->Subject = "PHPMailer Test Subject via smtp (Gmail), basic"; + +$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + +$mail->MsgHTML($body); + +$address = "whoto@otherdomain.com"; +$mail->AddAddress($address, "John Doe"); + +$mail->AddAttachment("images/phpmailer.gif"); // attachment +$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment + +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +?> + + + diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ar.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ar.php new file mode 100644 index 00000000..b7c5057d --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ar.php @@ -0,0 +1,27 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: لم نستطع تأكيد الهوية.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: لم يتم قبول المعلومات .'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'ترميز غير معروÙ: '; +$PHPMAILER_LANG['execute'] = 'لم أستطع تنÙيذ : '; +$PHPMAILER_LANG['file_access'] = 'لم نستطع الوصول للملÙ: '; +$PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع Ùتح الملÙ: '; +$PHPMAILER_LANG['from_failed'] = 'البريد التالي لم نستطع ارسال البريد له : '; +$PHPMAILER_LANG['instantiate'] = 'لم نستطع توÙير خدمة البريد.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.'; +//$PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: الأخطاء التالية ' . + 'Ùشل ÙÙŠ الارسال لكل من : '; +$PHPMAILER_LANG['signing'] = 'خطأ ÙÙŠ التوقيع: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-br.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-br.php new file mode 100644 index 00000000..7d64ce4d --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-br.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ca.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ca.php new file mode 100644 index 00000000..1127567d --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ca.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ch.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ch.php new file mode 100644 index 00000000..31ebd861 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ch.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-cz.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-cz.php new file mode 100644 index 00000000..f9589ca1 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-cz.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-de.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-de.php new file mode 100644 index 00000000..165a86f4 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-de.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-dk.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-dk.php new file mode 100644 index 00000000..59b58c0f --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-dk.php @@ -0,0 +1,26 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Kunne ikke logge pÃ¥.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data kunne ikke accepteres.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: '; +$PHPMAILER_LANG['execute'] = 'Kunne ikke køre: '; +$PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: '; +$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke Ã¥bne filen: '; +$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: '; +$PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere email funktionen.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; +$PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-es.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-es.php new file mode 100644 index 00000000..0b698250 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-es.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-et.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-et.php new file mode 100644 index 00000000..cf61779b --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-et.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fi.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fi.php new file mode 100644 index 00000000..6d7dccee --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fi.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fo.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fo.php new file mode 100644 index 00000000..704c4772 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fo.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fr.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fr.php new file mode 100644 index 00000000..52e9ae2b --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-fr.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-hu.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-hu.php new file mode 100644 index 00000000..a2664848 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-hu.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-it.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-it.php new file mode 100644 index 00000000..59bf4fb9 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-it.php @@ -0,0 +1,27 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: Impossibile autenticarsi.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi all\'host SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Data non accettati dal server.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Encoding set dei caratteri sconosciuto: '; +$PHPMAILER_LANG['execute'] = 'Impossibile eseguire l\'operazione: '; +$PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: '; +$PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: '; +$PHPMAILER_LANG['from_failed'] = 'I seguenti indirizzi mittenti hanno generato errore: '; +$PHPMAILER_LANG['instantiate'] = 'Impossibile istanziare la funzione mail'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente'; +$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: I seguenti indirizzi destinatari hanno generato errore: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ja.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ja.php new file mode 100644 index 00000000..66da1b6a --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ja.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-nl.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-nl.php new file mode 100644 index 00000000..355dcdc4 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-nl.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-no.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-no.php new file mode 100644 index 00000000..bf2f84ee --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-no.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-pl.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-pl.php new file mode 100644 index 00000000..e8bd5124 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-pl.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ro.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ro.php new file mode 100644 index 00000000..17cddb76 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ro.php @@ -0,0 +1,27 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'Eroare SMTP: Nu a functionat autentificarea.'; +$PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Encodare necunoscuta: '; +$PHPMAILER_LANG['execute'] = 'Nu pot executa: '; +$PHPMAILER_LANG['file_access'] = 'Nu pot accesa fisierul: '; +$PHPMAILER_LANG['file_open'] = 'Eroare de fisier: Nu pot deschide fisierul: '; +$PHPMAILER_LANG['from_failed'] = 'Urmatoarele adrese From au dat eroare: '; +$PHPMAILER_LANG['instantiate'] = 'Nu am putut instantia functia mail.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.'; +$PHPMAILER_LANG['provide_address'] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; +$PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ru.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ru.php new file mode 100644 index 00000000..295a56ef --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-ru.php @@ -0,0 +1,25 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.'; +$PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удаетÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒÑÑ Ðº Ñерверу SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не принÑÑ‚Ñ‹.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'ÐеизвеÑтный вид кодировки: '; +$PHPMAILER_LANG['execute'] = 'Ðевозможно выполнить команду: '; +$PHPMAILER_LANG['file_access'] = 'Ðет доÑтупа к файлу: '; +$PHPMAILER_LANG['file_open'] = 'Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°: не удаетÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ файл: '; +$PHPMAILER_LANG['from_failed'] = 'Ðеверный Ð°Ð´Ñ€ÐµÑ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÐµÐ»Ñ: '; +$PHPMAILER_LANG['instantiate'] = 'Ðевозможно запуÑтить функцию mail.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'ПожалуйÑта, введите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один Ð°Ð´Ñ€ÐµÑ e-mail получателÑ.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый Ñервер не поддерживаетÑÑ.'; +$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по Ñледующим адреÑам получателей не удалаÑÑŒ: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-se.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-se.php new file mode 100644 index 00000000..d459667f --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-se.php @@ -0,0 +1,26 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP fel: Kunde inte autentisera.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fel: Kunde inte ansluta till SMTP-server.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fel: Data accepterades inte.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Okänt encode-format: '; +$PHPMAILER_LANG['execute'] = 'Kunde inte köra: '; +$PHPMAILER_LANG['file_access'] = 'Ingen Ã¥tkomst till fil: '; +$PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: '; +$PHPMAILER_LANG['from_failed'] = 'Följande avsändaradress är felaktig: '; +$PHPMAILER_LANG['instantiate'] = 'Kunde inte initiera e-postfunktion.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'Du mÃ¥ste ange minst en mottagares e-postadress.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-tr.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-tr.php new file mode 100644 index 00000000..8a069d14 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-tr.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-zh.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-zh.php new file mode 100644 index 00000000..fef66f8c --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-zh.php @@ -0,0 +1,26 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登錄失敗。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連接到 SMTP 主機。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:數據ä¸è¢«æŽ¥å—。'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = '未知編碼: '; +$PHPMAILER_LANG['file_access'] = '無法訪å•æ–‡ä»¶ï¼š'; +$PHPMAILER_LANG['file_open'] = '文件錯誤:無法打開文件:'; +$PHPMAILER_LANG['from_failed'] = '發é€åœ°å€éŒ¯èª¤ï¼š'; +$PHPMAILER_LANG['execute'] = '無法執行:'; +$PHPMAILER_LANG['instantiate'] = '未知函數調用。'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'å¿…é ˆæ供至少一個收件人地å€ã€‚'; +$PHPMAILER_LANG['mailer_not_supported'] = '發信客戶端ä¸è¢«æ”¯æŒã€‚'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:收件人地å€éŒ¯èª¤ï¼š'; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-zh_cn.php b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-zh_cn.php new file mode 100644 index 00000000..b1884043 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/language/phpmailer.lang-zh_cn.php @@ -0,0 +1,26 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数æ®ä¸è¢«æŽ¥å—。'; +//$P$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = '未知编ç : '; +$PHPMAILER_LANG['execute'] = '无法执行:'; +$PHPMAILER_LANG['file_access'] = '无法访问文件:'; +$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; +$PHPMAILER_LANG['from_failed'] = 'å‘é€åœ°å€é”™è¯¯ï¼š'; +$PHPMAILER_LANG['instantiate'] = '未知函数调用。'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = 'å‘信客户端ä¸è¢«æ”¯æŒã€‚'; +$PHPMAILER_LANG['provide_address'] = 'å¿…é¡»æ供至少一个收件人地å€ã€‚'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地å€é”™è¯¯ï¼š'; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/test/contents.html b/libraries/external/PHPMailer_v5.1/test/contents.html new file mode 100644 index 00000000..dbb8bfee --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/test/contents.html @@ -0,0 +1,10 @@ + + + + Email test + + + +

Here is a test HTML email

+ + diff --git a/libraries/external/PHPMailer_v5.1/test/phpmailerTest.php b/libraries/external/PHPMailer_v5.1/test/phpmailerTest.php new file mode 100644 index 00000000..9fb8e44f --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/test/phpmailerTest.php @@ -0,0 +1,670 @@ +Mail = new PHPMailer(); + + $this->Mail->Priority = 3; + $this->Mail->Encoding = "8bit"; + $this->Mail->CharSet = "iso-8859-1"; + if (array_key_exists('mail_from', $_REQUEST)) { + $this->Mail->From = $_REQUEST['mail_from']; + } else { + $this->Mail->From = 'unit_test@phpmailer.sf.net'; + } + $this->Mail->FromName = "Unit Tester"; + $this->Mail->Sender = ""; + $this->Mail->Subject = "Unit Test"; + $this->Mail->Body = ""; + $this->Mail->AltBody = ""; + $this->Mail->WordWrap = 0; + if (array_key_exists('mail_host', $_REQUEST)) { + $this->Mail->Host = $_REQUEST['mail_host']; + } else { + $this->Mail->Host = 'mail.example.com'; + } + $this->Mail->Port = 25; + $this->Mail->Helo = "localhost.localdomain"; + $this->Mail->SMTPAuth = false; + $this->Mail->Username = ""; + $this->Mail->Password = ""; + $this->Mail->PluginDir = $INCLUDE_DIR; + $this->Mail->AddReplyTo("no_reply@phpmailer.sf.net", "Reply Guy"); + $this->Mail->Sender = "unit_test@phpmailer.sf.net"; + + if(strlen($this->Mail->Host) > 0) { + $this->Mail->Mailer = "smtp"; + } else { + $this->Mail->Mailer = "mail"; + $this->Sender = "unit_test@phpmailer.sf.net"; + } + + if (array_key_exists('mail_to', $_REQUEST)) { + $this->SetAddress($_REQUEST['mail_to'], 'Test User', 'to'); + } + if (array_key_exists('mail_cc', $_REQUEST) and strlen($_REQUEST['mail_cc']) > 0) { + $this->SetAddress($_REQUEST['mail_cc'], 'Carbon User', 'cc'); + } + } + + /** + * Run after each test is completed. + */ + function tearDown() { + // Clean global variables + $this->Mail = NULL; + $this->ChangeLog = array(); + $this->NoteLog = array(); + } + + + /** + * Build the body of the message in the appropriate format. + * @private + * @returns void + */ + function BuildBody() { + $this->CheckChanges(); + + // Determine line endings for message + if($this->Mail->ContentType == "text/html" || strlen($this->Mail->AltBody) > 0) + { + $eol = "
"; + $bullet = "
  • "; + $bullet_start = "
      "; + $bullet_end = "
    "; + } + else + { + $eol = "\n"; + $bullet = " - "; + $bullet_start = ""; + $bullet_end = ""; + } + + $ReportBody = ""; + + $ReportBody .= "---------------------" . $eol; + $ReportBody .= "Unit Test Information" . $eol; + $ReportBody .= "---------------------" . $eol; + $ReportBody .= "phpmailer version: " . PHPMailer::VERSION . $eol; + $ReportBody .= "Content Type: " . $this->Mail->ContentType . $eol; + + if(strlen($this->Mail->Host) > 0) + $ReportBody .= "Host: " . $this->Mail->Host . $eol; + + // If attachments then create an attachment list + $attachments = $this->Mail->GetAttachments(); + if(count($attachments) > 0) + { + $ReportBody .= "Attachments:" . $eol; + $ReportBody .= $bullet_start; + foreach($attachments as $attachment) { + $ReportBody .= $bullet . "Name: " . $attachment[1] . ", "; + $ReportBody .= "Encoding: " . $attachment[3] . ", "; + $ReportBody .= "Type: " . $attachment[4] . $eol; + } + $ReportBody .= $bullet_end . $eol; + } + + // If there are changes then list them + if(count($this->ChangeLog) > 0) + { + $ReportBody .= "Changes" . $eol; + $ReportBody .= "-------" . $eol; + + $ReportBody .= $bullet_start; + for($i = 0; $i < count($this->ChangeLog); $i++) + { + $ReportBody .= $bullet . $this->ChangeLog[$i][0] . " was changed to [" . + $this->ChangeLog[$i][1] . "]" . $eol; + } + $ReportBody .= $bullet_end . $eol . $eol; + } + + // If there are notes then list them + if(count($this->NoteLog) > 0) + { + $ReportBody .= "Notes" . $eol; + $ReportBody .= "-----" . $eol; + + $ReportBody .= $bullet_start; + for($i = 0; $i < count($this->NoteLog); $i++) + { + $ReportBody .= $bullet . $this->NoteLog[$i] . $eol; + } + $ReportBody .= $bullet_end; + } + + // Re-attach the original body + $this->Mail->Body .= $eol . $eol . $ReportBody; + } + + /** + * Check which default settings have been changed for the report. + * @private + * @returns void + */ + function CheckChanges() { + if($this->Mail->Priority != 3) + $this->AddChange("Priority", $this->Mail->Priority); + if($this->Mail->Encoding != "8bit") + $this->AddChange("Encoding", $this->Mail->Encoding); + if($this->Mail->CharSet != "iso-8859-1") + $this->AddChange("CharSet", $this->Mail->CharSet); + if($this->Mail->Sender != "") + $this->AddChange("Sender", $this->Mail->Sender); + if($this->Mail->WordWrap != 0) + $this->AddChange("WordWrap", $this->Mail->WordWrap); + if($this->Mail->Mailer != "mail") + $this->AddChange("Mailer", $this->Mail->Mailer); + if($this->Mail->Port != 25) + $this->AddChange("Port", $this->Mail->Port); + if($this->Mail->Helo != "localhost.localdomain") + $this->AddChange("Helo", $this->Mail->Helo); + if($this->Mail->SMTPAuth) + $this->AddChange("SMTPAuth", "true"); + } + + /** + * Adds a change entry. + * @private + * @returns void + */ + function AddChange($sName, $sNewValue) { + $cur = count($this->ChangeLog); + $this->ChangeLog[$cur][0] = $sName; + $this->ChangeLog[$cur][1] = $sNewValue; + } + + /** + * Adds a simple note to the message. + * @public + * @returns void + */ + function AddNote($sValue) { + $this->NoteLog[] = $sValue; + } + + /** + * Adds all of the addresses + * @public + * @returns void + */ + function SetAddress($sAddress, $sName = "", $sType = "to") { + switch($sType) + { + case "to": + return $this->Mail->AddAddress($sAddress, $sName); + case "cc": + return $this->Mail->AddCC($sAddress, $sName); + case "bcc": + return $this->Mail->AddBCC($sAddress, $sName); + } + } + + ///////////////////////////////////////////////// + // UNIT TESTS + ///////////////////////////////////////////////// + + /** + * Try a plain message. + */ + function test_WordWrap() { + + $this->Mail->WordWrap = 40; + $my_body = "Here is the main body of this message. It should " . + "be quite a few lines. It should be wrapped at the " . + "40 characters. Make sure that it is."; + $nBodyLen = strlen($my_body); + $my_body .= "\n\nThis is the above body length: " . $nBodyLen; + + $this->Mail->Body = $my_body; + $this->Mail->Subject .= ": Wordwrap"; + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Try a plain message. + */ + function test_Low_Priority() { + + $this->Mail->Priority = 5; + $this->Mail->Body = "Here is the main body. There should be " . + "a reply to address in this message."; + $this->Mail->Subject .= ": Low Priority"; + $this->Mail->AddReplyTo("nobody@nobody.com", "Nobody (Unit Test)"); + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Simple plain file attachment test. + */ + function test_Multiple_Plain_FileAttachment() { + + $this->Mail->Body = "Here is the text body"; + $this->Mail->Subject .= ": Plain + Multiple FileAttachments"; + + if(!$this->Mail->AddAttachment("test.png")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + if(!$this->Mail->AddAttachment(__FILE__, "test.txt")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Simple plain string attachment test. + */ + function test_Plain_StringAttachment() { + + $this->Mail->Body = "Here is the text body"; + $this->Mail->Subject .= ": Plain + StringAttachment"; + + $sAttachment = "These characters are the content of the " . + "string attachment.\nThis might be taken from a ". + "database or some other such thing. "; + + $this->Mail->AddStringAttachment($sAttachment, "string_attach.txt"); + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Plain quoted-printable message. + */ + function test_Quoted_Printable() { + + $this->Mail->Body = "Here is the main body"; + $this->Mail->Subject .= ": Plain + Quoted-printable"; + $this->Mail->Encoding = "quoted-printable"; + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + + //Check that a quoted printable encode and decode results in the same as went in + $t = substr(file_get_contents(__FILE__), 0, 1024); //Just pick a chunk of this file as test content + $this->assertEquals($t, quoted_printable_decode($this->Mail->EncodeQP($t)), 'QP encoding round-trip failed'); + //$this->assertEquals($t, quoted_printable_decode($this->Mail->EncodeQPphp($t)), 'Native PHP QP encoding round-trip failed'); //TODO the PHP qp encoder is quite broken + + } + + /** + * Try a plain message. + */ + function test_Html() { + + $this->Mail->IsHTML(true); + $this->Mail->Subject .= ": HTML only"; + + $this->Mail->Body = "This is a test message written in HTML.
    " . + "Go to " . + "http://phpmailer.sourceforge.net/ for new versions of " . + "phpmailer.

    Thank you!"; + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Simple HTML and attachment test + */ + function test_HTML_Attachment() { + + $this->Mail->Body = "This is the HTML part of the email."; + $this->Mail->Subject .= ": HTML + Attachment"; + $this->Mail->IsHTML(true); + + if(!$this->Mail->AddAttachment(__FILE__, "test_attach.txt")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * An embedded attachment test. + */ + function test_Embedded_Image() { + + $this->Mail->Body = "Embedded Image: \"phpmailer\"" . + "Here is an image!"; + $this->Mail->Subject .= ": Embedded Image"; + $this->Mail->IsHTML(true); + + if(!$this->Mail->AddEmbeddedImage("test.png", "my-attach", "test.png", + "base64", "image/png")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + //For code coverage + $this->Mail->AddEmbeddedImage('thisfiledoesntexist', 'xyz'); //Non-existent file + $this->Mail->AddEmbeddedImage(__FILE__, '123'); //Missing name + + } + + /** + * An embedded attachment test. + */ + function test_Multi_Embedded_Image() { + + $this->Mail->Body = "Embedded Image: \"phpmailer\"" . + "Here is an image!"; + $this->Mail->Subject .= ": Embedded Image + Attachment"; + $this->Mail->IsHTML(true); + + if(!$this->Mail->AddEmbeddedImage("test.png", "my-attach", "test.png", + "base64", "image/png")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + if(!$this->Mail->AddAttachment(__FILE__, "test.txt")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Simple multipart/alternative test. + */ + function test_AltBody() { + + $this->Mail->Body = "This is the HTML part of the email."; + $this->Mail->AltBody = "Here is the text body of this message. " . + "It should be quite a few lines. It should be wrapped at the " . + "40 characters. Make sure that it is."; + $this->Mail->WordWrap = 40; + $this->AddNote("This is a mulipart alternative email"); + $this->Mail->Subject .= ": AltBody + Word Wrap"; + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + /** + * Simple HTML and attachment test + */ + function test_AltBody_Attachment() { + + $this->Mail->Body = "This is the HTML part of the email."; + $this->Mail->AltBody = "This is the text part of the email."; + $this->Mail->Subject .= ": AltBody + Attachment"; + $this->Mail->IsHTML(true); + + if(!$this->Mail->AddAttachment(__FILE__, "test_attach.txt")) + { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + $this->BuildBody(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + if (is_writable('.')) { + file_put_contents('message.txt', $this->Mail->CreateHeader() . $this->Mail->CreateBody()); + } else { + $this->assertTrue(false, 'Could not write local file - check permissions'); + } + } + + function test_MultipleSend() { + $this->Mail->Body = "Sending two messages without keepalive"; + $this->BuildBody(); + $subject = $this->Mail->Subject; + + $this->Mail->Subject = $subject . ": SMTP 1"; + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + + $this->Mail->Subject = $subject . ": SMTP 2"; + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + function test_SendmailSend() { + $this->Mail->Body = "Sending via sendmail"; + $this->BuildBody(); + $subject = $this->Mail->Subject; + + $this->Mail->Subject = $subject . ": sendmail"; + $this->Mail->IsSendmail(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + function test_MailSend() { + $this->Mail->Body = "Sending via mail()"; + $this->BuildBody(); + $subject = $this->Mail->Subject; + + $this->Mail->Subject = $subject . ": mail()"; + $this->Mail->IsMail(); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + function test_SmtpKeepAlive() { + $this->Mail->Body = "This was done using the SMTP keep-alive."; + $this->BuildBody(); + $subject = $this->Mail->Subject; + + $this->Mail->SMTPKeepAlive = true; + $this->Mail->Subject = $subject . ": SMTP keep-alive 1"; + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + + $this->Mail->Subject = $subject . ": SMTP keep-alive 2"; + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + $this->Mail->SmtpClose(); + } + + /** + * Tests this denial of service attack: + * http://www.cybsec.com/vuln/PHPMailer-DOS.pdf + */ + function test_DenialOfServiceAttack() { + $this->Mail->Body = "This should no longer cause a denial of service."; + $this->BuildBody(); + + $this->Mail->Subject = str_repeat("A", 998); + $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo); + } + + function test_Error() { + $this->Mail->Subject .= ": This should be sent"; + $this->BuildBody(); + $this->Mail->ClearAllRecipients(); // no addresses should cause an error + $this->assertTrue($this->Mail->IsError() == false, "Error found"); + $this->assertTrue($this->Mail->Send() == false, "Send succeeded"); + $this->assertTrue($this->Mail->IsError(), "No error found"); + $this->assertEquals('You must provide at least one recipient email address.', $this->Mail->ErrorInfo); + $this->Mail->AddAddress($_REQUEST['mail_to']); + $this->assertTrue($this->Mail->Send(), "Send failed"); + } + + function test_Addressing() { + $this->assertFalse($this->Mail->AddAddress('a@example..com'), 'Invalid address accepted'); + $this->assertTrue($this->Mail->AddAddress('a@example.com'), 'Addressing failed'); + $this->assertFalse($this->Mail->AddAddress('a@example.com'), 'Duplicate addressing failed'); + $this->assertTrue($this->Mail->AddCC('b@example.com'), 'CC addressing failed'); + $this->assertFalse($this->Mail->AddCC('b@example.com'), 'CC duplicate addressing failed'); + $this->assertFalse($this->Mail->AddCC('a@example.com'), 'CC duplicate addressing failed (2)'); + $this->assertTrue($this->Mail->AddBCC('c@example.com'), 'BCC addressing failed'); + $this->assertFalse($this->Mail->AddBCC('c@example.com'), 'BCC duplicate addressing failed'); + $this->assertFalse($this->Mail->AddBCC('a@example.com'), 'BCC duplicate addressing failed (2)'); + $this->assertTrue($this->Mail->AddReplyTo('a@example.com'), 'Replyto Addressing failed'); + $this->assertFalse($this->Mail->AddReplyTo('a@example..com'), 'Invalid Replyto address accepted'); + $this->Mail->ClearAddresses(); + $this->Mail->ClearCCs(); + $this->Mail->ClearBCCs(); + $this->Mail->ClearReplyTos(); + } + + /** + * Test language files for missing and excess translations + * All languages are compared with English + */ + function test_Translations() { + $this->Mail->SetLanguage('en'); + $definedStrings = $this->Mail->GetTranslations(); + foreach (new DirectoryIterator('../language') as $fileInfo) { + if($fileInfo->isDot()) continue; + $matches = array(); + //Only look at language files, ignore anything else in there + if (preg_match('/^phpmailer\.lang-([a-z_]{2,})\.php$/', $fileInfo->getFilename(), $matches)) { + $lang = $matches[1]; //Extract language code + $PHPMAILER_LANG = array(); //Language strings get put in here + include $fileInfo->getPathname(); //Get language strings + $missing = array_diff(array_keys($definedStrings), array_keys($PHPMAILER_LANG)); + $extra = array_diff(array_keys($PHPMAILER_LANG), array_keys($definedStrings)); + $this->assertTrue(empty($missing), "Missing translations in $lang: ". implode(', ', $missing)); + $this->assertTrue(empty($extra), "Extra translations in $lang: ". implode(', ', $extra)); + } + } + } + + /** + * Encoding tests + */ + function test_Encodings() { + $this->Mail->Charset = 'iso-8859-1'; + $this->assertEquals('=A1Hola!_Se=F1or!', $this->Mail->EncodeQ('¡Hola! Señor!', 'text'), 'Q Encoding (text) failed'); + $this->assertEquals('=A1Hola!_Se=F1or!', $this->Mail->EncodeQ('¡Hola! Señor!', 'comment'), 'Q Encoding (comment) failed'); + $this->assertEquals('=A1Hola!_Se=F1or!', $this->Mail->EncodeQ('¡Hola! Señor!', 'phrase'), 'Q Encoding (phrase) failed'); + } + + /** + * Signing tests + */ + function test_Signing() { + $this->Mail->Sign('certfile.txt', 'keyfile.txt', 'password'); //TODO this is not really testing signing, but at least helps coverage + } + + /** + * Miscellaneous calls to improve test coverage and some small tests + */ + function test_Miscellaneous() { + $this->assertEquals('application/pdf', PHPMailer::_mime_types('pdf') , 'MIME TYPE lookup failed'); + $this->Mail->AddCustomHeader('SomeHeader: Some Value'); + $this->Mail->ClearCustomHeaders(); + $this->Mail->ClearAttachments(); + $this->Mail->IsHTML(false); + $this->Mail->IsSMTP(); + $this->Mail->IsMail(); + $this->Mail->IsSendMail(); + $this->Mail->IsQmail(); + $this->Mail->SetLanguage('fr'); + $this->Mail->Sender = ''; + $this->Mail->CreateHeader(); + $this->assertFalse($this->Mail->set('x', 'y'), 'Invalid property set succeeded'); + $this->assertTrue($this->Mail->set('Timeout', 11), 'Valid property set failed'); + $this->Mail->getFile(__FILE__); + } +} + +/** +* This is a sample form for setting appropriate test values through a browser +* These values can also be set using a file called testbootstrap.php (not in svn) in the same folder as this script +* which is probably more useful if you run these tests a lot + + +

    phpmailer Unit Test

    +By entering a SMTP hostname it will automatically perform tests with SMTP. + +
    + +From Address: "/> +
    +To Address: "/> +
    +Cc Address: "/> +
    +SMTP Hostname: "/> +

    + + +

    + + + */ + +?> \ No newline at end of file diff --git a/libraries/external/PHPMailer_v5.1/test/test.png b/libraries/external/PHPMailer_v5.1/test/test.png new file mode 100644 index 00000000..02de5a7a Binary files /dev/null and b/libraries/external/PHPMailer_v5.1/test/test.png differ diff --git a/libraries/external/PHPMailer_v5.1/test/test_callback.php b/libraries/external/PHPMailer_v5.1/test/test_callback.php new file mode 100644 index 00000000..4b3dfd6f --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/test/test_callback.php @@ -0,0 +1,84 @@ + + +PHPMailer Lite - DKIM and Callback Function test + + + +\n"; + return true; +} + +$testLite = false; + +if ($testLite) { + require_once '../class.phpmailer-lite.php'; + $mail = new PHPMailerLite(); +} else { + require_once '../class.phpmailer.php'; + $mail = new PHPMailer(); +} + +try { + $mail->IsMail(); // telling the class to use SMTP + $mail->SetFrom('you@yourdomain.com', 'Your Name'); + $mail->AddAddress('another@yourdomain.com', 'John Doe'); + $mail->Subject = 'PHPMailer Lite Test Subject via Mail()'; + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically + $mail->MsgHTML(file_get_contents('contents.html')); + $mail->AddAttachment('images/phpmailer.gif'); // attachment + $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment + $mail->action_function = 'callbackAction'; + $mail->Send(); + echo "Message Sent OK

    \n"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} + +function cleanEmails($str,$type) { + if ($type == 'cc') { + $addy['Email'] = $str[0]; + $addy['Name'] = $str[1]; + return $addy; + } + if (!strstr($str, ' <')) { + $addy['Name'] = ''; + $addy['Email'] = $addy; + return $addy; + } + $addyArr = explode(' <', $str); + if (substr($addyArr[1],-1) == '>') { + $addyArr[1] = substr($addyArr[1],0,-1); + } + $addy['Name'] = $addyArr[0]; + $addy['Email'] = $addyArr[1]; + $addy['Email'] = str_replace('@', '@', $addy['Email']); + return $addy; +} + +?> + + diff --git a/libraries/external/PHPMailer_v5.1/test/testemail.php b/libraries/external/PHPMailer_v5.1/test/testemail.php new file mode 100644 index 00000000..d96e2001 --- /dev/null +++ b/libraries/external/PHPMailer_v5.1/test/testemail.php @@ -0,0 +1,48 @@ +IsSMTP(); // tell the class to use SMTP + $mail->SMTPAuth = true; // enable SMTP authentication + $mail->Port = 25; // set the SMTP server port + $mail->Host = "mail.yourdomain.com"; // SMTP server + $mail->Username = "name@domain.com"; // SMTP server username + $mail->Password = "password"; // SMTP server password + + $mail->IsSendmail(); // tell the class to use Sendmail + + $mail->AddReplyTo("name@domain.com","First Last"); + + $mail->From = "name@domain.com"; + $mail->FromName = "First Last"; + + $to = "someone@example...com"; + + $mail->AddAddress($to); + + $mail->Subject = "First PHPMailer Message"; + + $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + $mail->WordWrap = 80; // set word wrap + + $mail->MsgHTML($body); + + $mail->IsHTML(true); // send as HTML + + $mail->Send(); + echo 'Message has been sent.'; +} catch (phpmailerException $e) { + echo $e->errorMessage(); +} +?> \ No newline at end of file diff --git a/libraries/external/RedBean/Adapter.php b/libraries/external/RedBean/Adapter.php new file mode 100644 index 00000000..9540d20d --- /dev/null +++ b/libraries/external/RedBean/Adapter.php @@ -0,0 +1,144 @@ +db = $database; + } + + /** + * Returns the latest SQL Statement. + * @return unknown_type + */ + public function getSQL() { + return $this->sql; + } + + /** + * Escapes a string for use in a Query. + * @param $sqlvalue + * @return unknown_type + */ + public function escape( $sqlvalue ) { + return $this->db->Escape($sqlvalue); + } + + /** + * Executes SQL code; any query without + * returning a resultset. + * @param $sql + * @return unknown_type + */ + public function exec( $sql , $aValues=array(), $noevent=false) { + if (!$noevent) { + $this->sql = $sql; + $this->signal("sql_exec", $this); + } + return $this->db->Execute( $sql, $aValues ); + } + + /** + * Multi array SQL fetch. Fetches a multi dimensional array. + * @param $sql + * @return unknown_type + */ + public function get( $sql, $aValues = array() ) { + $this->sql = $sql; + $this->signal("sql_exec", $this); + return $this->db->GetAll( $sql,$aValues ); + } + + /** + * SQL row fetch. Fetches a single row. + * @param $sql + * @return unknown_type + */ + public function getRow( $sql, $aValues = array() ) { + + $this->sql = $sql; + $this->signal("sql_exec", $this); + return $this->db->GetRow( $sql,$aValues ); + } + + /** + * SQL column fetch. Fetches one column of a table. + * @param $sql + * @return unknown_type + */ + public function getCol( $sql, $aValues = array() ) { + $this->sql = $sql; + $this->signal("sql_exec", $this); + return $this->db->GetCol( $sql,$aValues ); + } + + + /** + * Executes an SQL Query and fetches the first two columns only. + * Then this function builds an associative array using the first + * column for the keys and the second result column for the + * values. For instance: SELECT id, name FROM... will produce + * an array like: id => name. + * @param string $sql + * @param array $aValues + * @return array $resultsAsAssocAray + */ + public function getAssoc( $sql, $aValues = array() ) { + $this->sql = $sql; + $this->signal("sql_exec", $this); + $rows = $this->db->GetAll( $sql, $aValues ); + $assoc = array(); + if ($rows) { + foreach($rows as $row) { + + if (count($row)>0) { + $key = array_shift($row); + } + + if (count($row)>0) { + $value = array_shift($row); + } + else { + $value = $key; + } + + $assoc[ $key ] = $value; + } + } + return $assoc; + } + + + /** + * Retrieves a single cell + * @param $sql + * @return unknown_type + */ + public function getCell( $sql, $aValues = array() ) { + + $this->sql = $sql; + $this->signal("sql_exec", $this); + $arr = $this->db->getCol( $sql, $aValues ); + if ($arr && is_array($arr)) return ($arr[0]); else return false; + } + + /** + * Returns latest insert id, most recently inserted id. + * @return mixed $id + */ + public function getInsertID() { + return $this->db->getInsertID(); + } + + /** + * Returns number of affected rows. + * @return unknown_type + */ + public function getAffectedRows() { + return $this->db->Affected_Rows(); + } + + /** + * Unwrap the original database object. + * @return $database + */ + public function getDatabase() { + return $this->db; + } + + /** + * Return latest error message. + * @return string $message + */ + public function getErrorMsg() { + return $this->db->Errormsg(); + } + + /** + * Transactions. + * Part of the transaction management infrastructure of RedBean. + * Starts a transaction. + */ + public function startTransaction() { + return $this->db->StartTrans(); + } + + /** + * Transactions. + * Part of the transaction management infrastructure of RedBean. + * Commits a transaction. + */ + public function commit() { + return $this->db->CommitTrans(); + } + + /** + * Transactions. + * Part of the transaction management infrastructure of RedBean. + * Rolls back transaction. + */ + public function rollback() { + return $this->db->FailTrans(); + } + +} diff --git a/libraries/external/RedBean/AssociationManager.php b/libraries/external/RedBean/AssociationManager.php new file mode 100644 index 00000000..e3904646 --- /dev/null +++ b/libraries/external/RedBean/AssociationManager.php @@ -0,0 +1,205 @@ + "5" + ); + + /** + * @var RedBean_OODB + */ + private $oodb; + + /** + * @var RedBean_Adapter_DBAdapter + */ + private $adapter; + + /** + * @var RedBean_QueryWriter + */ + private $writer; + + + /** + * Constructor + * @param RedBean_ToolBox $tools + */ + public function __construct( RedBean_ToolBox $tools ) { + $this->scanToolBox( $tools ); + $this->oodb = $tools->getRedBean(); + $this->adapter = $tools->getDatabaseAdapter(); + $this->writer = $tools->getWriter(); + } + /** + * Creates a table name based on a types array. + * @param array $types + * @return string $table + */ + public function getTable( $types ) { + sort($types); + return implode("_", $types); + } + /** + * Associates two beans with eachother. + * @param RedBean_OODBBean $bean1 + * @param RedBean_OODBBean $bean2 + */ + public function associate(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2) { + $table = $this->getTable( array($bean1->getMeta("type") , $bean2->getMeta("type")) ); + $idfield1 = $this->writer->getIDField($bean1->getMeta("type")); + $idfield2 = $this->writer->getIDField($bean2->getMeta("type")); + $bean = $this->oodb->dispense($table); + $property1 = $bean1->getMeta("type") . "_id"; + $property2 = $bean2->getMeta("type") . "_id"; + if ($property1==$property2) $property2 = $bean2->getMeta("type")."2_id"; + $bean->setMeta( "buildcommand.unique" , array( array( $property1, $property2 ))); + $this->oodb->store($bean1); + $this->oodb->store($bean2); + $bean->$property1 = $bean1->$idfield1; + $bean->$property2 = $bean2->$idfield2; + try { + return $this->oodb->store( $bean ); + } + catch(RedBean_Exception_SQL $e) { + //If this is a SQLSTATE[23000]: Integrity constraint violation + //Then just ignore the insert + if ((int)$e->getSQLState()!==23000) { + throw $e; + } + } + } + + /** + * Gets related beans of type $type for bean $bean + * @param RedBean_OODBBean $bean + * @param string $type + * @return array $ids + */ + public function related( RedBean_OODBBean $bean, $type, $getLinks=false ) { + $table = $this->getTable( array($bean->getMeta("type") , $type) ); + $idfield = $this->writer->getIDField($bean->getMeta("type")); + if ($type==$bean->getMeta("type")) {// echo "CROSS"; + $type .= "2"; + $cross = 1; + } + else $cross=0; + if (!$getLinks) $targetproperty = $type."_id"; else $targetproperty="id"; + + $property = $bean->getMeta("type")."_id"; + try { + if ($cross) { + $sqlFetchKeys = $this->writer->selectByCrit( + $targetproperty, + $table, + $property, + $bean->$idfield, + true + ); + } + else { + $sqlFetchKeys = $this->writer->selectByCrit( + $targetproperty, + $table, + $property, + $bean->$idfield + ); + } + return ( $sqlFetchKeys ); + }catch(RedBean_Exception_SQL $e ){ + if ($e->getSQLState()!="42S02" && $e->getSQLState()!="42S22") throw $e; + return array(); + } + } + + /** + * Breaks the association between two beans + * @param RedBean_OODBBean $bean1 + * @param RedBean_OODBBean $bean2 + */ + public function unassociate(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2) { + $this->oodb->store($bean1); + $this->oodb->store($bean2); + $table = $this->getTable( array($bean1->getMeta("type") , $bean2->getMeta("type")) ); + $idfield1 = $this->writer->getIDField($bean1->getMeta("type")); + $idfield2 = $this->writer->getIDField($bean2->getMeta("type")); + $type = $bean1->getMeta("type"); + if ($type==$bean2->getMeta("type")) { //echo "CROSS"; + $type .= "2"; + $cross = 1; + } + else $cross = 0; + $property1 = $type."_id"; + $property2 = $bean2->getMeta("type")."_id"; + $value1 = (int) $bean1->$idfield1; + $value2 = (int) $bean2->$idfield2; + try { + $this->writer->deleteByCrit($table,array($property1=>$value1,$property2=>$value2)); + if ($cross) { + $this->writer->deleteByCrit($table,array($property2=>$value1,$property1=>$value2)); + } + }catch(RedBean_Exception_SQL $e ){ + if ($e->getSQLState()!="42S02" && $e->getSQLState()!="42S22") throw $e; + } + } + /** + * Removes all relations for a bean + * @param RedBean_OODBBean $bean + * @param string $type + */ + public function clearRelations(RedBean_OODBBean $bean, $type) { + $this->oodb->store($bean); + $table = $this->getTable( array($bean->getMeta("type") , $type) ); + $idfield = $this->writer->getIDField($bean->getMeta("type")); + if ($type==$bean->getMeta("type")) { + $property2 = $type."2_id"; + $cross = 1; + } + else $cross = 0; + $property = $bean->getMeta("type")."_id"; + try { + $this->writer->deleteByCrit($table,array($property=>$bean->$idfield)); + if ($cross) { + $this->writer->deleteByCrit($table,array($property2=>$bean->$idfield)); + } + }catch(RedBean_Exception_SQL $e ){ + if ($e->getSQLState()!="42S02" && $e->getSQLState()!="42S22") throw $e; + } + } + /** + * Creates a 1 to Many Association + * If the association fails it throws an exception. + * @throws RedBean_Exception_SQL $failedToEnforce1toN + * @param RedBean_OODBBean $bean1 + * @param RedBean_OODBBean $bean2 + * @return RedBean_AssociationManager $chainable + */ + public function set1toNAssoc(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2) { + $type = $bean1->getMeta("type"); + $this->clearRelations($bean2, $type); + $this->associate($bean1, $bean2); + if (count( $this->related($bean2, $type) )===1) { + return $this; + } + else { + throw new RedBean_Exception_SQL("Failed to enforce 1toN Relation for $type "); + } + } + +} \ No newline at end of file diff --git a/libraries/external/RedBean/CompatManager.php b/libraries/external/RedBean/CompatManager.php new file mode 100644 index 00000000..acaf96e0 --- /dev/null +++ b/libraries/external/RedBean/CompatManager.php @@ -0,0 +1,121 @@ +getDatabaseAdapter()->getDatabase()->getDatabaseType())); + + //obtain version number + $version = $toolbox->getDatabaseAdapter()->getDatabase()->getDatabaseVersion(); + + if (!is_numeric($version)) { + $version = 999; //No version number? Ignore! + } + + //compare database + if (isset($this->supportedSystems[$brand]) + && ((float)$this->supportedSystems[$brand] <= (float) $version) + ) { + return true; + } + else { + if (!self::$ignoreVersion) { + $this->messageUnsupported = str_replace("##YOU##",$brand." v".$version,$this->messageUnsupported); + $list = array(); + foreach($this->supportedSystems as $supported=>$version) { + $list[] = " ".$supported . " v".$version."+"; + } + $this->messageUnsupported = str_replace("##DBS##",implode(",",$list),$this->messageUnsupported); + throw new RedBean_Exception_UnsupportedDatabase($this->messageUnsupported); + } + else { + return false; + } + } + + + } + + /** + * Static Variant + * Scans the toolbox to determine whether the database adapter + * is compatible with the current class, plugin or module. + * @throws RedBean_Exception_UnsupportedDatabase $exception + * @param RedBean_ToolBox $toolbox + * @param array $listOfSystemsSupported + * @return bool $compatible + */ + public static function scanDirect( RedBean_ToolBox $toolbox, $list = array() ) { + $compat = new RedBean_CompatManager(); + $compat->supportedSystems = $list; + return $compat->scanToolBox($toolbox); + } + +} \ No newline at end of file diff --git a/libraries/external/RedBean/DomainObject.php b/libraries/external/RedBean/DomainObject.php new file mode 100644 index 00000000..1cd5cd2e --- /dev/null +++ b/libraries/external/RedBean/DomainObject.php @@ -0,0 +1,210 @@ +0) { + + //Fetch us a toolbox. + $this->tools = RedBean_Setup::getToolBox(); + $this->redbean = $this->tools->getRedBean(); + + //Here the bean type is checked properly. + $this->bean = $this->redbean->dispense( strtolower( $beanTypeName ) ); + + //Create some handy modules so you dont have to do the wiring yourself. + $this->associationManager = new RedBean_AssociationManager($this->tools); + $this->treeManager = new RedBean_TreeManager($this->tools); + } + else { + throw new Exception("Invalid Domain Object TypeName"); + } + } + /** + * Associates the bean inside with another OODBBean + * @param RedBean_DomainObject $other + */ + protected function associate(RedBean_DomainObject $other) { + $this->associationManager->associate($this->bean, $other->bean); + } + /** + * Breaks the association between this OODBBean an the one belonging + * to the other model. + * @param RedBean_DomainObject $other + */ + protected function unassociate(RedBean_DomainObject $other) { + $this->associationManager->unassociate($this->bean, $other->bean); + } + /** + * Fetches related domain objects. + * @param string $className + * @param mixed $constructorArg + * @return mixed $models + */ + protected function related( $className, $constructorArg = null ) { + $models = array(); + $model = new $className; + $keys = $this->associationManager->related($this->bean, $model->getBeanType()); + foreach($keys as $key) { + $modelItem = new $className($constructorArg); + $modelItem->find( (int) $key ); + $models[$key] = $modelItem; + } + return $models; + } + /** + * Returns the type of the bean. + * @return string $type + */ + protected function getBeanType() { + return $this->bean->getMeta("type"); + } + /** + * + * @param RedBean_DomainObject $other + */ + protected function set1toNAssoc(RedBean_DomainObject $other) { + $this->associationManager->set1toNAssoc($this->bean, $other->bean); + } + /** + * Clears associations + */ + protected function clearRelations() { + $this->associationManager->clearRelations($this->bean); + } + /** + * + * @param RedBean_DomainObject $other + */ + protected function attach(RedBean_DomainObject $other) { + $this->treeManager->attach($this->bean, $other->bean); + } + /** + * Loads the Bean internally + * @param integer $id + */ + public function find( $id ) { + $this->bean = $this->redbean->load( $this->bean->getMeta("type"), (int) $id ); + } + /** + * Returns a collection of Domain Objects. + * @param string $type + * @param string $query + * @return array $collection + */ + public static function getDomainObjects( $type, $query="1", $values=array() ) { + //Fetch us a toolbox. + $tools = RedBean_Setup::getToolBox(); + $redbean = $tools->getRedBean(); + + $domainObject = new $type; + $typeName = $domainObject->bean->getMeta("type"); + $collection = array(); + $finder = new \RedBean_Plugin_Finder(); + $beans = $finder->where($typeName, $query, $values); + foreach($beans as $bean) { + $domainObject = new $type; + $domainObject->bean = $bean; + $collection[] = $domainObject; + } + return $collection; + } + /** + * Saves the current domain object. + * The function saves the inner bean to the database. + */ + public function save() { + $this->redbean->store( $this->bean ); + } + /** + * Deletes the inner bean from the database. + */ + public function delete() { + $this->redbean->trash( $this->bean ); + } + /** + * Returns the ID of the Model. + */ + public function getID() { + $idField = $this->tools->getWriter()->getIDField( $this->bean->getMeta("type") ); + return $this->bean->$idField; + } + +} diff --git a/libraries/external/RedBean/Driver.php b/libraries/external/RedBean/Driver.php new file mode 100644 index 00000000..4d19149a --- /dev/null +++ b/libraries/external/RedBean/Driver.php @@ -0,0 +1,130 @@ +pdo = new PDO( + $dsn, + $user, + $pass, + + array(1002 => 'SET NAMES utf8', + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC) + ); + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#GetAll() + */ + public function GetAll( $sql, $aValues=array() ) + { + + $this->exc = 0; + if ($this->debug) { + echo "
    " . $sql.print_r($aValues,1); + } + + try { + $s = $this->pdo->prepare($sql); + + $s->execute($aValues); + $this->rs = $s->fetchAll(); + $rows = $this->rs; + }catch(PDOException $e) { + //Unfortunately the code field is supposed to be int by default (php) + //So we need a property to convey the SQL State code. + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + $x = new RedBean_Exception_SQL( $e->getMessage(), 0); + } + else { + $x = new RedBean_Exception_SQL( $e->getMessage(), 0, $e ); + } + $x->setSQLState( $e->getCode() ); + throw $x; + } + + if(!$rows) { + $rows = array(); + } + + if ($this->debug) { + if (count($rows) > 0) { + echo "
    resultset: " . count($rows) . " rows"; + } + } + return $rows; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#GetCol() + */ + public function GetCol($sql, $aValues=array()) + { + $this->exc = 0; + $rows = $this->GetAll($sql,$aValues); + $cols = array(); + + if ($rows && is_array($rows) && count($rows)>0){ + foreach ($rows as $row) + { + $cols[] = array_shift($row); + } + } + + return $cols; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#GetCell() + */ + public function GetCell($sql, $aValues=array()) + { + $this->exc = 0; + $arr = $this->GetAll($sql,$aValues); + $row1 = array_shift($arr); + $col1 = array_shift($row1); + return $col1; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#GetRow() + */ + public function GetRow($sql, $aValues=array()) + { + $this->exc = 0; + $arr = $this->GetAll($sql, $aValues); + return array_shift($arr); + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#ErrorNo() + */ + public function ErrorNo() + { + if (!$this->exc) return 0; + $infos = $this->pdo->errorInfo(); + return $infos[1]; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#Errormsg() + */ + public function Errormsg() + { + if (!$this->exc) return ""; + $infos = $this->pdo->errorInfo(); + return $infos[2]; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#Execute() + */ + public function Execute( $sql, $aValues=array() ) + { + $this->exc = 0; + if ($this->debug) + { + echo "
    " . $sql.print_r($aValues,1); + } + try { + $s = $this->pdo->prepare($sql); + $s->execute($aValues); + $this->affected_rows=$s->rowCount(); + return $this->affected_rows; + } + catch(PDOException $e) { + //Unfortunately the code field is supposed to be int by default (php) + //So we need a property to convey the SQL State code. + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + $x = new RedBean_Exception_SQL( $e->getMessage(), 0); + } + else { + $x = new RedBean_Exception_SQL( $e->getMessage(), 0, $e ); + } + + $x->setSQLState( $e->getCode() ); + throw $x; + + } + // + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#Escape() + */ + public function Escape( $str ) + { + return substr(substr($this->pdo->quote($str), 1), 0, -1); + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#GetInsertID() + */ + public function GetInsertID() + { + return (int) $this->pdo->lastInsertId(); + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#Affected_Rows() + */ + public function Affected_Rows() + { + return (int) $this->affected_rows; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#setDebugMode() + */ + public function setDebugMode( $tf ) + { + $this->debug = (bool)$tf; + } + + /** + * (non-PHPdoc) + * @see RedBean/RedBean_Driver#GetRaw() + */ + public function GetRaw() + { + return $this->rs; + } + + + /** + * Starts a transaction. + */ + public function StartTrans() { + $this->pdo->beginTransaction(); + } + + /** + * Commits a transaction. + */ + public function CommitTrans() { + $this->pdo->commit(); + } + + + /** + * Rolls back a transaction. + */ + public function FailTrans() { + $this->pdo->rollback(); + } + + /** + * Returns the name of the database type/brand: i.e. mysql, db2 etc. + * @return string $typeName + */ + public function getDatabaseType() { + return $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME); + } + + /** + * Returns the version number of the database. + * @return mixed $version + */ + public function getDatabaseVersion() { + return $this->pdo->getAttribute(PDO::ATTR_CLIENT_VERSION); + } + +} diff --git a/libraries/external/RedBean/Exception.php b/libraries/external/RedBean/Exception.php new file mode 100644 index 00000000..b06672b8 --- /dev/null +++ b/libraries/external/RedBean/Exception.php @@ -0,0 +1,15 @@ +sqlState; + } + + /** + * @todo parse state to verify valid ANSI92! + * Stores ANSI-92 compliant SQL state. + * @param string $sqlState + */ + public function setSQLState( $sqlState ) { + $this->sqlState = $sqlState; + } + + + /** + * To String prints both code and SQL state. + * @return string + */ + public function __toString() { + return "[".$this->getSQLState()."] - ".$this->getMessage(); + } +} \ No newline at end of file diff --git a/libraries/external/RedBean/Exception/Security.php b/libraries/external/RedBean/Exception/Security.php new file mode 100644 index 00000000..d50ee28a --- /dev/null +++ b/libraries/external/RedBean/Exception/Security.php @@ -0,0 +1,15 @@ +writer = $writer; + } + + /** + * Toggles fluid or frozen mode. In fluid mode the database + * structure is adjusted to accomodate your objects. In frozen mode + * this is not the case. + * @param boolean $trueFalse + */ + public function freeze( $tf ) { + $this->isFrozen = (bool) $tf; + } + + + /** + * Returns the current mode of operation of RedBean. + * In fluid mode the database + * structure is adjusted to accomodate your objects. + * In frozen mode + * this is not the case. + * @return + */ + public function isFrozen() { + return (bool) $this->isFrozen; + } + + /** + * Dispenses a new bean (a RedBean_OODBBean Bean Object) + * of the specified type. Always + * use this function to get an empty bean object. Never + * instantiate a RedBean_OODBBean yourself because it needs + * to be configured before you can use it with RedBean. This + * function applies the appropriate initialization / + * configuration for you. + * @param string $type + * @return RedBean_OODBBean $bean + */ + public function dispense($type ) { + + $bean = new RedBean_OODBBean(); + $bean->setMeta("type", $type ); + $idfield = $this->writer->getIDField($bean->getMeta("type")); + $bean->$idfield = 0; + $this->signal( "dispense", $bean ); + $this->check( $bean ); + return $bean; + } + + /** + * Checks whether a RedBean_OODBBean bean is valid. + * If the type is not valid or the ID is not valid it will + * throw an exception: RedBean_Exception_Security. + * @throws RedBean_Exception_Security $exception + * @param RedBean_OODBBean $bean + */ + public function check( RedBean_OODBBean $bean ) { + $idfield = $this->writer->getIDField($bean->getMeta("type")); + //Is all meta information present? + if (!isset($bean->$idfield) || !($bean->getMeta("type"))) { + throw new RedBean_Exception_Security("Bean has incomplete Meta Information"); + } + //Pattern of allowed characters + $pattern = '/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]/'; + //Does the type contain invalid characters? + if (preg_match($pattern,$bean->getMeta("type"))) { + throw new RedBean_Exception_Security("Bean Type is invalid"); + } + //Are the properties and values valid? + foreach($bean as $prop=>$value) { + if ( + is_array($value) || + is_object($value) || + strlen($prop)<1 || + preg_match($pattern,$prop) + ) { + throw new RedBean_Exception_Security("Invalid Bean: property $prop "); + } + } + } + + + /** + * Checks whether the specified table already exists in the database. + * Not part of the Object Database interface! + * @param string $table + * @return boolean $exists + */ + public function tableExists($table) { + //does this table exist? + $tables = $this->writer->getTables(); + return in_array($table, $tables); + } + + /** + * Stores a bean in the database. This function takes a + * RedBean_OODBBean Bean Object $bean and stores it + * in the database. If the database schema is not compatible + * with this bean and RedBean runs in fluid mode the schema + * will be altered to store the bean correctly. + * If the database schema is not compatible with this bean and + * RedBean runs in frozen mode it will throw an exception. + * This function returns the primary key ID of the inserted + * bean. + * @throws RedBean_Exception_Security $exception + * @param RedBean_OODBBean $bean + * @return integer $newid + */ + public function store( RedBean_OODBBean $bean ) { + $this->signal( "update", $bean ); + $this->check($bean); + //what table does it want + $table = $bean->getMeta("type"); + $idfield = $this->writer->getIDField($table); + //Does table exist? If not, create + if (!$this->isFrozen && !$this->tableExists($table)) { + $this->writer->createTable( $table ); + } + $columns = $this->writer->getColumns($table) ; + //does the table fit? + $insertvalues = array(); + $insertcolumns = array(); + $updatevalues = array(); + foreach( $bean as $p=>$v) { + if ($p!=$idfield) { + if (!$this->isFrozen) { + //What kind of property are we dealing with? + $typeno = $this->writer->scanType($v); + //Is this property represented in the table? + if (isset($columns[$p])) { + //yes it is, does it still fit? + $sqlt = $this->writer->code($columns[$p]); + if ($typeno > $sqlt) { + //no, we have to widen the database column type + $this->writer->widenColumn( $table, $p, $typeno ); + } + } + else { + //no it is not + $this->writer->addColumn($table, $p, $typeno); + } + } + //Okay, now we are sure that the property value will fit + $insertvalues[] = $v; + $insertcolumns[] = $p; + $updatevalues[] = array( "property"=>$p, "value"=>$v ); + } + } + if (!$this->isFrozen && ($uniques = $bean->getMeta("buildcommand.unique"))) { + foreach($uniques as $unique) { + $this->writer->addUniqueIndex( $table, $unique ); + } + } + if ($bean->$idfield) { + if (count($updatevalues)>0) { + $this->writer->updateRecord( $table, $updatevalues, $bean->$idfield ); + } + return (int) $bean->$idfield; + } + else { + $id = $this->writer->insertRecord( $table, $insertcolumns, array($insertvalues) ); + $bean->$idfield = $id; + return (int) $id; + } + } + + /** + * Loads a bean from the object database. + * It searches for a RedBean_OODBBean Bean Object in the + * database. It does not matter how this bean has been stored. + * RedBean uses the primary key ID $id and the string $type + * to find the bean. The $type specifies what kind of bean your + * are looking for; this is the same type as used with the + * dispense() function. If RedBean finds the bean it will return + * the RedBean_OODB Bean object; if it cannot find the bean + * RedBean will return a new bean of type $type and with + * primary key ID 0. In the latter case it acts basically the + * same as dispense(). + * If the bean cannot be found in the database a new bean of + * the specified type will be generated and returned. + * @param string $type + * @param integer $id + * @return RedBean_OODBBean $bean + */ + public function load($type, $id) { + $id = intval( $id ); + if ($id < 0) throw new RedBean_Exception_Security("Id less than zero not allowed"); + $bean = $this->dispense( $type ); + if ($this->stash && isset($this->stash[$id])) { + $row = $this->stash[$id]; + } + else { + try { $rows = $this->writer->selectRecord($type,array($id)); }catch(RedBean_Exception_SQL $e ){ + if ($e->getSQLState()=="42S02" || $e->getSQLState()=="42S22") { + $rows = 0; + if ($this->isFrozen) throw $e; //only throw if frozen; + } + else throw $e; + } + if (!$rows) return $this->dispense($type); + $row = array_pop($rows); + } + foreach($row as $p=>$v) { + //populate the bean with the database row + $bean->$p = $v; + } + $this->signal( "open", $bean ); + return $bean; + } + + /** + * Removes a bean from the database. + * This function will remove the specified RedBean_OODBBean + * Bean Object from the database. + * @throws RedBean_Exception_Security $exception + * @param RedBean_OODBBean $bean + */ + public function trash( RedBean_OODBBean $bean ) { + $idfield = $this->writer->getIDField($bean->getMeta("type")); + $this->signal( "delete", $bean ); + $this->check( $bean ); + try { + $this->writer->deleteRecord( $bean->getMeta("type"), $bean->$idfield ); + }catch(RedBean_Exception_SQL $e ){ + if ($e->getSQLState()!="42S02" && $e->getSQLState()!="42S22") throw $e; + } + } + + /** + * Loads and returns a series of beans of type $type. + * The beans are loaded all at once. + * The beans are retrieved using their primary key IDs + * specified in the second argument. + * @throws RedBean_Exception_Security $exception + * @param string $type + * @param array $ids + * @return array $beans + */ + public function batch( $type, $ids ) { + if (!$ids) return array(); + $collection = array(); + try { + $rows = $this->writer->selectRecord($type,$ids); + }catch(RedBean_Exception_SQL $e ){ + if ($e->getSQLState()!="42S02" && $e->getSQLState()!="42S22") throw $e; + $rows = false; + } + $this->stash = array(); + if (!$rows) return array(); + foreach($rows as $row) { + $this->stash[$row[$this->writer->getIDField($type)]] = $row; + } + foreach($ids as $id) { + $collection[ $id ] = $this->load( $type, $id ); + } + $this->stash = NULL; + return $collection; + } + + /** + * This is a convenience method; it converts database rows + * (arrays) into beans. + * @param string $type + * @param array $rows + * @return array $collectionOfBeans + */ + public function convertToBeans($type, $rows) { + $collection = array(); + $this->stash = array(); + foreach($rows as $row) { + $id = $row[$this->writer->getIDField($type)]; + $this->stash[$id] = $row; + $collection[ $id ] = $this->load( $type, $id ); + + } + $this->stash = NULL; + return $collection; + } + +} + + diff --git a/libraries/external/RedBean/OODBBean.php b/libraries/external/RedBean/OODBBean.php new file mode 100644 index 00000000..590229cf --- /dev/null +++ b/libraries/external/RedBean/OODBBean.php @@ -0,0 +1,155 @@ +$v) { + if ($k != "__info") { + if (!$selection || ($selection && in_array($k,$selection))) { + $this->$k = $v; + } + } + } + return $this; + } + + /** + * Exports the bean as an array. + * This function exports the contents of a bean to an array and returns + * the resulting array. If $meta equals boolean TRUE, then the array will + * also contain the __info section containing the meta data inside the + * RedBean_OODBBean Bean object. + * @param boolean $meta + * @return array $arr + */ + public function export($meta = false) { + $arr = array(); + foreach($this as $p=>$v) { + if ($p != "__info" || $meta) { + $arr[ $p ] = $v; + } + } + return $arr; + } + + + /** + * Magic Getter. Gets the value for a specific property in the bean. + * If the property does not exist this getter will make sure no error + * occurs. This is because RedBean allows you to query (probe) for + * properties. If the property can not be found this method will + * return NULL instead. + * @param string $property + * @return mixed $value + */ + public function __get( $property ) { + if (!isset($this->$property) || $this->$property=="") { + return NULL; + } + return $this->$property; + } + + + /** + * Returns the value of a meta property. A meta property + * contains extra information about the bean object that will not + * get stored in the database. Meta information is used to instruct + * RedBean as well as other systems how to deal with the bean. + * For instance: $bean->setMeta("buildcommand.unique.0", array( + * "column1", "column2", "column3") ); + * Will add a UNIQUE constaint for the bean on columns: column1, column2 and + * column 3. + * To access a Meta property we use a dot separated notation. + * If the property cannot be found this getter will return NULL instead. + * @param string $path + * @param mixed $default + * @return mixed $value + */ + public function getMeta( $path, $default = NULL) { + $ref = $this->__info; + $parts = explode(".", $path); + foreach($parts as $part) { + if (isset($ref[$part])) { + $ref = $ref[$part]; + } + else { + return $default; + } + } + return $ref; + } + + /** + * Stores a value in the specified Meta information property. $value contains + * the value you want to store in the Meta section of the bean and $path + * specifies the dot separated path to the property. For instance "my.meta.property". + * If "my" and "meta" do not exist they will be created automatically. + * @param string $path + * @param mixed $value + */ + public function setMeta( $path, $value ) { + $ref = &$this->__info; + $parts = explode(".", $path); + $lastpart = array_pop( $parts ); + foreach($parts as $part) { + if (!isset($ref[$part])) { + $ref[$part] = array(); + } + $ref = &$ref[$part]; + } + $ref[$lastpart] = $value; + } + + /** + * Copies the meta information of the specified bean + * This is a convenience method to enable you to + * exchange meta information easily. + * @param RedBean_OODBBean $bean + * @return RedBean_OODBBean + */ + public function copyMetaFrom( RedBean_OODBBean $bean ) { + $this->__info = $bean->__info; + return $this; + } + + //@todo copy/clone a bean + + +} + diff --git a/libraries/external/RedBean/ObjectDatabase.php b/libraries/external/RedBean/ObjectDatabase.php new file mode 100644 index 00000000..73ea429d --- /dev/null +++ b/libraries/external/RedBean/ObjectDatabase.php @@ -0,0 +1,69 @@ +observers[ $eventname ])) { + $this->observers[ $eventname ] = array(); + } + + $this->observers[ $eventname ][] = $observer; + } + + /** + * Sends an event (signal) to the registered listeners + * @param $eventname + * @return unknown_type + */ + public function signal( $eventname, $info ) { + + if (!isset($this->observers[ $eventname ])) { + $this->observers[ $eventname ] = array(); + } + + foreach($this->observers[$eventname] as $observer) { + $observer->onEvent( $eventname, $info ); + } + + } + + +} \ No newline at end of file diff --git a/libraries/external/RedBean/Observer.php b/libraries/external/RedBean/Observer.php new file mode 100644 index 00000000..28cc4f0b --- /dev/null +++ b/libraries/external/RedBean/Observer.php @@ -0,0 +1,22 @@ +oodb = $oodb; + $this->writer = $toolBox->getWriter(); + } + + /** + * Adds event listener. + * @param $event + * @param RedBean_Observer $o + */ + public function addEventListener($event, RedBean_Observer $o) { + $this->oodb->addEventListener($event, $o); + } + + + /** + * Generates a key based on the ID and TYPE of a bean to + * identify the bean in the cache. + * @param RedBean_OODBBean $bean + * @return string $key + */ + private function generateKey( RedBean_OODBBean $bean ) { + $type=$bean->getMeta("type"); + $idfield = $this->writer->getIDField($type); + $id = $bean->$idfield; + return sha1($type."-".$id); + } + + + /** + * Puts a bean in the cache and stores a copy of the bean in the + * cache archive. + * @param RedBean_OODBBean $bean + */ + private function putInCache( RedBean_OODBBean $bean ) { + $key = $this->generateKey($bean); + $this->cache[$key]=$bean; + $copy = clone $bean; + $copy->copyMetaFrom($bean); + $this->originals[ $key ] = $copy; + return $this; + } + + + /** + * Fetches a bean from the cache or returns NULL. + * @param RedBean_OODBBean $bean + * @return RedBean_OODBBean $bean + */ + private function fetchFromCache( RedBean_OODBBean $bean ) { + $key = $this->generateKey($bean); + if (isset($this->cache[$key])) { + return $this->cache[$key]; + } + else { + return NULL; + } + } + + + /** + * Fetches a bean from the cache or returns NULL. + * This function takes a TYPE and ID. + * @param string $type + * @param integer $id + * @return RedBean_OODBBean $bean + */ + private function fetchFromCacheByTypeID( $type, $id ) { + $bean = $this->oodb->dispense($type); + $idfield = $this->writer->getIDField($type); + $bean->$idfield = $id; + return $this->fetchFromCache($bean); + } + + + /** + * Fetches the original bean as it was stored in the cache + * archive or NULL. + * @param RedBean_OODBBean $bean + * @return RedBean_OODBBean $bean + */ + private function fetchOriginal(RedBean_OODBBean $bean) { + $key = $this->generateKey($bean); + if (isset($this->originals[$key])) { + return $this->originals[$key]; + } + else { + return NULL; + } + } + + /** + * Removes a bean from the cache and the archive. + * @param RedBean_OODBBean $bean + */ + private function removeFromCache( RedBean_OODBBean $bean ) { + $key = $this->generateKey($bean); + unset($this->cache[$key]); + unset($this->originals[$key]); + return $this; + } + + /** + * Tries to load a bean from cache, if this fails, it asks + * the oodb object to load the bean from the database. + * @param string $type + * @param integer $id + * @return RedBean_OODB $bean + */ + public function load( $type, $id ) { + + $bean = $this->fetchFromCacheByTypeID($type, $id); + if ($bean) { + return $bean; + } + else { + $bean = $this->oodb->load($type, $id); + $this->putInCache($bean); + return $bean; + } + + } + + + /** + * Stores a bean and updates cache. + * @param RedBean_OODBBean $bean + * @return integer $id + */ + public function store( RedBean_OODBBean $bean ) { + + $this->columnCounter = 0; + $type=$bean->getMeta("type"); + $idfield = $this->writer->getIDField($type); + $newbean = $this->oodb->dispense($type); + $newbean->$idfield = $bean->$idfield; + $oldBean = $this->fetchOriginal($bean); + //Is there a cached version? + if ($oldBean) { + //Assume no differences. + $dirty = false; + //Check for differences. + foreach($oldBean as $p=>$v) { + if ($v !== $bean->$p && $p!=$idfield) { + $newbean->$p = $bean->$p; + //echo "ADDING CHANGED PROP: $p $v -> ".$bean->$p; + $this->columnCounter++; //for tests. + //found a difference; mark as tainted. + $dirty=true; + } + } + + //are there any new props? + foreach($bean as $p=>$v){ + if (!isset($oldBean->$p)) { + $dirty=true; + $newbean->$p = $bean->$p; + $this->columnCounter++; + } + } + + //If the bean is dirty; send only differences for update. + if ($dirty) { + $newbean->copyMetaFrom($bean); + $id = $this->oodb->store($newbean); + $bean->copyMetaFrom($newbean); + $this->putInCache($bean); + return $id; + } + else { + return $bean->$idfield; + } + } + else { + $id = $this->oodb->store($bean); + $this->putInCache($bean); + return $id; + } + } + + /** + * Trashes a bean and removes the bean from cache. + * @param RedBean_OODBBean $bean + */ + public function trash( RedBean_OODBBean $bean ) { + $this->removeFromCache($bean); + return $this->oodb->trash($bean); + } + + /** + * Loads a batch of beans all at once. + * This function first inspects the cache; if every element in the batch + * is available in the cache, the function will return the collected beans + * from the cache. If one or more beans cannot be found, the function will + * ask oodb for the beans and update the cache. + * @param string $type + * @param integer $ids + * @return array $beans + */ + public function batch( $type, $ids ) { + $idfield = $this->writer->getIDField($type); + $collect = array(); + foreach($ids as $id) { + $bean = $this->fetchFromCacheByTypeID($type, $id); + if ($bean) $collect[$id] = $bean; + } + if (count($collect) == count($ids)) { + return $collect; + } + else { + $beans = $this->oodb->batch($type, $ids); + foreach($beans as $bean) { + $this->putInCache( $bean ); + } + return $beans; + } + } + + /** + * Dispenses a bean, just like oodb does + * @param string $type + * @return RedBean_OODBBean $bean + */ + public function dispense( $type ){ + return $this->oodb->dispense($type); + } + + /** + * For testing only; returns the number of properties that has + * been updated in the latest store action. + * @return integer $count + */ + public function test_getColCount() { + return $this->columnCounter; + } + +} \ No newline at end of file diff --git a/libraries/external/RedBean/Plugin/ChangeLogger.php b/libraries/external/RedBean/Plugin/ChangeLogger.php new file mode 100644 index 00000000..428c4480 --- /dev/null +++ b/libraries/external/RedBean/Plugin/ChangeLogger.php @@ -0,0 +1,173 @@ + "5" + ); + + + /** + * @var RedBean_Adapter_DBAdapter + */ + private $writer; + + /** + * + * @var RedBean_Adapter + */ + private $adapter; + + + /** + * + * @var array + */ + private $stash = array(); + + /** + * + * @var RedBean_OODB + */ + private $redbean; + + /** + * Constructor, requires a writer + * @param RedBean_QueryWriter $writer + */ + public function __construct(RedBean_ToolBox $toolbox) { + + //Do a compatibility check, using the Compatibility Management System + $this->scanToolBox( $toolbox ); + + $this->writer = $toolbox->getWriter(); + $this->adapter = $toolbox->getDatabaseAdapter(); + $this->redbean = $toolbox->getRedBean(); + if (!$this->redbean->isFrozen()) { + $this->adapter->exec(" + CREATE TABLE IF NOT EXISTS `__log` ( + `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , + `tbl` VARCHAR( 255 ) NOT NULL , + `action` TINYINT( 2 ) NOT NULL , + `itemid` INT( 11 ) NOT NULL + ) ENGINE = MYISAM ; + "); //Must be MyISAM! else you run in trouble if you use transactions! + } + $maxid = $this->adapter->getCell("SELECT MAX(id) FROM __log"); + $this->adapter->exec("DELETE FROM __log WHERE id < $maxid - 200 "); + } + + /** + * Throws an exception if information in the bean has been changed + * by another process or bean. This is actually the same as journaling + * using timestamps however with timestamps you risk race conditions + * when the measurements are not fine-grained enough; with + * auto-incremented primary key ids we dont have this risk. + * @param string $event + * @param RedBean_OODBBean $item + */ + public function onEvent( $event, $item ) { + $id = $item->id; + if (! ((int) $id)) $event="open"; + + + $type = $item->getMeta("type"); + if ($event=="open") { + if (isset($this->stash[$id])) { + $insertid = $this->stash[$id]; + unset($this->stash[$id]); + return $insertid; + } + $insertid = $this->writer->insertRecord("__log",array("action","tbl","itemid"), + array(array(1, $type, $id))); + $item->setMeta("opened",$insertid); + + } + if ($event=="update" || $event=="delete") { + if (($item->getMeta("opened"))) $oldid = $item->getMeta("opened"); else $oldid=0; + $newid = $this->checkChanges($type,$id, $oldid); + $item->setMeta("opened",$newid); + } + } + + + /** + * Facilitates preloading. If you want to load multiple beans at once + * these beans can be locked individually; given N beans this means approx. + * N*3 queries which is quite a lot. This method allows you to pre-lock or pre-open + * multiple entries at once. All beans will get an opened stamp that correspond to + * the first bean opened. This means this approach is conservative; it might + * produce a higher rate of false alarms but it does not compromise + * concurrency security. + * @param string $type + * @param array $ids + */ + public function preLoad( $type, $ids ) { + $this->adapter->exec("INSERT INTO __log (id,action,tbl,itemid) + VALUES(NULL, :action,:tbl,:id)",array(":action"=>1,":tbl"=>"__no_type__",":id"=>0)); //Write a multi opened record + $insertid = $this->adapter->getInsertID(); + $values = array(); + foreach($ids as $id) { //The returned Ids will be stored in a stash buffer + $this->stash[$id]=$insertid; //the onEvent OPEN will empty this stash + $values[] = array(1, $type, $id); //by using up the ids in it. + + } + $this->writer->insertRecord("__log",array("action","tbl","itemid"), $values); //use extend. insert if possible + } + + /** + * For testing only, dont use. + * @return array $stash + */ + public function testingOnly_getStash() { + return $this->stash; + } + + /** + * Gets information about changed records using a type and id and a logid. + * RedBean Locking shields you from race conditions by comparing the latest + * cached insert id with a the highest insert id associated with a write action + * on the same table. If there is any id between these two the record has + * been changed and RedBean will throw an exception. This function checks for changes. + * If changes have occurred it will throw an exception. If no changes have occurred + * it will insert a new change record and return the new change id. + * This method locks the log table exclusively. + * @param string $type + * @param integer $id + * @param integer $logid + * @return integer $newchangeid + */ + public function checkChanges($type, $id, $logid) { + $type = $this->writer->check($type); + $id = (int) $id; + $logid = (int) $logid; + $num = $this->adapter->getCell(" + SELECT count(*) FROM __log WHERE tbl=\"$type\" AND itemid=$id AND action=2 AND id > $logid"); + if ($num) { + throw new RedBean_Exception_FailedAccessBean("Locked, failed to access (type:$type, id:$id)"); + } + $this->adapter->exec("INSERT INTO __log (id,action,tbl,itemid) VALUES(NULL, 2,:tbl,:id)",array(":tbl"=>$type, ":id"=>$id)); + $newid = $this->adapter->getInsertID(); + if ($this->adapter->getCell("select id from __log where tbl=:tbl AND id < $newid and id > $logid and action=2 and itemid=$id ", + array(":tbl"=>$type))){ + throw new RedBean_Exception_FailedAccessBean("Locked, failed to access II (type:$type, id:$id)"); + } + return $newid; + } +} \ No newline at end of file diff --git a/libraries/external/RedBean/Plugin/Constraint.php b/libraries/external/RedBean/Plugin/Constraint.php new file mode 100644 index 00000000..9bb69bbc --- /dev/null +++ b/libraries/external/RedBean/Plugin/Constraint.php @@ -0,0 +1,108 @@ + "5")); + + + //Create an association manager + $association = new RedBean_AssociationManager( $toolbox ); + $writer = $toolbox->getWriter(); + $oodb = $toolbox->getRedBean(); + $adapter = $toolbox->getDatabaseAdapter(); + + //Frozen? Then we may not alter the schema! + if ($oodb->isFrozen()) return false; + + + //$adapter->getDatabase()->setDebugMode(1); + + $table1 = $bean1->getMeta("type"); + $table2 = $bean2->getMeta("type"); + $table = $association->getTable( array( $table1,$table2) ); + $idfield1 = $writer->getIDField($bean1->getMeta("type")); + $idfield2 = $writer->getIDField($bean2->getMeta("type")); + $bean = $oodb->dispense($table); + $property1 = $bean1->getMeta("type") . "_id"; + $property2 = $bean2->getMeta("type") . "_id"; + if ($property1==$property2) $property2 = $bean2->getMeta("type")."2_id"; + + $table = $adapter->escape($table); + $table1 = $adapter->escape($table1); + $table2 = $adapter->escape($table2); + $property1 = $adapter->escape($property1); + $property2 = $adapter->escape($property2); + + //In Cache? Then we dont need to bother + if (isset(self::$fkcache[$table])) return false; + + $db = $adapter->getCell("select database()"); + $fks = $adapter->getCell(" + SELECT count(*) + FROM information_schema.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA ='$db' AND TABLE_NAME ='$table' AND + CONSTRAINT_NAME <>'PRIMARY' AND REFERENCED_TABLE_NAME is not null + "); + + //already foreign keys added in this association table + if ($fks>0) return false; + + //add the table to the cache, so we dont have to fire the fk query all the time. + if (!$dontCache) self::$fkcache[ $table ] = true; + + $columns = $writer->getColumns($table); + + if ($writer->code($columns[$property1])!==RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32) { + $writer->widenColumn($table, $property1, RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32); + } + if ($writer->code($columns[$property2])!==RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32) { + $writer->widenColumn($table, $property2, RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32); + } + + + + $sql = " + ALTER TABLE ".$writer->noKW($table)." + ADD FOREIGN KEY($property1) references $table1(id) ON DELETE CASCADE; + + "; + $adapter->exec( $sql ); + $sql =" + ALTER TABLE ".$writer->noKW($table)." + ADD FOREIGN KEY($property2) references $table2(id) ON DELETE CASCADE + "; + $adapter->exec( $sql ); + return true; + + } + +} diff --git a/libraries/external/RedBean/Plugin/Finder.php b/libraries/external/RedBean/Plugin/Finder.php new file mode 100644 index 00000000..ea121796 --- /dev/null +++ b/libraries/external/RedBean/Plugin/Finder.php @@ -0,0 +1,86 @@ +'%more%')); + * + * Also, note that the default search is always 1. So if you do not + * specify a search parameter this function will just return every + * bean of the given type: + * + * - Finder::where("page"); //returns all pages + * + * + * @param string $type + * @param string $SQL + * @param array $values + * @return array $beans + */ + public static function where( $type, $SQL = " 1 ", $values=array() ) { + + //Sorry, quite draconic filtering + $type = preg_replace("/\W/","", $type); + + //First get hold of the toolbox + $tools = RedBean_Setup::getToolBox(); + + RedBean_CompatManager::scanDirect($tools, array(RedBean_CompatManager::C_SYSTEM_MYSQL => "5")); + + //Now get the two tools we need; RedBean and the Adapter + $redbean = $tools->getRedBean(); + $adapter = $tools->getDatabaseAdapter(); + + //Make a standard ANSI SQL query from the SQL provided + try{ + $SQL = "SELECT * FROM $type WHERE ".$SQL; + + //Fetch the values using the SQL and value pairs provided + $rows = $adapter->get($SQL, $values); + + } + catch(RedBean_Exception_SQL $e) { + if ($e->getSQLState()=="42S02" || $e->getSQLState()=="42S22") { //no such table? no problem. may happen. + return array(); + } + else { + throw $e; + } + } + + + //Give the rows to RedBean OODB to convert them + //into beans. + return $redbean->convertToBeans($type, $rows); + + + } + +} + +//Short Alias for this class +class Finder extends RedBean_Plugin_Finder { } + diff --git a/libraries/external/RedBean/Plugin/Optimizer.php b/libraries/external/RedBean/Plugin/Optimizer.php new file mode 100644 index 00000000..41e47ca2 --- /dev/null +++ b/libraries/external/RedBean/Plugin/Optimizer.php @@ -0,0 +1,135 @@ + "5" + ); + + + /** + * @var RedBean_Adapter_DBAdapter + */ + private $adapter; + + /** + * @var RedBean_OODB + */ + private $oodb; + + /** + * @var RedBean_QueryWriter_MySQL + */ + private $writer; + + /** + * Constructor + * Handles the toolbox + * @param RedBean_ToolBox $toolbox + */ + public function __construct( RedBean_ToolBox $toolbox ) { + $this->scanToolBox( $toolbox ); + $this->oodb = $toolbox->getRedBean(); + $this->adapter = $toolbox->getDatabaseAdapter(); + $this->writer = $toolbox->getWriter(); + + } + + /** + * Does an optimization cycle for each UPDATE event. + * @param string $event + * @param RedBean_OODBBean $bean + */ + public function onEvent( $event , $bean ) { + try{ + if ($event=="update") { + $arr = $bean->export(); + unset($arr["id"]); + if (count($arr)==0) return; + $table = $this->adapter->escape($bean->getMeta("type")); + $columns = array_keys($arr); + //Select a random column for optimization. + $column = $this->adapter->escape($columns[ array_rand($columns) ]); + $value = $arr[$column]; + $type = $this->writer->scanType($value); + $fields = $this->writer->getColumns($table); + if (!in_array($column,array_keys($fields))) return; + $typeInField = $this->writer->code($fields[$column]); + //Is the type too wide? + if ($type < $typeInField) { + try{@$this->adapter->exec("alter table ".$this->writer->noKW($table)." drop __test");}catch(Exception $e){} + //Try to re-fit the entire column; by testing it. + $type = $this->writer->typeno_sqltype[$type]; + //Add a test column. + @$this->adapter->exec("alter table ".$this->writer->noKW($table)." add __test ".$type); + //Copy the values and see if there are differences. + @$this->adapter->exec("update ".$this->writer->noKW($table)." set __test=".$this->writer->noKW($column).""); + $rows = $this->adapter->get("select ".$this->writer->noKW($column)." as a, __test as b from ".$this->writer->noKW($table)); + $diff = 0; + foreach($rows as $row){ $diff += ($row["a"]!=$row["b"]); } + if (!$diff) { + //No differences; shrink column. + @$this->adapter->exec("alter table ".$this->writer->noKW($table)." change ".$this->writer->noKW($column)." ".$this->writer->noKW($column)." ".$type); + } + //Throw away test column; we don't need it anymore! + @$this->adapter->exec("alter table ".$this->writer->noKW($table)." drop __test"); + } + else { + $this->MySQLSpecificColumns($table, $column, $fields[$column], $value); + } + + } + }catch(RedBean_Exception_SQL $e){ + //optimizer might make mistakes, don't care. + //echo $e->getMessage()."
    "; + } + } + + + /** + * Tries to convert columns to MySQL specific types like: + * datetime, ENUM etc. This method is called automatically for you and + * works completely in the background. You can however if you like trigger + * this method by invoking it directly. + * @param string $table + * @param string $column + * @param string $columnType + * @param string $value + */ + public function MySQLSpecificColumns( $table, $column, $columnType, $value ) { + //$this->adapter->getDatabase()->setDebugMode(1); + $table = $this->adapter->escape($table); + $column = $this->adapter->escape($column); + //Is column already datetime? + if ($columnType!="datetime") { + $pattern = "/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/"; + if (preg_match($pattern, $value)){ + //Ok, value is datetime, can we convert the column to support this? + $cnt = (int) $this->adapter->getCell("select count(*) as n from $table where + $column regexp '[0-9]{4}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]' + "); + $total = (int) $this->adapter->getCell("SELECT count(*) FROM ".$this->writer->noKW($table)); + //Is it safe to convert: ie are all values compatible? + if ($total===$cnt) { //yes + $this->adapter->exec("ALTER TABLE ".$this->writer->noKW($table)." change ".$this->writer->noKW($column)." ".$this->writer->noKW($column)." datetime "); + } + } + } + + } + +} \ No newline at end of file diff --git a/libraries/external/RedBean/QueryWriter.php b/libraries/external/RedBean/QueryWriter.php new file mode 100644 index 00000000..0ad0b71d --- /dev/null +++ b/libraries/external/RedBean/QueryWriter.php @@ -0,0 +1,134 @@ +" SET('1') ", + RedBean_QueryWriter_MySQL::C_DATATYPE_UINT8=>" TINYINT(3) UNSIGNED ", + RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32=>" INT(11) UNSIGNED ", + RedBean_QueryWriter_MySQL::C_DATATYPE_DOUBLE=>" DOUBLE ", + RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT8=>" VARCHAR(255) ", + RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT16=>" TEXT ", + RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT32=>" LONGTEXT " + ); + + /** + * + * @var array + * Supported Column Types and their + * constants (magic numbers) + */ + public $sqltype_typeno = array( + "set('1')"=>RedBean_QueryWriter_MySQL::C_DATATYPE_BOOL, + "tinyint(3) unsigned"=>RedBean_QueryWriter_MySQL::C_DATATYPE_UINT8, + "int(11) unsigned"=>RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32, + "double" => RedBean_QueryWriter_MySQL::C_DATATYPE_DOUBLE, + "varchar(255)"=>RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT8, + "text"=>RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT16, + "longtext"=>RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT32 + ); + + /** + * @var array + * DTYPES code names of the supported types, + * these are used for the column names + */ + public $dtypes = array( + "booleanset","tinyintus","intus","doubles","varchar255","text","ltext" + ); + + /** + * + * @var RedBean_Adapter_DBAdapter + */ + protected $adapter; + + /** + * Indicates the field name to be used for primary keys; + * default is 'id' + * @var string + */ + protected $idfield = "id"; + + + /** + * Returns the column name that should be used + * to store and retrieve the primary key ID. + * @param string $type + * @return string $idfieldtobeused + */ + public function getIDField( $type ) { + return $this->idfield; + } + + + /** + * Checks table name or column name. + * @param string $table + * @return string $table + */ + public function check($table) { + if (strpos($table,"`")!==false) throw new RedBean_Exception_Security("Illegal chars in table name"); + return $this->adapter->escape($table); + } + + /** + * Constructor. + * The Query Writer Constructor also sets up the database. + * @param RedBean_Adapter_DBAdapter $adapter + */ + public function __construct( RedBean_Adapter $adapter, $frozen = false ) { + $this->adapter = $adapter; + } + + + /** + * Returns all tables in the database. + * @return array $tables + */ + public function getTables() { + return $this->adapter->getCol( "show tables" ); + } + + /** + * Creates an empty, column-less table for a bean. + * @param string $table + */ + public function createTable( $table ) { + $idfield = $this->getIDfield($table); + $table = $this->check($table); + $sql = " + CREATE TABLE `$table` ( + `$idfield` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT , + PRIMARY KEY ( `$idfield` ) + ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci + "; + $this->adapter->exec( $sql ); + } + + /** + * Returns an array containing the column names of the specified table. + * @param string $table + * @return array $columns + */ + public function getColumns( $table ) { + $table = $this->check($table); + $columnsRaw = $this->adapter->get("DESCRIBE `$table`"); + foreach($columnsRaw as $r) { + $columns[$r["Field"]]=$r["Type"]; + } + return $columns; + } + + /** + * Returns the MySQL Column Type Code (integer) that corresponds + * to the given value type. + * @param string $value + * @return integer $type + */ + public function scanType( $value ) { + + if (is_null($value)) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_BOOL; + } + $orig = $value; + $value = strval($value); + if ($value=="1" || $value=="" || $value=="0") { + return RedBean_QueryWriter_MySQL::C_DATATYPE_BOOL; + } + if (is_numeric($value) && (floor($value)==$value) && $value >= 0 && $value <= 255 ) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_UINT8; + } + if (is_numeric($value) && (floor($value)==$value) && $value >= 0 && $value <= 4294967295 ) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32; + } + if (is_numeric($value)) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_DOUBLE; + } + if (strlen($value) <= 255) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT8; + } + return RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT16; + } + + /** + * Adds a column of a given type to a table. + * @param string $table + * @param string $column + * @param integer $type + */ + public function addColumn( $table, $column, $type ) { + $column = $this->check($column); + $table = $this->check($table); + $type=$this->typeno_sqltype[$type]; + $sql = "ALTER TABLE `$table` ADD `$column` $type "; + $this->adapter->exec( $sql ); + } + + /** + * Returns the Type Code for a Column Description + * @param string $typedescription + * @return integer $typecode + */ + public function code( $typedescription ) { + return ((isset($this->sqltype_typeno[$typedescription])) ? $this->sqltype_typeno[$typedescription] : 99); + } + + /** + * Change (Widen) the column to the give type. + * @param string $table + * @param string $column + * @param integer $type + */ + public function widenColumn( $table, $column, $type ) { + $column = $this->check($column); + $table = $this->check($table); + $newtype = $this->typeno_sqltype[$type]; + $changecolumnSQL = "ALTER TABLE `$table` CHANGE `$column` `$column` $newtype "; + $this->adapter->exec( $changecolumnSQL ); + } + + /** + * Update a record using a series of update values. + * @param string $table + * @param array $updatevalues + * @param integer $id + */ + public function updateRecord( $table, $updatevalues, $id) { + $idfield = $this->getIDField($table); + $sql = "UPDATE `".$this->check($table)."` SET "; + $p = $v = array(); + foreach($updatevalues as $uv) { + $p[] = " `".$uv["property"]."` = ? "; + $v[]=( $uv["value"] ); + } + $sql .= implode(",", $p ) ." WHERE $idfield = ".intval($id); + $this->adapter->exec( $sql, $v ); + } + + /** + * Inserts a record into the database using a series of insert columns + * and corresponding insertvalues. Returns the insert id. + * @param string $table + * @param array $insertcolumns + * @param array $insertvalues + * @return integer $insertid + */ + public function insertRecord( $table, $insertcolumns, $insertvalues ) { + //if ($table == "__log") $idfield="id"; else + $idfield = $this->getIDField($table); + $table = $this->check($table); + if (count($insertvalues)>0 && is_array($insertvalues[0]) && count($insertvalues[0])>0) { + foreach($insertcolumns as $k=>$v) { + $insertcolumns[$k] = "`".$this->check($v)."`"; + } + $insertSQL = "INSERT INTO `$table` ( $idfield, ".implode(",",$insertcolumns)." ) VALUES "; + $pat = "( NULL, ". implode(",",array_fill(0,count($insertcolumns)," ? "))." )"; + $insertSQL .= implode(",",array_fill(0,count($insertvalues),$pat)); + foreach($insertvalues as $insertvalue) { + foreach($insertvalue as $v) { + $vs[] = ( $v ); + } + } + $this->adapter->exec( $insertSQL, $vs ); + return ($this->adapter->getErrorMsg()=="" ? $this->adapter->getInsertID() : 0); + } + else { + $this->adapter->exec( "INSERT INTO `$table` ($idfield) VALUES(NULL) " ); + return ($this->adapter->getErrorMsg()=="" ? $this->adapter->getInsertID() : 0); + } + } + + /** + * Selects a record based on type and id. + * @param string $type + * @param integer $id + * @return array $row + */ + public function selectRecord($type, $ids) { + $idfield = $this->getIDField($type); + $type=$this->check($type); + $sql = "SELECT * FROM `$type` WHERE $idfield IN ( ".implode(',', array_fill(0, count($ids), " ? "))." )"; + $rows = $this->adapter->get($sql,$ids); + return ($rows) ? $rows : NULL; + + } + + /** + * Deletes a record based on a table, column, value and operator + * @param string $table + * @param string $column + * @param mixed $value + * @param string $oper + * @todo validate arguments for security + */ + public function deleteRecord( $table, $id) { + $table = $this->check($table); + $this->adapter->exec("DELETE FROM `$table` WHERE `".$this->getIDField($table)."` = ? ",array(strval($id))); + } + + /** + * Adds a Unique index constrain to the table. + * @param string $table + * @param string $col1 + * @param string $col2 + * @return void + */ + public function addUniqueIndex( $table,$columns ) { + sort($columns); //else we get multiple indexes due to order-effects + foreach($columns as $k=>$v) { + $columns[$k]="`".$this->adapter->escape($v)."`"; + } + $table = $this->check($table); + $r = $this->adapter->get("SHOW INDEX FROM `$table`"); + $name = "UQ_".sha1(implode(',',$columns)); + if ($r) { + foreach($r as $i) { + if ($i["Key_name"]==$name) { + return; + } + } + } + $sql = "ALTER IGNORE TABLE `$table` + ADD UNIQUE INDEX `$name` (".implode(",",$columns).")"; + $this->adapter->exec($sql); + } + + /** + * Selects a record using a criterium. + * Specify the select-column, the target table, the criterium column + * and the criterium value. This method scans the specified table for + * records having a criterium column with a value that matches the + * specified value. For each record the select-column value will be + * returned, most likely this will be a primary key column like ID. + * If $withUnion equals true the method will also return the $column + * values for each entry that has a matching select-column. This is + * handy for cross-link tables like page_page. + * @param string $select, the column to be selected + * @param string $table, the table to select from + * @param string $column, the column to compare the criteria value against + * @param string $value, the criterium value to match against + * @param boolean $withUnion (default is false) + * @return array $mixedColumns + */ + public function selectByCrit( $select, $table, $column, $value, $withUnion=false ) { + $select = $this->noKW($this->adapter->escape($select)); + $table = $this->noKW($this->adapter->escape($table)); + $column = $this->noKW($this->adapter->escape($column)); + $value = $this->adapter->escape($value); + $sql = "SELECT $select FROM $table WHERE $column = ? "; + $values = array($value); + if ($withUnion) { + $sql .= " UNION SELECT $column FROM $table WHERE $select = ? "; + $values[] = $value; + } + return $this->adapter->getCol($sql,$values); + } + + /** + * This method takes an array with key=>value pairs. + * Each record that has a complete match with the array is + * deleted from the table. + * @param string $table + * @param array $crits + * @return integer $affectedRows + */ + public function deleteByCrit( $table, $crits ) { + $table = $this->noKW($this->adapter->escape($table)); + $values = array(); + foreach($crits as $key=>$val) { + $key = $this->noKW($this->adapter->escape($key)); + $values[] = $this->adapter->escape($val); + $conditions[] = $key ."= ? "; + } + $sql = "DELETE FROM $table WHERE ".implode(" AND ", $conditions); + return (int) $this->adapter->exec($sql, $values); + } + + /** + * Puts keyword escaping symbols around string. + * @param string $str + * @return string $keywordSafeString + */ + public function noKW($str) { + return "`".$str."`"; + } +} \ No newline at end of file diff --git a/libraries/external/RedBean/QueryWriter/MySQLS.php b/libraries/external/RedBean/QueryWriter/MySQLS.php new file mode 100644 index 00000000..62af55a5 --- /dev/null +++ b/libraries/external/RedBean/QueryWriter/MySQLS.php @@ -0,0 +1,109 @@ +" SET('1') ", + RedBean_QueryWriter_MySQL::C_DATATYPE_UINT8=>" TINYINT(3) UNSIGNED ", + RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32=>" INT(11) UNSIGNED ", + RedBean_QueryWriter_MySQL::C_DATATYPE_DOUBLE=>" DOUBLE ", + RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT8=>" VARCHAR(255) ", + RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT16=>" TEXT ", + RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT32=>" LONGTEXT " + ); + + /** + * + * @var array + * Supported Column Types and their + * constants (magic numbers) + */ + public $sqltype_typeno = array( + "set('1')"=>RedBean_QueryWriter_MySQL::C_DATATYPE_BOOL, + "tinyint(3) unsigned"=>RedBean_QueryWriter_MySQL::C_DATATYPE_UINT8, + "int(11) unsigned"=>RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32, + "double" => RedBean_QueryWriter_MySQL::C_DATATYPE_DOUBLE, + "varchar(255)"=>RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT8, + "text"=>RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT16, + "longtext"=>RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT32 + ); + + /** + * Constructor + * @param RedBean_Adapter $adapter + * @param boolean $frozen + */ + public function __construct( RedBean_Adapter $adapter, $frozen = false ) { + $this->adapter = $adapter; + //try{ $this->adapter->exec("set session sql_mode='STRICT_ALL_TABLES'"); + //}catch(Exception $e){} + } + + + /** + * Scans the type using PHP. + * @param mixed $value + * @return integer $typeConstant + */ + public function scanType( $value ) { + + if (is_null($value)) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_BOOL; + } + $orig = $value; + $value = strval($value); + if ($value=="1" || $value=="" || $value=="0") { + return RedBean_QueryWriter_MySQL::C_DATATYPE_BOOL; + } + if (is_numeric($value) && (floor($value)==$value) && $value >= 0 && $value <= 255 ) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_UINT8; + } + if (is_numeric($value) && (floor($value)==$value) && $value >= 0 && $value <= 4294967295 ) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32; + } + if (is_numeric($value)) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_DOUBLE; + } + if (strlen($value) <= 255) { + return RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT8; + } + return RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT16; + } + + + + /** + * Selects a record based on type and id. + * @param string $type + * @param integer $id + * @return array $row + */ + public function selectRecord($type, $ids) { + $rows = parent::selectRecord($type, $ids); + if ($rows) { + foreach($rows as $key=>$row) { + foreach($row as $k=>$cell) { + if ($cell=="") unset( $rows[$key][$k] ); + } + } + } + return $rows; + } + + +} + diff --git a/libraries/external/RedBean/QueryWriter/NullWriter.php b/libraries/external/RedBean/QueryWriter/NullWriter.php new file mode 100644 index 00000000..d34ccd79 --- /dev/null +++ b/libraries/external/RedBean/QueryWriter/NullWriter.php @@ -0,0 +1,360 @@ +returnTables; } + public function createTable( $table ){ $this->createTableArgument = $table; } + public function getColumns( $table ){ $this->getColumnsArgument = $table; return $this->returnGetColumns; } + public function scanType( $value ){ $this->scanTypeArgument = $value; return $this->returnScanType; } + public function addColumn( $table, $column, $type ){ + $this->addColumnArguments = array( $table, $column, $type ); + return $this->returnAddColumn; + } + + + public function code( $typedescription ){ $this->codeArgument = $typedescription; + return $this->returnCode; + } + public function widenColumn( $table, $column, $type ){ + $this->widenColumnArguments = array($table, $column, $type); + return $this->returnWidenColumn; + } + public function updateRecord( $table, $updatevalues, $id){ + $this->updateRecordArguments = array($table, $updatevalues, $id); + return $this->returnUpdateRecord; + } + public function insertRecord( $table, $insertcolumns, $insertvalues ){ + $this->insertRecordArguments = array( $table, $insertcolumns, $insertvalues ); + return $this->returnInsertRecord; + } + public function selectRecord($type, $ids){ + $this->selectRecordArguments = array($type, $ids); + return $this->returnSelectRecord; + } + public function deleteRecord( $table, $id){ + $this->deleteRecordArguments = array($table, "id", $id); + return $this->returnDeleteRecord; + } + public function checkChanges($type, $id, $logid){ + $this->checkChangesArguments = array($type, $id, $logid); + return $this->returnCheckChanges; + } + public function addUniqueIndex( $table,$columns ){ + $this->addUniqueIndexArguments=array($table,$columns); + return $this->returnAddUniqueIndex; + } + + public function selectByCrit( $select, $table, $column, $value, $withUnion=false ){ + $this->selectByCritArguments=array($select, $table, $column, $value, $withUnion); + return $this->returnSelectByCrit; + } + + public function deleteByCrit( $table, $crits ){ + $this->deleteByCrit=array($table, $crits ); + return $this->returnDeleteByCrit; + } + + + public function getIDField( $type ) { return "id"; } + + public function noKW($str) { return $str; } + + /** + * Resets the mock object. All public + * properties will be assigned values like NULL or an empty + * array. + */ + public function reset() { + $this->createTableArgument = NULL; + $this->getColumnsArgument = NULL; + $this->scanTypeArgument = NULL; + $this->addColumnArguments = array(); + $this->codeArgument = NULL; + $this->widenColumnArguments = array(); + $this->updateRecordArguments = array(); + $this->insertRecordArguments = array(); + $this->selectRecordArguments = array(); + $this->deleteRecordArguments = array(); + $this->checkChangesArguments = array(); + $this->addUniqueIndexArguments = array(); + + $this->returnTables = array(); + $this->returnGetColumns = array(); + $this->returnScanType = 1; + $this->returnAddColumn = NULL; + $this->returnCode = NULL; + $this->returnWidenColumn = NULL; + $this->returnUpdateRecord = NULL; + $this->returnInsertRecord = NULL; + $this->returnSelectRecord = NULL; + $this->returnDeleteRecord = NULL; + $this->returnCheckChanges = NULL; + $this->returnAddUniqueIndex = NULL; + } +} \ No newline at end of file diff --git a/libraries/external/RedBean/Setup.php b/libraries/external/RedBean/Setup.php new file mode 100644 index 00000000..d43fb934 --- /dev/null +++ b/libraries/external/RedBean/Setup.php @@ -0,0 +1,239 @@ +getRedBean(); Now you have a reference + * to the RedBean object. + * @param string $dsn + * @param string $username + * @param string $password + * @return RedBean_ToolBox $toolbox + */ + public static function kickstart( $dsn, $username, $password, $frozen=false ) { + + self::checkDSN($dsn); + $pdo = new RedBean_Driver_PDO( $dsn,$username,$password ); + $adapter = new RedBean_Adapter_DBAdapter( $pdo ); + + $writer = new RedBean_QueryWriter_MySQL( $adapter, $frozen ); + + $redbean = new RedBean_OODB( $writer ); + $toolbox = new RedBean_ToolBox( $redbean, $adapter, $writer ); + + //deliver everything back in a neat toolbox + self::$toolbox = $toolbox; + return self::$toolbox; + + } + + /** + * Kickstart for development phase. + * Use this method to quickly setup RedBean for use during development phase. + * This Kickstart establishes a database connection + * using the $dsn, the $username and the $password you provide. + * It will start RedBean in fluid mode; meaning the database will + * be altered if required to store your beans. + * This method returns a RedBean_Toolbox $toolbox filled with a + * RedBean_Adapter, a RedBean_QueryWriter and most importantly a + * RedBean_OODB; the object database. To start storing beans in the database + * simply say: $redbean = $toolbox->getRedBean(); Now you have a reference + * to the RedBean object. + * @param string $dsn + * @param string $username + * @param string $password + * @return RedBean_ToolBox $toolbox + */ + public static function kickstartDev( $dsn, $username="root", $password="" ) { + $toolbox = self::kickstart($dsn, $username, $password); + return $toolbox; + } + + /** + * Kickstart for development phase (strict mode). + * Use this method to quickly setup RedBean for use during development phase. + * This Kickstart establishes a database connection + * using the $dsn, the $username and the $password you provide. + * It will start RedBean in fluid mode; meaning the database will + * be altered if required to store your beans. + * This method returns a RedBean_Toolbox $toolbox filled with a + * RedBean_Adapter, a RedBean_QueryWriter and most importantly a + * RedBean_OODB; the object database. To start storing beans in the database + * simply say: $redbean = $toolbox->getRedBean(); Now you have a reference + * to the RedBean object. + * @param string $dsn + * @param string $username + * @param string $password + * @return RedBean_ToolBox $toolbox + */ + public static function kickstartDevS( $dsn, $username="root", $password="" ) { + $frozen = false; + self::checkDSN($dsn); + $pdo = new RedBean_Driver_PDO( $dsn,$username,$password ); + $adapter = new RedBean_Adapter_DBAdapter( $pdo ); + $writer = new RedBean_QueryWriter_MySQLS( $adapter, $frozen ); + $redbean = new RedBean_OODB( $writer ); + $toolbox = new RedBean_ToolBox( $redbean, $adapter, $writer ); + //deliver everything back in a neat toolbox + self::$toolbox = $toolbox; + return self::$toolbox; + } + + + /** + * Almost the same as Dev, but adds the journaling plugin by default for you. + * This Kickstart establishes a database connection + * using the $dsn, the $username and the $password you provide. + * The Journaling plugin detects Race Conditions, for more information please + * consult the RedBean_Plugin_ChangeLogger Documentation. + * This method returns a RedBean_Toolbox $toolbox filled with a + * RedBean_Adapter, a RedBean_QueryWriter and most importantly a + * RedBean_OODB; the object database. To start storing beans in the database + * simply say: $redbean = $toolbox->getRedBean(); Now you have a reference + * to the RedBean object. + * @param string $dsn + * @param string $username + * @param string $password + * @return RedBean_ToolBox $toolbox + */ + public static function KickStartDevWithJournal($dsn, $username="root", $password="") { + $toolbox = self::kickstart($dsn, $username, $password); + $redbean = $toolbox->getRedBean(); + $logger = new RedBean_Plugin_ChangeLogger( $toolbox ); + self::$observers["logger"] = $logger; + $redbean->addEventListener( "open", $logger ); + $redbean->addEventListener( "update", $logger); + $redbean->addEventListener( "delete", $logger); + return $toolbox; + } + + + /** + * Kickstart method for production environment. + * This Kickstart establishes a database connection + * using the $dsn, the $username and the $password you provide. + * This method will start RedBean in frozen mode which is + * the preferred mode of operation for a production environment. + * In frozen mode, RedBean will not alter the schema of the database; + * which improves performance and security. + * This method returns a RedBean_Toolbox $toolbox filled with a + * RedBean_Adapter, a RedBean_QueryWriter and most importantly a + * RedBean_OODB; the object database. To start storing beans in the database + * simply say: $redbean = $toolbox->getRedBean(); Now you have a reference + * to the RedBean object. + * @param string $dsn + * @param string $username + * @param string $password + * @return RedBean_ToolBox $toolbox + */ + public static function kickstartFrozen( $dsn, $username, $password ) { + $toolbox = self::kickstart($dsn, $username, $password, true); + $toolbox->getRedBean()->freeze(true); + return $toolbox; + } + + /** + * Kickstart Method for debugging. + * This method returns a RedBean_Toolbox $toolbox filled with a + * RedBean_Adapter, a RedBean_QueryWriter and most importantly a + * RedBean_OODB; the object database. To start storing beans in the database + * simply say: $redbean = $toolbox->getRedBean(); Now you have a reference + * to the RedBean object. + * @param string $dsn + * @param string $username + * @param string $password + * @return RedBean_ToolBox $toolbox + */ + public static function kickstartDebug( $dsn, $username="root", $password="" ) { + $toolbox = self::kickstart($dsn, $username, $password); + $toolbox->getDatabaseAdapter()->getDatabase()->setDebugMode( true ); + return $toolbox; + } + + + /** + * During a kickstart method observers may be attached to the RedBean_OODB object. + * Setup keeps track of the observers that are connected to RedBean. + * Returns the observers that have been attached by Setup. + * @return array $observers + */ + public static function getAttachedObservers() { + return self::$observers; + } + + /** + * This is a convenience method. By default a kickstart method + * returns the RedBean_ToolBox $toolbox for you with all necessary + * objects inside. If for some reason you need to have access to the + * latest toolbox that Setup has assembled you can use this function + * to retrieve it. + * Returns the most recently assembled toolbox + * @return RedBean_ToolBox $toolbox + */ + public static function getToolBox() { + return self::$toolbox; + } + +} diff --git a/libraries/external/RedBean/SimpleStat.php b/libraries/external/RedBean/SimpleStat.php new file mode 100644 index 00000000..c1d6982b --- /dev/null +++ b/libraries/external/RedBean/SimpleStat.php @@ -0,0 +1,70 @@ + "5" + ); + + + /** + * Constructor + * @param RedBean_ToolBox $tools + */ + public function __construct( RedBean_ToolBox $tools ) { + + //Do a compatibility check, using the Compatibility Management System + $this->scanToolBox( $tools ); + + + $this->oodb = $tools->getRedBean(); + $this->adapter = $tools->getDatabaseAdapter(); + $this->writer = $tools->getWriter(); + } + + + /** + * Counts the number of beans of a specific type + * @param RedBean_OODBBean $bean + * @return integer $count + */ + public function numberOf(RedBean_OODBBean $bean) { + $type = $this->adapter->escape( $bean->getMeta("type") ); + return (int) $this->adapter->getCell("SELECT count(*) FROM `$type`"); + } + + + + +} \ No newline at end of file diff --git a/libraries/external/RedBean/ToolBox.php b/libraries/external/RedBean/ToolBox.php new file mode 100644 index 00000000..5544c5c0 --- /dev/null +++ b/libraries/external/RedBean/ToolBox.php @@ -0,0 +1,95 @@ +oodb = $oodb; + $this->adapter = $adapter; + $this->writer = $writer; + return $this; + } + + /** + * The Toolbox acts as a kind of micro service locator, providing just the + * most important objects that make up RedBean. You can pass the toolkit to + * any object that needs one of these objects to function properly. + * Returns the QueryWriter; normally you do not use this object but other + * object might want to use the default RedBean query writer to be + * database independent. + * @return RedBean_QueryWriter $writer + */ + public function getWriter() { + return $this->writer; + } + + /** + * The Toolbox acts as a kind of micro service locator, providing just the + * most important objects that make up RedBean. You can pass the toolkit to + * any object that needs one of these objects to function properly. + * Retruns the RedBean OODB Core object. The RedBean OODB object is + * the ultimate core of Redbean. It provides the means to store and load + * beans. Extract this object immediately after invoking a kickstart method. + * @return RedBean_OODB $oodb + */ + public function getRedBean() { + return $this->oodb; + } + + /** + * The Toolbox acts as a kind of micro service locator, providing just the + * most important objects that make up RedBean. You can pass the toolkit to + * any object that needs one of these objects to function properly. + * Returns the adapter. The Adapter can be used to perform queries + * on the database directly. + * @return RedBean_Adapter_DBAdapter $adapter + */ + public function getDatabaseAdapter() { + return $this->adapter; + } +} \ No newline at end of file diff --git a/libraries/external/RedBean/TreeManager.php b/libraries/external/RedBean/TreeManager.php new file mode 100644 index 00000000..68f511a9 --- /dev/null +++ b/libraries/external/RedBean/TreeManager.php @@ -0,0 +1,83 @@ +oodb = $tools->getRedBean(); + $this->adapter = $tools->getDatabaseAdapter(); + $this->writer = $tools->getWriter(); + } + + /** + * Attaches the specified child node to the specified parent node. + * @param RedBean_OODBBean $parent + * @param RedBean_OODBBean $child + */ + public function attach( RedBean_OODBBean $parent, RedBean_OODBBean $child ) { + $idfield = $this->writer->getIDField($parent->getMeta("type")); + if (!intval($parent->$idfield)) $this->oodb->store($parent); + $child->{$this->property} = $parent->$idfield; + $this->oodb->store($child); + } + + /** + * Returns all the nodes that have been attached to the specified + * parent node. + * @param RedBean_OODBBean $parent + * @return array $childObjects + */ + public function children( RedBean_OODBBean $parent ) { + $idfield = $this->writer->getIDField($parent->getMeta("type")); + try { + $ids = $this->writer->selectByCrit( $idfield, + $parent->getMeta("type"), + $this->property, + intval( $parent->$idfield ) ); + + } + catch(RedBean_Exception_SQL $e) { + return array(); + } + return $this->oodb->batch($parent->getMeta("type"),$ids ); + } + +} \ No newline at end of file diff --git a/libraries/external/RedBean/example.php b/libraries/external/RedBean/example.php new file mode 100644 index 00000000..86e00b56 --- /dev/null +++ b/libraries/external/RedBean/example.php @@ -0,0 +1,85 @@ +getRedBean(); +$db = $toolbox->getDatabaseAdapter(); +$writer = $toolbox->getWriter(); + +//Creating an Association Manager for you +$assoc = new RedBean_AssociationManager( $toolbox ); + +//Creating a Tree Manager for you +$tree = new RedBean_TreeManager( $toolbox ); + +function assoc( $bean1, $bean2 ) { + global $assoc; + $assoc->associate($bean1, $bean2); + + //also put a cascaded delete constraint - why not? + RedBean_Plugin_Constraint::addConstraint($bean1, $bean2); +} + +function related( $bean, $type ) { + global $assoc; + return $assoc->related($bean, $type); +} + +function clearassoc($bean, $type) { + global $assoc; + $assoc->clearRelations($bean, $type); +} + +function unassoc($bean1, $bean2) { + global $assoc; + $assoc->unassociate($bean1, $bean2); +} + +/* + + PUT YOUR CODE HERE... + + OR... + + ...INCLUDE THIS FILE AND WORK WITH THE + CREATED OBJECTS DIRECTLY. + + +*/ \ No newline at end of file diff --git a/libraries/external/RedBean/license.txt b/libraries/external/RedBean/license.txt new file mode 100644 index 00000000..2d045f9f --- /dev/null +++ b/libraries/external/RedBean/license.txt @@ -0,0 +1,40 @@ + + + .______. +_______ ____ __| _/\_ |__ ____ _____ ____ +\_ __ \_/ __ \ / __ | | __ \_/ __ \\__ \ / \ + | | \/\ ___// /_/ | | \_\ \ ___/ / __ \| | \ + |__| \___ >____ | |___ /\___ >____ /___| / + \/ \/ \/ \/ \/ \/ + + + +RedBean Database Objects - +Written by Gabor de Mooij (c) copyright 2010 + +RedBean is Licensed BSD + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +* Neither the name of RedBeanPHP nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY GABOR DE MOOIJ ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL GABOR DE MOOIJ BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +RedBeanPHP is Written by Gabor de Mooij (G.J.G.T de Mooij) Copyright (c) 2010. diff --git a/libraries/external/RedBean/redbean.inc.php b/libraries/external/RedBean/redbean.inc.php new file mode 100644 index 00000000..c163ccb0 --- /dev/null +++ b/libraries/external/RedBean/redbean.inc.php @@ -0,0 +1,85 @@ +____ | |___ /\___ >____ /___| / + \/ \/ \/ \/ \/ \/ + + Written by Gabor de Mooij Copyright (c) 2009 + + */ + +/** + * RedBean Loader + * @file RedBean/redbean.inc.php + * @description If you do not use a pre-packaged version of RedBean + * you can use this RedBean loader to include all RedBean + * files for you. + * @author Gabor de Mooij + * @license BSD + * + * (c) G.J.G.T. (Gabor) de Mooij + * This source file is subject to the BSD license that is bundled + * with this source code in the file license.txt. + */ + + + + +//Check the current PHP version +if (version_compare(PHP_VERSION, '5.0.0', '<')) { + throw new Exception("Sorry, RedBean is not compatible with PHP versions < 5."); +} + +//Set the directory path +$dir = dirname(__FILE__) . "/"; + +//Load Core Intefaces +require($dir."ObjectDatabase.php"); +require($dir."Plugin.php"); + +//Load Database drivers +require($dir."Driver.php"); +require($dir."Driver/PDO.php"); + +//Load Infrastructure +require($dir."OODBBean.php"); +require($dir."Observable.php"); +require($dir."Observer.php"); + +//Load Database Adapters +require($dir."Adapter.php"); +require($dir."Adapter/DBAdapter.php"); + +//Load SQL drivers +require($dir."QueryWriter.php"); +require($dir."QueryWriter/MySQL.php"); + +//Load required Exceptions +require($dir."Exception.php"); +require($dir."Exception/SQL.php"); +require($dir."Exception/Security.php"); +require($dir."Exception/FailedAccessBean.php"); +require($dir."Exception/NotImplemented.php"); +require($dir."Exception/UnsupportedDatabase.php"); + +//Load Core functionality +require("OODB.php"); +require("ToolBox.php"); +require("CompatManager.php"); + +//Load extended functionality +require("AssociationManager.php"); +require("TreeManager.php"); +require("Setup.php"); +require("SimpleStat.php"); + +//Load the default plugins +require("Plugin/ChangeLogger.php"); +require("Plugin/Cache.php"); +require("Plugin/Finder.php"); +require("Plugin/Constraint.php"); diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/HTMLPurifier.standalone.php b/libraries/external/htmlpurifier-4.1.1-standalone/HTMLPurifier.standalone.php new file mode 100644 index 00000000..f7e09c5b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/HTMLPurifier.standalone.php @@ -0,0 +1,16149 @@ +config = HTMLPurifier_Config::create($config); + + $this->strategy = new HTMLPurifier_Strategy_Core(); + + } + + /** + * Adds a filter to process the output. First come first serve + * @param $filter HTMLPurifier_Filter object + */ + public function addFilter($filter) { + trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING); + $this->filters[] = $filter; + } + + /** + * Filters an HTML snippet/document to be XSS-free and standards-compliant. + * + * @param $html String of HTML to purify + * @param $config HTMLPurifier_Config object for this operation, if omitted, + * defaults to the config object specified during this + * object's construction. The parameter can also be any type + * that HTMLPurifier_Config::create() supports. + * @return Purified HTML + */ + public function purify($html, $config = null) { + + // :TODO: make the config merge in, instead of replace + $config = $config ? HTMLPurifier_Config::create($config) : $this->config; + + // implementation is partially environment dependant, partially + // configuration dependant + $lexer = HTMLPurifier_Lexer::create($config); + + $context = new HTMLPurifier_Context(); + + // setup HTML generator + $this->generator = new HTMLPurifier_Generator($config, $context); + $context->register('Generator', $this->generator); + + // set up global context variables + if ($config->get('Core.CollectErrors')) { + // may get moved out if other facilities use it + $language_factory = HTMLPurifier_LanguageFactory::instance(); + $language = $language_factory->create($config, $context); + $context->register('Locale', $language); + + $error_collector = new HTMLPurifier_ErrorCollector($context); + $context->register('ErrorCollector', $error_collector); + } + + // setup id_accumulator context, necessary due to the fact that + // AttrValidator can be called from many places + $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); + $context->register('IDAccumulator', $id_accumulator); + + $html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context); + + // setup filters + $filter_flags = $config->getBatch('Filter'); + $custom_filters = $filter_flags['Custom']; + unset($filter_flags['Custom']); + $filters = array(); + foreach ($filter_flags as $filter => $flag) { + if (!$flag) continue; + if (strpos($filter, '.') !== false) continue; + $class = "HTMLPurifier_Filter_$filter"; + $filters[] = new $class; + } + foreach ($custom_filters as $filter) { + // maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat + $filters[] = $filter; + } + $filters = array_merge($filters, $this->filters); + // maybe prepare(), but later + + for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) { + $html = $filters[$i]->preFilter($html, $config, $context); + } + + // purified HTML + $html = + $this->generator->generateFromTokens( + // list of tokens + $this->strategy->execute( + // list of un-purified tokens + $lexer->tokenizeHTML( + // un-purified HTML + $html, $config, $context + ), + $config, $context + ) + ); + + for ($i = $filter_size - 1; $i >= 0; $i--) { + $html = $filters[$i]->postFilter($html, $config, $context); + } + + $html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context); + $this->context =& $context; + return $html; + } + + /** + * Filters an array of HTML snippets + * @param $config Optional HTMLPurifier_Config object for this operation. + * See HTMLPurifier::purify() for more details. + * @return Array of purified HTML + */ + public function purifyArray($array_of_html, $config = null) { + $context_array = array(); + foreach ($array_of_html as $key => $html) { + $array_of_html[$key] = $this->purify($html, $config); + $context_array[$key] = $this->context; + } + $this->context = $context_array; + return $array_of_html; + } + + /** + * Singleton for enforcing just one HTML Purifier in your system + * @param $prototype Optional prototype HTMLPurifier instance to + * overload singleton with, or HTMLPurifier_Config + * instance to configure the generated version with. + */ + public static function instance($prototype = null) { + if (!self::$instance || $prototype) { + if ($prototype instanceof HTMLPurifier) { + self::$instance = $prototype; + } elseif ($prototype) { + self::$instance = new HTMLPurifier($prototype); + } else { + self::$instance = new HTMLPurifier(); + } + } + return self::$instance; + } + + /** + * @note Backwards compatibility, see instance() + */ + public static function getInstance($prototype = null) { + return HTMLPurifier::instance($prototype); + } + +} + + + + + +/** + * Defines common attribute collections that modules reference + */ + +class HTMLPurifier_AttrCollections +{ + + /** + * Associative array of attribute collections, indexed by name + */ + public $info = array(); + + /** + * Performs all expansions on internal data for use by other inclusions + * It also collects all attribute collection extensions from + * modules + * @param $attr_types HTMLPurifier_AttrTypes instance + * @param $modules Hash array of HTMLPurifier_HTMLModule members + */ + public function __construct($attr_types, $modules) { + // load extensions from the modules + foreach ($modules as $module) { + foreach ($module->attr_collections as $coll_i => $coll) { + if (!isset($this->info[$coll_i])) { + $this->info[$coll_i] = array(); + } + foreach ($coll as $attr_i => $attr) { + if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { + // merge in includes + $this->info[$coll_i][$attr_i] = array_merge( + $this->info[$coll_i][$attr_i], $attr); + continue; + } + $this->info[$coll_i][$attr_i] = $attr; + } + } + } + // perform internal expansions and inclusions + foreach ($this->info as $name => $attr) { + // merge attribute collections that include others + $this->performInclusions($this->info[$name]); + // replace string identifiers with actual attribute objects + $this->expandIdentifiers($this->info[$name], $attr_types); + } + } + + /** + * Takes a reference to an attribute associative array and performs + * all inclusions specified by the zero index. + * @param &$attr Reference to attribute array + */ + public function performInclusions(&$attr) { + if (!isset($attr[0])) return; + $merge = $attr[0]; + $seen = array(); // recursion guard + // loop through all the inclusions + for ($i = 0; isset($merge[$i]); $i++) { + if (isset($seen[$merge[$i]])) continue; + $seen[$merge[$i]] = true; + // foreach attribute of the inclusion, copy it over + if (!isset($this->info[$merge[$i]])) continue; + foreach ($this->info[$merge[$i]] as $key => $value) { + if (isset($attr[$key])) continue; // also catches more inclusions + $attr[$key] = $value; + } + if (isset($this->info[$merge[$i]][0])) { + // recursion + $merge = array_merge($merge, $this->info[$merge[$i]][0]); + } + } + unset($attr[0]); + } + + /** + * Expands all string identifiers in an attribute array by replacing + * them with the appropriate values inside HTMLPurifier_AttrTypes + * @param &$attr Reference to attribute array + * @param $attr_types HTMLPurifier_AttrTypes instance + */ + public function expandIdentifiers(&$attr, $attr_types) { + + // because foreach will process new elements we add, make sure we + // skip duplicates + $processed = array(); + + foreach ($attr as $def_i => $def) { + // skip inclusions + if ($def_i === 0) continue; + + if (isset($processed[$def_i])) continue; + + // determine whether or not attribute is required + if ($required = (strpos($def_i, '*') !== false)) { + // rename the definition + unset($attr[$def_i]); + $def_i = trim($def_i, '*'); + $attr[$def_i] = $def; + } + + $processed[$def_i] = true; + + // if we've already got a literal object, move on + if (is_object($def)) { + // preserve previous required + $attr[$def_i]->required = ($required || $attr[$def_i]->required); + continue; + } + + if ($def === false) { + unset($attr[$def_i]); + continue; + } + + if ($t = $attr_types->get($def)) { + $attr[$def_i] = $t; + $attr[$def_i]->required = $required; + } else { + unset($attr[$def_i]); + } + } + + } + +} + + + + + +/** + * Base class for all validating attribute definitions. + * + * This family of classes forms the core for not only HTML attribute validation, + * but also any sort of string that needs to be validated or cleaned (which + * means CSS properties and composite definitions are defined here too). + * Besides defining (through code) what precisely makes the string valid, + * subclasses are also responsible for cleaning the code if possible. + */ + +abstract class HTMLPurifier_AttrDef +{ + + /** + * Tells us whether or not an HTML attribute is minimized. Has no + * meaning in other contexts. + */ + public $minimized = false; + + /** + * Tells us whether or not an HTML attribute is required. Has no + * meaning in other contexts + */ + public $required = false; + + /** + * Validates and cleans passed string according to a definition. + * + * @param $string String to be validated and cleaned. + * @param $config Mandatory HTMLPurifier_Config object. + * @param $context Mandatory HTMLPurifier_AttrContext object. + */ + abstract public function validate($string, $config, $context); + + /** + * Convenience method that parses a string as if it were CDATA. + * + * This method process a string in the manner specified at + * by removing + * leading and trailing whitespace, ignoring line feeds, and replacing + * carriage returns and tabs with spaces. While most useful for HTML + * attributes specified as CDATA, it can also be applied to most CSS + * values. + * + * @note This method is not entirely standards compliant, as trim() removes + * more types of whitespace than specified in the spec. In practice, + * this is rarely a problem, as those extra characters usually have + * already been removed by HTMLPurifier_Encoder. + * + * @warning This processing is inconsistent with XML's whitespace handling + * as specified by section 3.3.3 and referenced XHTML 1.0 section + * 4.7. However, note that we are NOT necessarily + * parsing XML, thus, this behavior may still be correct. We + * assume that newlines have been normalized. + */ + public function parseCDATA($string) { + $string = trim($string); + $string = str_replace(array("\n", "\t", "\r"), ' ', $string); + return $string; + } + + /** + * Factory method for creating this class from a string. + * @param $string String construction info + * @return Created AttrDef object corresponding to $string + */ + public function make($string) { + // default implementation, return a flyweight of this object. + // If $string has an effect on the returned object (i.e. you + // need to overload this method), it is best + // to clone or instantiate new copies. (Instantiation is safer.) + return $this; + } + + /** + * Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work + * properly. THIS IS A HACK! + */ + protected function mungeRgb($string) { + return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string); + } + + /** + * Parses a possibly escaped CSS string and returns the "pure" + * version of it. + */ + protected function expandCSSEscape($string) { + // flexibly parse it + $ret = ''; + for ($i = 0, $c = strlen($string); $i < $c; $i++) { + if ($string[$i] === '\\') { + $i++; + if ($i >= $c) { + $ret .= '\\'; + break; + } + if (ctype_xdigit($string[$i])) { + $code = $string[$i]; + for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) { + if (!ctype_xdigit($string[$i])) break; + $code .= $string[$i]; + } + // We have to be extremely careful when adding + // new characters, to make sure we're not breaking + // the encoding. + $char = HTMLPurifier_Encoder::unichr(hexdec($code)); + if (HTMLPurifier_Encoder::cleanUTF8($char) === '') continue; + $ret .= $char; + if ($i < $c && trim($string[$i]) !== '') $i--; + continue; + } + if ($string[$i] === "\n") continue; + } + $ret .= $string[$i]; + } + return $ret; + } + +} + + + + + +/** + * Processes an entire attribute array for corrections needing multiple values. + * + * Occasionally, a certain attribute will need to be removed and popped onto + * another value. Instead of creating a complex return syntax for + * HTMLPurifier_AttrDef, we just pass the whole attribute array to a + * specialized object and have that do the special work. That is the + * family of HTMLPurifier_AttrTransform. + * + * An attribute transformation can be assigned to run before or after + * HTMLPurifier_AttrDef validation. See HTMLPurifier_HTMLDefinition for + * more details. + */ + +abstract class HTMLPurifier_AttrTransform +{ + + /** + * Abstract: makes changes to the attributes dependent on multiple values. + * + * @param $attr Assoc array of attributes, usually from + * HTMLPurifier_Token_Tag::$attr + * @param $config Mandatory HTMLPurifier_Config object. + * @param $context Mandatory HTMLPurifier_Context object + * @returns Processed attribute array. + */ + abstract public function transform($attr, $config, $context); + + /** + * Prepends CSS properties to the style attribute, creating the + * attribute if it doesn't exist. + * @param $attr Attribute array to process (passed by reference) + * @param $css CSS to prepend + */ + public function prependCSS(&$attr, $css) { + $attr['style'] = isset($attr['style']) ? $attr['style'] : ''; + $attr['style'] = $css . $attr['style']; + } + + /** + * Retrieves and removes an attribute + * @param $attr Attribute array to process (passed by reference) + * @param $key Key of attribute to confiscate + */ + public function confiscateAttr(&$attr, $key) { + if (!isset($attr[$key])) return null; + $value = $attr[$key]; + unset($attr[$key]); + return $value; + } + +} + + + + + +/** + * Provides lookup array of attribute types to HTMLPurifier_AttrDef objects + */ +class HTMLPurifier_AttrTypes +{ + /** + * Lookup array of attribute string identifiers to concrete implementations + */ + protected $info = array(); + + /** + * Constructs the info array, supplying default implementations for attribute + * types. + */ + public function __construct() { + // pseudo-types, must be instantiated via shorthand + $this->info['Enum'] = new HTMLPurifier_AttrDef_Enum(); + $this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool(); + + $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text(); + $this->info['ID'] = new HTMLPurifier_AttrDef_HTML_ID(); + $this->info['Length'] = new HTMLPurifier_AttrDef_HTML_Length(); + $this->info['MultiLength'] = new HTMLPurifier_AttrDef_HTML_MultiLength(); + $this->info['NMTOKENS'] = new HTMLPurifier_AttrDef_HTML_Nmtokens(); + $this->info['Pixels'] = new HTMLPurifier_AttrDef_HTML_Pixels(); + $this->info['Text'] = new HTMLPurifier_AttrDef_Text(); + $this->info['URI'] = new HTMLPurifier_AttrDef_URI(); + $this->info['LanguageCode'] = new HTMLPurifier_AttrDef_Lang(); + $this->info['Color'] = new HTMLPurifier_AttrDef_HTML_Color(); + + // unimplemented aliases + $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); + $this->info['ContentTypes'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Charsets'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Character'] = new HTMLPurifier_AttrDef_Text(); + + // "proprietary" types + $this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class(); + + // number is really a positive integer (one or more digits) + // FIXME: ^^ not always, see start and value of list items + $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); + } + + /** + * Retrieves a type + * @param $type String type name + * @return Object AttrDef for type + */ + public function get($type) { + + // determine if there is any extra info tacked on + if (strpos($type, '#') !== false) list($type, $string) = explode('#', $type, 2); + else $string = ''; + + if (!isset($this->info[$type])) { + trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR); + return; + } + + return $this->info[$type]->make($string); + + } + + /** + * Sets a new implementation for a type + * @param $type String type name + * @param $impl Object AttrDef for type + */ + public function set($type, $impl) { + $this->info[$type] = $impl; + } +} + + + + + +/** + * Validates the attributes of a token. Doesn't manage required attributes + * very well. The only reason we factored this out was because RemoveForeignElements + * also needed it besides ValidateAttributes. + */ +class HTMLPurifier_AttrValidator +{ + + /** + * Validates the attributes of a token, returning a modified token + * that has valid tokens + * @param $token Reference to token to validate. We require a reference + * because the operation this class performs on the token are + * not atomic, so the context CurrentToken to be updated + * throughout + * @param $config Instance of HTMLPurifier_Config + * @param $context Instance of HTMLPurifier_Context + */ + public function validateToken(&$token, &$config, $context) { + + $definition = $config->getHTMLDefinition(); + $e =& $context->get('ErrorCollector', true); + + // initialize IDAccumulator if necessary + $ok =& $context->get('IDAccumulator', true); + if (!$ok) { + $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); + $context->register('IDAccumulator', $id_accumulator); + } + + // initialize CurrentToken if necessary + $current_token =& $context->get('CurrentToken', true); + if (!$current_token) $context->register('CurrentToken', $token); + + if ( + !$token instanceof HTMLPurifier_Token_Start && + !$token instanceof HTMLPurifier_Token_Empty + ) return $token; + + // create alias to global definition array, see also $defs + // DEFINITION CALL + $d_defs = $definition->info_global_attr; + + // don't update token until the very end, to ensure an atomic update + $attr = $token->attr; + + // do global transformations (pre) + // nothing currently utilizes this + foreach ($definition->info_attr_transform_pre as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + + // do local transformations only applicable to this element (pre) + // ex.

    to

    + foreach ($definition->info[$token->name]->attr_transform_pre as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + + // create alias to this element's attribute definition array, see + // also $d_defs (global attribute definition array) + // DEFINITION CALL + $defs = $definition->info[$token->name]->attr; + + $attr_key = false; + $context->register('CurrentAttr', $attr_key); + + // iterate through all the attribute keypairs + // Watch out for name collisions: $key has previously been used + foreach ($attr as $attr_key => $value) { + + // call the definition + if ( isset($defs[$attr_key]) ) { + // there is a local definition defined + if ($defs[$attr_key] === false) { + // We've explicitly been told not to allow this element. + // This is usually when there's a global definition + // that must be overridden. + // Theoretically speaking, we could have a + // AttrDef_DenyAll, but this is faster! + $result = false; + } else { + // validate according to the element's definition + $result = $defs[$attr_key]->validate( + $value, $config, $context + ); + } + } elseif ( isset($d_defs[$attr_key]) ) { + // there is a global definition defined, validate according + // to the global definition + $result = $d_defs[$attr_key]->validate( + $value, $config, $context + ); + } else { + // system never heard of the attribute? DELETE! + $result = false; + } + + // put the results into effect + if ($result === false || $result === null) { + // this is a generic error message that should replaced + // with more specific ones when possible + if ($e) $e->send(E_ERROR, 'AttrValidator: Attribute removed'); + + // remove the attribute + unset($attr[$attr_key]); + } elseif (is_string($result)) { + // generally, if a substitution is happening, there + // was some sort of implicit correction going on. We'll + // delegate it to the attribute classes to say exactly what. + + // simple substitution + $attr[$attr_key] = $result; + } else { + // nothing happens + } + + // we'd also want slightly more complicated substitution + // involving an array as the return value, + // although we're not sure how colliding attributes would + // resolve (certain ones would be completely overriden, + // others would prepend themselves). + } + + $context->destroy('CurrentAttr'); + + // post transforms + + // global (error reporting untested) + foreach ($definition->info_attr_transform_post as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + + // local (error reporting untested) + foreach ($definition->info[$token->name]->attr_transform_post as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + + $token->attr = $attr; + + // destroy CurrentToken if we made it ourselves + if (!$current_token) $context->destroy('CurrentToken'); + + } + + +} + + + + + +// constants are slow, so we use as few as possible +if (!defined('HTMLPURIFIER_PREFIX')) { + define('HTMLPURIFIER_PREFIX', dirname(__FILE__) . '/standalone'); + set_include_path(HTMLPURIFIER_PREFIX . PATH_SEPARATOR . get_include_path()); +} + +// accomodations for versions earlier than 5.0.2 +// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister +if (!defined('PHP_EOL')) { + switch (strtoupper(substr(PHP_OS, 0, 3))) { + case 'WIN': + define('PHP_EOL', "\r\n"); + break; + case 'DAR': + define('PHP_EOL', "\r"); + break; + default: + define('PHP_EOL', "\n"); + } +} + +/** + * Bootstrap class that contains meta-functionality for HTML Purifier such as + * the autoload function. + * + * @note + * This class may be used without any other files from HTML Purifier. + */ +class HTMLPurifier_Bootstrap +{ + + /** + * Autoload function for HTML Purifier + * @param $class Class to load + */ + public static function autoload($class) { + $file = HTMLPurifier_Bootstrap::getPath($class); + if (!$file) return false; + require HTMLPURIFIER_PREFIX . '/' . $file; + return true; + } + + /** + * Returns the path for a specific class. + */ + public static function getPath($class) { + if (strncmp('HTMLPurifier', $class, 12) !== 0) return false; + // Custom implementations + if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) { + $code = str_replace('_', '-', substr($class, 22)); + $file = 'HTMLPurifier/Language/classes/' . $code . '.php'; + } else { + $file = str_replace('_', '/', $class) . '.php'; + } + if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) return false; + return $file; + } + + /** + * "Pre-registers" our autoloader on the SPL stack. + */ + public static function registerAutoload() { + $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); + if ( ($funcs = spl_autoload_functions()) === false ) { + spl_autoload_register($autoload); + } elseif (function_exists('spl_autoload_unregister')) { + $compat = version_compare(PHP_VERSION, '5.1.2', '<=') && + version_compare(PHP_VERSION, '5.1.0', '>='); + foreach ($funcs as $func) { + if (is_array($func)) { + // :TRICKY: There are some compatibility issues and some + // places where we need to error out + $reflector = new ReflectionMethod($func[0], $func[1]); + if (!$reflector->isStatic()) { + throw new Exception(' + HTML Purifier autoloader registrar is not compatible + with non-static object methods due to PHP Bug #44144; + Please do not use HTMLPurifier.autoload.php (or any + file that includes this file); instead, place the code: + spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\')) + after your own autoloaders. + '); + } + // Suprisingly, spl_autoload_register supports the + // Class::staticMethod callback format, although call_user_func doesn't + if ($compat) $func = implode('::', $func); + } + spl_autoload_unregister($func); + } + spl_autoload_register($autoload); + foreach ($funcs as $func) spl_autoload_register($func); + } + } + +} + + + + + +/** + * Super-class for definition datatype objects, implements serialization + * functions for the class. + */ +abstract class HTMLPurifier_Definition +{ + + /** + * Has setup() been called yet? + */ + public $setup = false; + + /** + * What type of definition is it? + */ + public $type; + + /** + * Sets up the definition object into the final form, something + * not done by the constructor + * @param $config HTMLPurifier_Config instance + */ + abstract protected function doSetup($config); + + /** + * Setup function that aborts if already setup + * @param $config HTMLPurifier_Config instance + */ + public function setup($config) { + if ($this->setup) return; + $this->setup = true; + $this->doSetup($config); + } + +} + + + + + +/** + * Defines allowed CSS attributes and what their values are. + * @see HTMLPurifier_HTMLDefinition + */ +class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition +{ + + public $type = 'CSS'; + + /** + * Assoc array of attribute name to definition object. + */ + public $info = array(); + + /** + * Constructs the info array. The meat of this class. + */ + protected function doSetup($config) { + + $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( + array('left', 'right', 'center', 'justify'), false); + + $border_style = + $this->info['border-bottom-style'] = + $this->info['border-right-style'] = + $this->info['border-left-style'] = + $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( + array('none', 'hidden', 'dotted', 'dashed', 'solid', 'double', + 'groove', 'ridge', 'inset', 'outset'), false); + + $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); + + $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( + array('none', 'left', 'right', 'both'), false); + $this->info['float'] = new HTMLPurifier_AttrDef_Enum( + array('none', 'left', 'right'), false); + $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( + array('normal', 'italic', 'oblique'), false); + $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( + array('normal', 'small-caps'), false); + + $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('none')), + new HTMLPurifier_AttrDef_CSS_URI() + ) + ); + + $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( + array('inside', 'outside'), false); + $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( + array('disc', 'circle', 'square', 'decimal', 'lower-roman', + 'upper-roman', 'lower-alpha', 'upper-alpha', 'none'), false); + $this->info['list-style-image'] = $uri_or_none; + + $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); + + $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( + array('capitalize', 'uppercase', 'lowercase', 'none'), false); + $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + $this->info['background-image'] = $uri_or_none; + $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( + array('repeat', 'repeat-x', 'repeat-y', 'no-repeat') + ); + $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( + array('scroll', 'fixed') + ); + $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); + + $border_color = + $this->info['border-top-color'] = + $this->info['border-bottom-color'] = + $this->info['border-left-color'] = + $this->info['border-right-color'] = + $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('transparent')), + new HTMLPurifier_AttrDef_CSS_Color() + )); + + $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); + + $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color); + + $border_width = + $this->info['border-top-width'] = + $this->info['border-bottom-width'] = + $this->info['border-left-width'] = + $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), + new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative + )); + + $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); + + $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Length() + )); + + $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Length() + )); + + $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('xx-small', 'x-small', + 'small', 'medium', 'large', 'x-large', 'xx-large', + 'larger', 'smaller')), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + )); + + $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + )); + + $margin = + $this->info['margin-top'] = + $this->info['margin-bottom'] = + $this->info['margin-left'] = + $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(array('auto')) + )); + + $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); + + // non-negative + $padding = + $this->info['padding-top'] = + $this->info['padding-bottom'] = + $this->info['padding-left'] = + $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + )); + + $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); + + $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + )); + + $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + new HTMLPurifier_AttrDef_Enum(array('auto')) + )); + $max = $config->get('CSS.MaxImgLength'); + + $this->info['width'] = + $this->info['height'] = + $max === null ? + $trusted_wh : + new HTMLPurifier_AttrDef_Switch('img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + new HTMLPurifier_AttrDef_Enum(array('auto')) + )), + // For everyone else: + $trusted_wh + ); + + $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); + + $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); + + // this could use specialized code + $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( + array('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', + '400', '500', '600', '700', '800', '900'), false); + + // MUST be called after other font properties, as it references + // a CSSDefinition object + $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config); + + // same here + $this->info['border'] = + $this->info['border-bottom'] = + $this->info['border-top'] = + $this->info['border-left'] = + $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); + + $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(array( + 'collapse', 'separate')); + + $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(array( + 'top', 'bottom')); + + $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(array( + 'auto', 'fixed')); + + $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_Enum(array('baseline', 'sub', 'super', + 'top', 'text-top', 'middle', 'bottom', 'text-bottom')), + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + )); + + $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); + + // partial support + $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap')); + + if ($config->get('CSS.Proprietary')) { + $this->doSetupProprietary($config); + } + + if ($config->get('CSS.AllowTricky')) { + $this->doSetupTricky($config); + } + + $allow_important = $config->get('CSS.AllowImportant'); + // wrap all attr-defs with decorator that handles !important + foreach ($this->info as $k => $v) { + $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important); + } + + $this->setupConfigStuff($config); + } + + protected function doSetupProprietary($config) { + // Internet Explorer only scrollbar colors + $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + // technically not proprietary, but CSS3, and no one supports it + $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + + // only opacity, for now + $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter(); + + } + + protected function doSetupTricky($config) { + $this->info['display'] = new HTMLPurifier_AttrDef_Enum(array( + 'inline', 'block', 'list-item', 'run-in', 'compact', + 'marker', 'table', 'inline-table', 'table-row-group', + 'table-header-group', 'table-footer-group', 'table-row', + 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none' + )); + $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(array( + 'visible', 'hidden', 'collapse' + )); + $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); + } + + + /** + * Performs extra config-based processing. Based off of + * HTMLPurifier_HTMLDefinition. + * @todo Refactor duplicate elements into common class (probably using + * composition, not inheritance). + */ + protected function setupConfigStuff($config) { + + // setup allowed elements + $support = "(for information on implementing this, see the ". + "support forums) "; + $allowed_attributes = $config->get('CSS.AllowedProperties'); + if ($allowed_attributes !== null) { + foreach ($this->info as $name => $d) { + if(!isset($allowed_attributes[$name])) unset($this->info[$name]); + unset($allowed_attributes[$name]); + } + // emit errors + foreach ($allowed_attributes as $name => $d) { + // :TODO: Is this htmlspecialchars() call really necessary? + $name = htmlspecialchars($name); + trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING); + } + } + + } +} + + + + + +/** + * Defines allowed child nodes and validates tokens against it. + */ +abstract class HTMLPurifier_ChildDef +{ + /** + * Type of child definition, usually right-most part of class name lowercase. + * Used occasionally in terms of context. + */ + public $type; + + /** + * Bool that indicates whether or not an empty array of children is okay + * + * This is necessary for redundant checking when changes affecting + * a child node may cause a parent node to now be disallowed. + */ + public $allow_empty; + + /** + * Lookup array of all elements that this definition could possibly allow + */ + public $elements = array(); + + /** + * Get lookup of tag names that should not close this element automatically. + * All other elements will do so. + */ + public function getAllowedElements($config) { + return $this->elements; + } + + /** + * Validates nodes according to definition and returns modification. + * + * @param $tokens_of_children Array of HTMLPurifier_Token + * @param $config HTMLPurifier_Config object + * @param $context HTMLPurifier_Context object + * @return bool true to leave nodes as is + * @return bool false to remove parent node + * @return array of replacement child tokens + */ + abstract public function validateChildren($tokens_of_children, $config, $context); +} + + + + + +/** + * Configuration object that triggers customizable behavior. + * + * @warning This class is strongly defined: that means that the class + * will fail if an undefined directive is retrieved or set. + * + * @note Many classes that could (although many times don't) use the + * configuration object make it a mandatory parameter. This is + * because a configuration object should always be forwarded, + * otherwise, you run the risk of missing a parameter and then + * being stumped when a configuration directive doesn't work. + * + * @todo Reconsider some of the public member variables + */ +class HTMLPurifier_Config +{ + + /** + * HTML Purifier's version + */ + public $version = '4.1.1'; + + /** + * Bool indicator whether or not to automatically finalize + * the object if a read operation is done + */ + public $autoFinalize = true; + + // protected member variables + + /** + * Namespace indexed array of serials for specific namespaces (see + * getSerial() for more info). + */ + protected $serials = array(); + + /** + * Serial for entire configuration object + */ + protected $serial; + + /** + * Parser for variables + */ + protected $parser; + + /** + * Reference HTMLPurifier_ConfigSchema for value checking + * @note This is public for introspective purposes. Please don't + * abuse! + */ + public $def; + + /** + * Indexed array of definitions + */ + protected $definitions; + + /** + * Bool indicator whether or not config is finalized + */ + protected $finalized = false; + + /** + * Property list containing configuration directives. + */ + protected $plist; + + /** + * Whether or not a set is taking place due to an + * alias lookup. + */ + private $aliasMode; + + /** + * Set to false if you do not want line and file numbers in errors + * (useful when unit testing) + */ + public $chatty = true; + + /** + * Current lock; only gets to this namespace are allowed. + */ + private $lock; + + /** + * @param $definition HTMLPurifier_ConfigSchema that defines what directives + * are allowed. + */ + public function __construct($definition, $parent = null) { + $parent = $parent ? $parent : $definition->defaultPlist; + $this->plist = new HTMLPurifier_PropertyList($parent); + $this->def = $definition; // keep a copy around for checking + $this->parser = new HTMLPurifier_VarParser_Flexible(); + } + + /** + * Convenience constructor that creates a config object based on a mixed var + * @param mixed $config Variable that defines the state of the config + * object. Can be: a HTMLPurifier_Config() object, + * an array of directives based on loadArray(), + * or a string filename of an ini file. + * @param HTMLPurifier_ConfigSchema Schema object + * @return Configured HTMLPurifier_Config object + */ + public static function create($config, $schema = null) { + if ($config instanceof HTMLPurifier_Config) { + // pass-through + return $config; + } + if (!$schema) { + $ret = HTMLPurifier_Config::createDefault(); + } else { + $ret = new HTMLPurifier_Config($schema); + } + if (is_string($config)) $ret->loadIni($config); + elseif (is_array($config)) $ret->loadArray($config); + return $ret; + } + + /** + * Creates a new config object that inherits from a previous one. + * @param HTMLPurifier_Config $config Configuration object to inherit + * from. + * @return HTMLPurifier_Config object with $config as its parent. + */ + public static function inherit(HTMLPurifier_Config $config) { + return new HTMLPurifier_Config($config->def, $config->plist); + } + + /** + * Convenience constructor that creates a default configuration object. + * @return Default HTMLPurifier_Config object. + */ + public static function createDefault() { + $definition = HTMLPurifier_ConfigSchema::instance(); + $config = new HTMLPurifier_Config($definition); + return $config; + } + + /** + * Retreives a value from the configuration. + * @param $key String key + */ + public function get($key, $a = null) { + if ($a !== null) { + $this->triggerError("Using deprecated API: use \$config->get('$key.$a') instead", E_USER_WARNING); + $key = "$key.$a"; + } + if (!$this->finalized) $this->autoFinalize(); + if (!isset($this->def->info[$key])) { + // can't add % due to SimpleTest bug + $this->triggerError('Cannot retrieve value of undefined directive ' . htmlspecialchars($key), + E_USER_WARNING); + return; + } + if (isset($this->def->info[$key]->isAlias)) { + $d = $this->def->info[$key]; + $this->triggerError('Cannot get value from aliased directive, use real name ' . $d->key, + E_USER_ERROR); + return; + } + if ($this->lock) { + list($ns) = explode('.', $key); + if ($ns !== $this->lock) { + $this->triggerError('Cannot get value of namespace ' . $ns . ' when lock for ' . $this->lock . ' is active, this probably indicates a Definition setup method is accessing directives that are not within its namespace', E_USER_ERROR); + return; + } + } + return $this->plist->get($key); + } + + /** + * Retreives an array of directives to values from a given namespace + * @param $namespace String namespace + */ + public function getBatch($namespace) { + if (!$this->finalized) $this->autoFinalize(); + $full = $this->getAll(); + if (!isset($full[$namespace])) { + $this->triggerError('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace), + E_USER_WARNING); + return; + } + return $full[$namespace]; + } + + /** + * Returns a md5 signature of a segment of the configuration object + * that uniquely identifies that particular configuration + * @note Revision is handled specially and is removed from the batch + * before processing! + * @param $namespace Namespace to get serial for + */ + public function getBatchSerial($namespace) { + if (empty($this->serials[$namespace])) { + $batch = $this->getBatch($namespace); + unset($batch['DefinitionRev']); + $this->serials[$namespace] = md5(serialize($batch)); + } + return $this->serials[$namespace]; + } + + /** + * Returns a md5 signature for the entire configuration object + * that uniquely identifies that particular configuration + */ + public function getSerial() { + if (empty($this->serial)) { + $this->serial = md5(serialize($this->getAll())); + } + return $this->serial; + } + + /** + * Retrieves all directives, organized by namespace + * @warning This is a pretty inefficient function, avoid if you can + */ + public function getAll() { + if (!$this->finalized) $this->autoFinalize(); + $ret = array(); + foreach ($this->plist->squash() as $name => $value) { + list($ns, $key) = explode('.', $name, 2); + $ret[$ns][$key] = $value; + } + return $ret; + } + + /** + * Sets a value to configuration. + * @param $key String key + * @param $value Mixed value + */ + public function set($key, $value, $a = null) { + if (strpos($key, '.') === false) { + $namespace = $key; + $directive = $value; + $value = $a; + $key = "$key.$directive"; + $this->triggerError("Using deprecated API: use \$config->set('$key', ...) instead", E_USER_NOTICE); + } else { + list($namespace) = explode('.', $key); + } + if ($this->isFinalized('Cannot set directive after finalization')) return; + if (!isset($this->def->info[$key])) { + $this->triggerError('Cannot set undefined directive ' . htmlspecialchars($key) . ' to value', + E_USER_WARNING); + return; + } + $def = $this->def->info[$key]; + + if (isset($def->isAlias)) { + if ($this->aliasMode) { + $this->triggerError('Double-aliases not allowed, please fix '. + 'ConfigSchema bug with' . $key, E_USER_ERROR); + return; + } + $this->aliasMode = true; + $this->set($def->key, $value); + $this->aliasMode = false; + $this->triggerError("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE); + return; + } + + // Raw type might be negative when using the fully optimized form + // of stdclass, which indicates allow_null == true + $rtype = is_int($def) ? $def : $def->type; + if ($rtype < 0) { + $type = -$rtype; + $allow_null = true; + } else { + $type = $rtype; + $allow_null = isset($def->allow_null); + } + + try { + $value = $this->parser->parse($value, $type, $allow_null); + } catch (HTMLPurifier_VarParserException $e) { + $this->triggerError('Value for ' . $key . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING); + return; + } + if (is_string($value) && is_object($def)) { + // resolve value alias if defined + if (isset($def->aliases[$value])) { + $value = $def->aliases[$value]; + } + // check to see if the value is allowed + if (isset($def->allowed) && !isset($def->allowed[$value])) { + $this->triggerError('Value not supported, valid values are: ' . + $this->_listify($def->allowed), E_USER_WARNING); + return; + } + } + $this->plist->set($key, $value); + + // reset definitions if the directives they depend on changed + // this is a very costly process, so it's discouraged + // with finalization + if ($namespace == 'HTML' || $namespace == 'CSS' || $namespace == 'URI') { + $this->definitions[$namespace] = null; + } + + $this->serials[$namespace] = false; + } + + /** + * Convenience function for error reporting + */ + private function _listify($lookup) { + $list = array(); + foreach ($lookup as $name => $b) $list[] = $name; + return implode(', ', $list); + } + + /** + * Retrieves object reference to the HTML definition. + * @param $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + */ + public function getHTMLDefinition($raw = false) { + return $this->getDefinition('HTML', $raw); + } + + /** + * Retrieves object reference to the CSS definition + * @param $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + */ + public function getCSSDefinition($raw = false) { + return $this->getDefinition('CSS', $raw); + } + + /** + * Retrieves a definition + * @param $type Type of definition: HTML, CSS, etc + * @param $raw Whether or not definition should be returned raw + */ + public function getDefinition($type, $raw = false) { + if (!$this->finalized) $this->autoFinalize(); + // temporarily suspend locks, so we can handle recursive definition calls + $lock = $this->lock; + $this->lock = null; + $factory = HTMLPurifier_DefinitionCacheFactory::instance(); + $cache = $factory->create($type, $this); + $this->lock = $lock; + if (!$raw) { + // see if we can quickly supply a definition + if (!empty($this->definitions[$type])) { + if (!$this->definitions[$type]->setup) { + $this->definitions[$type]->setup($this); + $cache->set($this->definitions[$type], $this); + } + return $this->definitions[$type]; + } + // memory check missed, try cache + $this->definitions[$type] = $cache->get($this); + if ($this->definitions[$type]) { + // definition in cache, return it + return $this->definitions[$type]; + } + } elseif ( + !empty($this->definitions[$type]) && + !$this->definitions[$type]->setup + ) { + // raw requested, raw in memory, quick return + return $this->definitions[$type]; + } + // quick checks failed, let's create the object + if ($type == 'HTML') { + $this->definitions[$type] = new HTMLPurifier_HTMLDefinition(); + } elseif ($type == 'CSS') { + $this->definitions[$type] = new HTMLPurifier_CSSDefinition(); + } elseif ($type == 'URI') { + $this->definitions[$type] = new HTMLPurifier_URIDefinition(); + } else { + throw new HTMLPurifier_Exception("Definition of $type type not supported"); + } + // quick abort if raw + if ($raw) { + if (is_null($this->get($type . '.DefinitionID'))) { + // fatally error out if definition ID not set + throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID"); + } + return $this->definitions[$type]; + } + // set it up + $this->lock = $type; + $this->definitions[$type]->setup($this); + $this->lock = null; + // save in cache + $cache->set($this->definitions[$type], $this); + return $this->definitions[$type]; + } + + /** + * Loads configuration values from an array with the following structure: + * Namespace.Directive => Value + * @param $config_array Configuration associative array + */ + public function loadArray($config_array) { + if ($this->isFinalized('Cannot load directives after finalization')) return; + foreach ($config_array as $key => $value) { + $key = str_replace('_', '.', $key); + if (strpos($key, '.') !== false) { + $this->set($key, $value); + } else { + $namespace = $key; + $namespace_values = $value; + foreach ($namespace_values as $directive => $value) { + $this->set($namespace .'.'. $directive, $value); + } + } + } + } + + /** + * Returns a list of array(namespace, directive) for all directives + * that are allowed in a web-form context as per an allowed + * namespaces/directives list. + * @param $allowed List of allowed namespaces/directives + */ + public static function getAllowedDirectivesForForm($allowed, $schema = null) { + if (!$schema) { + $schema = HTMLPurifier_ConfigSchema::instance(); + } + if ($allowed !== true) { + if (is_string($allowed)) $allowed = array($allowed); + $allowed_ns = array(); + $allowed_directives = array(); + $blacklisted_directives = array(); + foreach ($allowed as $ns_or_directive) { + if (strpos($ns_or_directive, '.') !== false) { + // directive + if ($ns_or_directive[0] == '-') { + $blacklisted_directives[substr($ns_or_directive, 1)] = true; + } else { + $allowed_directives[$ns_or_directive] = true; + } + } else { + // namespace + $allowed_ns[$ns_or_directive] = true; + } + } + } + $ret = array(); + foreach ($schema->info as $key => $def) { + list($ns, $directive) = explode('.', $key, 2); + if ($allowed !== true) { + if (isset($blacklisted_directives["$ns.$directive"])) continue; + if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue; + } + if (isset($def->isAlias)) continue; + if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue; + $ret[] = array($ns, $directive); + } + return $ret; + } + + /** + * Loads configuration values from $_GET/$_POST that were posted + * via ConfigForm + * @param $array $_GET or $_POST array to import + * @param $index Index/name that the config variables are in + * @param $allowed List of allowed namespaces/directives + * @param $mq_fix Boolean whether or not to enable magic quotes fix + * @param $schema Instance of HTMLPurifier_ConfigSchema to use, if not global copy + */ + public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema); + $config = HTMLPurifier_Config::create($ret, $schema); + return $config; + } + + /** + * Merges in configuration values from $_GET/$_POST to object. NOT STATIC. + * @note Same parameters as loadArrayFromForm + */ + public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def); + $this->loadArray($ret); + } + + /** + * Prepares an array from a form into something usable for the more + * strict parts of HTMLPurifier_Config + */ + public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) { + if ($index !== false) $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); + $mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); + + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); + $ret = array(); + foreach ($allowed as $key) { + list($ns, $directive) = $key; + $skey = "$ns.$directive"; + if (!empty($array["Null_$skey"])) { + $ret[$ns][$directive] = null; + continue; + } + if (!isset($array[$skey])) continue; + $value = $mq ? stripslashes($array[$skey]) : $array[$skey]; + $ret[$ns][$directive] = $value; + } + return $ret; + } + + /** + * Loads configuration values from an ini file + * @param $filename Name of ini file + */ + public function loadIni($filename) { + if ($this->isFinalized('Cannot load directives after finalization')) return; + $array = parse_ini_file($filename, true); + $this->loadArray($array); + } + + /** + * Checks whether or not the configuration object is finalized. + * @param $error String error message, or false for no error + */ + public function isFinalized($error = false) { + if ($this->finalized && $error) { + $this->triggerError($error, E_USER_ERROR); + } + return $this->finalized; + } + + /** + * Finalizes configuration only if auto finalize is on and not + * already finalized + */ + public function autoFinalize() { + if ($this->autoFinalize) { + $this->finalize(); + } else { + $this->plist->squash(true); + } + } + + /** + * Finalizes a configuration object, prohibiting further change + */ + public function finalize() { + $this->finalized = true; + unset($this->parser); + } + + /** + * Produces a nicely formatted error message by supplying the + * stack frame information from two levels up and OUTSIDE of + * HTMLPurifier_Config. + */ + protected function triggerError($msg, $no) { + // determine previous stack frame + $backtrace = debug_backtrace(); + if ($this->chatty && isset($backtrace[1])) { + $frame = $backtrace[1]; + $extra = " on line {$frame['line']} in file {$frame['file']}"; + } else { + $extra = ''; + } + trigger_error($msg . $extra, $no); + } + + /** + * Returns a serialized form of the configuration object that can + * be reconstituted. + */ + public function serialize() { + $this->getDefinition('HTML'); + $this->getDefinition('CSS'); + $this->getDefinition('URI'); + return serialize($this); + } + +} + + + + + +/** + * Configuration definition, defines directives and their defaults. + */ +class HTMLPurifier_ConfigSchema { + + /** + * Defaults of the directives and namespaces. + * @note This shares the exact same structure as HTMLPurifier_Config::$conf + */ + public $defaults = array(); + + /** + * The default property list. Do not edit this property list. + */ + public $defaultPlist; + + /** + * Definition of the directives. The structure of this is: + * + * array( + * 'Namespace' => array( + * 'Directive' => new stdclass(), + * ) + * ) + * + * The stdclass may have the following properties: + * + * - If isAlias isn't set: + * - type: Integer type of directive, see HTMLPurifier_VarParser for definitions + * - allow_null: If set, this directive allows null values + * - aliases: If set, an associative array of value aliases to real values + * - allowed: If set, a lookup array of allowed (string) values + * - If isAlias is set: + * - namespace: Namespace this directive aliases to + * - name: Directive name this directive aliases to + * + * In certain degenerate cases, stdclass will actually be an integer. In + * that case, the value is equivalent to an stdclass with the type + * property set to the integer. If the integer is negative, type is + * equal to the absolute value of integer, and allow_null is true. + * + * This class is friendly with HTMLPurifier_Config. If you need introspection + * about the schema, you're better of using the ConfigSchema_Interchange, + * which uses more memory but has much richer information. + */ + public $info = array(); + + /** + * Application-wide singleton + */ + static protected $singleton; + + public function __construct() { + $this->defaultPlist = new HTMLPurifier_PropertyList(); + } + + /** + * Unserializes the default ConfigSchema. + */ + public static function makeFromSerial() { + return unserialize(file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser')); + } + + /** + * Retrieves an instance of the application-wide configuration definition. + */ + public static function instance($prototype = null) { + if ($prototype !== null) { + HTMLPurifier_ConfigSchema::$singleton = $prototype; + } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) { + HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial(); + } + return HTMLPurifier_ConfigSchema::$singleton; + } + + /** + * Defines a directive for configuration + * @warning Will fail of directive's namespace is defined. + * @warning This method's signature is slightly different from the legacy + * define() static method! Beware! + * @param $namespace Namespace the directive is in + * @param $name Key of directive + * @param $default Default value of directive + * @param $type Allowed type of the directive. See + * HTMLPurifier_DirectiveDef::$type for allowed values + * @param $allow_null Whether or not to allow null values + */ + public function add($key, $default, $type, $allow_null) { + $obj = new stdclass(); + $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type]; + if ($allow_null) $obj->allow_null = true; + $this->info[$key] = $obj; + $this->defaults[$key] = $default; + $this->defaultPlist->set($key, $default); + } + + /** + * Defines a directive value alias. + * + * Directive value aliases are convenient for developers because it lets + * them set a directive to several values and get the same result. + * @param $namespace Directive's namespace + * @param $name Name of Directive + * @param $aliases Hash of aliased values to the real alias + */ + public function addValueAliases($key, $aliases) { + if (!isset($this->info[$key]->aliases)) { + $this->info[$key]->aliases = array(); + } + foreach ($aliases as $alias => $real) { + $this->info[$key]->aliases[$alias] = $real; + } + } + + /** + * Defines a set of allowed values for a directive. + * @warning This is slightly different from the corresponding static + * method definition. + * @param $namespace Namespace of directive + * @param $name Name of directive + * @param $allowed Lookup array of allowed values + */ + public function addAllowedValues($key, $allowed) { + $this->info[$key]->allowed = $allowed; + } + + /** + * Defines a directive alias for backwards compatibility + * @param $namespace + * @param $name Directive that will be aliased + * @param $new_namespace + * @param $new_name Directive that the alias will be to + */ + public function addAlias($key, $new_key) { + $obj = new stdclass; + $obj->key = $new_key; + $obj->isAlias = true; + $this->info[$key] = $obj; + } + + /** + * Replaces any stdclass that only has the type property with type integer. + */ + public function postProcess() { + foreach ($this->info as $key => $v) { + if (count((array) $v) == 1) { + $this->info[$key] = $v->type; + } elseif (count((array) $v) == 2 && isset($v->allow_null)) { + $this->info[$key] = -$v->type; + } + } + } + +} + + + + + +/** + * @todo Unit test + */ +class HTMLPurifier_ContentSets +{ + + /** + * List of content set strings (pipe seperators) indexed by name. + */ + public $info = array(); + + /** + * List of content set lookups (element => true) indexed by name. + * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets + */ + public $lookup = array(); + + /** + * Synchronized list of defined content sets (keys of info) + */ + protected $keys = array(); + /** + * Synchronized list of defined content values (values of info) + */ + protected $values = array(); + + /** + * Merges in module's content sets, expands identifiers in the content + * sets and populates the keys, values and lookup member variables. + * @param $modules List of HTMLPurifier_HTMLModule + */ + public function __construct($modules) { + if (!is_array($modules)) $modules = array($modules); + // populate content_sets based on module hints + // sorry, no way of overloading + foreach ($modules as $module_i => $module) { + foreach ($module->content_sets as $key => $value) { + $temp = $this->convertToLookup($value); + if (isset($this->lookup[$key])) { + // add it into the existing content set + $this->lookup[$key] = array_merge($this->lookup[$key], $temp); + } else { + $this->lookup[$key] = $temp; + } + } + } + $old_lookup = false; + while ($old_lookup !== $this->lookup) { + $old_lookup = $this->lookup; + foreach ($this->lookup as $i => $set) { + $add = array(); + foreach ($set as $element => $x) { + if (isset($this->lookup[$element])) { + $add += $this->lookup[$element]; + unset($this->lookup[$i][$element]); + } + } + $this->lookup[$i] += $add; + } + } + + foreach ($this->lookup as $key => $lookup) { + $this->info[$key] = implode(' | ', array_keys($lookup)); + } + $this->keys = array_keys($this->info); + $this->values = array_values($this->info); + } + + /** + * Accepts a definition; generates and assigns a ChildDef for it + * @param $def HTMLPurifier_ElementDef reference + * @param $module Module that defined the ElementDef + */ + public function generateChildDef(&$def, $module) { + if (!empty($def->child)) return; // already done! + $content_model = $def->content_model; + if (is_string($content_model)) { + // Assume that $this->keys is alphanumeric + $def->content_model = preg_replace_callback( + '/\b(' . implode('|', $this->keys) . ')\b/', + array($this, 'generateChildDefCallback'), + $content_model + ); + //$def->content_model = str_replace( + // $this->keys, $this->values, $content_model); + } + $def->child = $this->getChildDef($def, $module); + } + + public function generateChildDefCallback($matches) { + return $this->info[$matches[0]]; + } + + /** + * Instantiates a ChildDef based on content_model and content_model_type + * member variables in HTMLPurifier_ElementDef + * @note This will also defer to modules for custom HTMLPurifier_ChildDef + * subclasses that need content set expansion + * @param $def HTMLPurifier_ElementDef to have ChildDef extracted + * @return HTMLPurifier_ChildDef corresponding to ElementDef + */ + public function getChildDef($def, $module) { + $value = $def->content_model; + if (is_object($value)) { + trigger_error( + 'Literal object child definitions should be stored in '. + 'ElementDef->child not ElementDef->content_model', + E_USER_NOTICE + ); + return $value; + } + switch ($def->content_model_type) { + case 'required': + return new HTMLPurifier_ChildDef_Required($value); + case 'optional': + return new HTMLPurifier_ChildDef_Optional($value); + case 'empty': + return new HTMLPurifier_ChildDef_Empty(); + case 'custom': + return new HTMLPurifier_ChildDef_Custom($value); + } + // defer to its module + $return = false; + if ($module->defines_child_def) { // save a func call + $return = $module->getChildDef($def); + } + if ($return !== false) return $return; + // error-out + trigger_error( + 'Could not determine which ChildDef class to instantiate', + E_USER_ERROR + ); + return false; + } + + /** + * Converts a string list of elements separated by pipes into + * a lookup array. + * @param $string List of elements + * @return Lookup array of elements + */ + protected function convertToLookup($string) { + $array = explode('|', str_replace(' ', '', $string)); + $ret = array(); + foreach ($array as $i => $k) { + $ret[$k] = true; + } + return $ret; + } + +} + + + + + +/** + * Registry object that contains information about the current context. + * @warning Is a bit buggy when variables are set to null: it thinks + * they don't exist! So use false instead, please. + * @note Since the variables Context deals with may not be objects, + * references are very important here! Do not remove! + */ +class HTMLPurifier_Context +{ + + /** + * Private array that stores the references. + */ + private $_storage = array(); + + /** + * Registers a variable into the context. + * @param $name String name + * @param $ref Reference to variable to be registered + */ + public function register($name, &$ref) { + if (isset($this->_storage[$name])) { + trigger_error("Name $name produces collision, cannot re-register", + E_USER_ERROR); + return; + } + $this->_storage[$name] =& $ref; + } + + /** + * Retrieves a variable reference from the context. + * @param $name String name + * @param $ignore_error Boolean whether or not to ignore error + */ + public function &get($name, $ignore_error = false) { + if (!isset($this->_storage[$name])) { + if (!$ignore_error) { + trigger_error("Attempted to retrieve non-existent variable $name", + E_USER_ERROR); + } + $var = null; // so we can return by reference + return $var; + } + return $this->_storage[$name]; + } + + /** + * Destorys a variable in the context. + * @param $name String name + */ + public function destroy($name) { + if (!isset($this->_storage[$name])) { + trigger_error("Attempted to destroy non-existent variable $name", + E_USER_ERROR); + return; + } + unset($this->_storage[$name]); + } + + /** + * Checks whether or not the variable exists. + * @param $name String name + */ + public function exists($name) { + return isset($this->_storage[$name]); + } + + /** + * Loads a series of variables from an associative array + * @param $context_array Assoc array of variables to load + */ + public function loadArray($context_array) { + foreach ($context_array as $key => $discard) { + $this->register($key, $context_array[$key]); + } + } + +} + + + + + +/** + * Abstract class representing Definition cache managers that implements + * useful common methods and is a factory. + * @todo Create a separate maintenance file advanced users can use to + * cache their custom HTMLDefinition, which can be loaded + * via a configuration directive + * @todo Implement memcached + */ +abstract class HTMLPurifier_DefinitionCache +{ + + public $type; + + /** + * @param $name Type of definition objects this instance of the + * cache will handle. + */ + public function __construct($type) { + $this->type = $type; + } + + /** + * Generates a unique identifier for a particular configuration + * @param Instance of HTMLPurifier_Config + */ + public function generateKey($config) { + return $config->version . ',' . // possibly replace with function calls + $config->getBatchSerial($this->type) . ',' . + $config->get($this->type . '.DefinitionRev'); + } + + /** + * Tests whether or not a key is old with respect to the configuration's + * version and revision number. + * @param $key Key to test + * @param $config Instance of HTMLPurifier_Config to test against + */ + public function isOld($key, $config) { + if (substr_count($key, ',') < 2) return true; + list($version, $hash, $revision) = explode(',', $key, 3); + $compare = version_compare($version, $config->version); + // version mismatch, is always old + if ($compare != 0) return true; + // versions match, ids match, check revision number + if ( + $hash == $config->getBatchSerial($this->type) && + $revision < $config->get($this->type . '.DefinitionRev') + ) return true; + return false; + } + + /** + * Checks if a definition's type jives with the cache's type + * @note Throws an error on failure + * @param $def Definition object to check + * @return Boolean true if good, false if not + */ + public function checkDefType($def) { + if ($def->type !== $this->type) { + trigger_error("Cannot use definition of type {$def->type} in cache for {$this->type}"); + return false; + } + return true; + } + + /** + * Adds a definition object to the cache + */ + abstract public function add($def, $config); + + /** + * Unconditionally saves a definition object to the cache + */ + abstract public function set($def, $config); + + /** + * Replace an object in the cache + */ + abstract public function replace($def, $config); + + /** + * Retrieves a definition object from the cache + */ + abstract public function get($config); + + /** + * Removes a definition object to the cache + */ + abstract public function remove($config); + + /** + * Clears all objects from cache + */ + abstract public function flush($config); + + /** + * Clears all expired (older version or revision) objects from cache + * @note Be carefuly implementing this method as flush. Flush must + * not interfere with other Definition types, and cleanup() + * should not be repeatedly called by userland code. + */ + abstract public function cleanup($config); + +} + + + + + +/** + * Responsible for creating definition caches. + */ +class HTMLPurifier_DefinitionCacheFactory +{ + + protected $caches = array('Serializer' => array()); + protected $implementations = array(); + protected $decorators = array(); + + /** + * Initialize default decorators + */ + public function setup() { + $this->addDecorator('Cleanup'); + } + + /** + * Retrieves an instance of global definition cache factory. + */ + public static function instance($prototype = null) { + static $instance; + if ($prototype !== null) { + $instance = $prototype; + } elseif ($instance === null || $prototype === true) { + $instance = new HTMLPurifier_DefinitionCacheFactory(); + $instance->setup(); + } + return $instance; + } + + /** + * Registers a new definition cache object + * @param $short Short name of cache object, for reference + * @param $long Full class name of cache object, for construction + */ + public function register($short, $long) { + $this->implementations[$short] = $long; + } + + /** + * Factory method that creates a cache object based on configuration + * @param $name Name of definitions handled by cache + * @param $config Instance of HTMLPurifier_Config + */ + public function create($type, $config) { + $method = $config->get('Cache.DefinitionImpl'); + if ($method === null) { + return new HTMLPurifier_DefinitionCache_Null($type); + } + if (!empty($this->caches[$method][$type])) { + return $this->caches[$method][$type]; + } + if ( + isset($this->implementations[$method]) && + class_exists($class = $this->implementations[$method], false) + ) { + $cache = new $class($type); + } else { + if ($method != 'Serializer') { + trigger_error("Unrecognized DefinitionCache $method, using Serializer instead", E_USER_WARNING); + } + $cache = new HTMLPurifier_DefinitionCache_Serializer($type); + } + foreach ($this->decorators as $decorator) { + $new_cache = $decorator->decorate($cache); + // prevent infinite recursion in PHP 4 + unset($cache); + $cache = $new_cache; + } + $this->caches[$method][$type] = $cache; + return $this->caches[$method][$type]; + } + + /** + * Registers a decorator to add to all new cache objects + * @param + */ + public function addDecorator($decorator) { + if (is_string($decorator)) { + $class = "HTMLPurifier_DefinitionCache_Decorator_$decorator"; + $decorator = new $class; + } + $this->decorators[$decorator->name] = $decorator; + } + +} + + + + + +/** + * Represents a document type, contains information on which modules + * need to be loaded. + * @note This class is inspected by Printer_HTMLDefinition->renderDoctype. + * If structure changes, please update that function. + */ +class HTMLPurifier_Doctype +{ + /** + * Full name of doctype + */ + public $name; + + /** + * List of standard modules (string identifiers or literal objects) + * that this doctype uses + */ + public $modules = array(); + + /** + * List of modules to use for tidying up code + */ + public $tidyModules = array(); + + /** + * Is the language derived from XML (i.e. XHTML)? + */ + public $xml = true; + + /** + * List of aliases for this doctype + */ + public $aliases = array(); + + /** + * Public DTD identifier + */ + public $dtdPublic; + + /** + * System DTD identifier + */ + public $dtdSystem; + + public function __construct($name = null, $xml = true, $modules = array(), + $tidyModules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null + ) { + $this->name = $name; + $this->xml = $xml; + $this->modules = $modules; + $this->tidyModules = $tidyModules; + $this->aliases = $aliases; + $this->dtdPublic = $dtd_public; + $this->dtdSystem = $dtd_system; + } +} + + + + + +class HTMLPurifier_DoctypeRegistry +{ + + /** + * Hash of doctype names to doctype objects + */ + protected $doctypes; + + /** + * Lookup table of aliases to real doctype names + */ + protected $aliases; + + /** + * Registers a doctype to the registry + * @note Accepts a fully-formed doctype object, or the + * parameters for constructing a doctype object + * @param $doctype Name of doctype or literal doctype object + * @param $modules Modules doctype will load + * @param $modules_for_modes Modules doctype will load for certain modes + * @param $aliases Alias names for doctype + * @return Editable registered doctype + */ + public function register($doctype, $xml = true, $modules = array(), + $tidy_modules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null + ) { + if (!is_array($modules)) $modules = array($modules); + if (!is_array($tidy_modules)) $tidy_modules = array($tidy_modules); + if (!is_array($aliases)) $aliases = array($aliases); + if (!is_object($doctype)) { + $doctype = new HTMLPurifier_Doctype( + $doctype, $xml, $modules, $tidy_modules, $aliases, $dtd_public, $dtd_system + ); + } + $this->doctypes[$doctype->name] = $doctype; + $name = $doctype->name; + // hookup aliases + foreach ($doctype->aliases as $alias) { + if (isset($this->doctypes[$alias])) continue; + $this->aliases[$alias] = $name; + } + // remove old aliases + if (isset($this->aliases[$name])) unset($this->aliases[$name]); + return $doctype; + } + + /** + * Retrieves reference to a doctype of a certain name + * @note This function resolves aliases + * @note When possible, use the more fully-featured make() + * @param $doctype Name of doctype + * @return Editable doctype object + */ + public function get($doctype) { + if (isset($this->aliases[$doctype])) $doctype = $this->aliases[$doctype]; + if (!isset($this->doctypes[$doctype])) { + trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR); + $anon = new HTMLPurifier_Doctype($doctype); + return $anon; + } + return $this->doctypes[$doctype]; + } + + /** + * Creates a doctype based on a configuration object, + * will perform initialization on the doctype + * @note Use this function to get a copy of doctype that config + * can hold on to (this is necessary in order to tell + * Generator whether or not the current document is XML + * based or not). + */ + public function make($config) { + return clone $this->get($this->getDoctypeFromConfig($config)); + } + + /** + * Retrieves the doctype from the configuration object + */ + public function getDoctypeFromConfig($config) { + // recommended test + $doctype = $config->get('HTML.Doctype'); + if (!empty($doctype)) return $doctype; + $doctype = $config->get('HTML.CustomDoctype'); + if (!empty($doctype)) return $doctype; + // backwards-compatibility + if ($config->get('HTML.XHTML')) { + $doctype = 'XHTML 1.0'; + } else { + $doctype = 'HTML 4.01'; + } + if ($config->get('HTML.Strict')) { + $doctype .= ' Strict'; + } else { + $doctype .= ' Transitional'; + } + return $doctype; + } + +} + + + + + +/** + * Structure that stores an HTML element definition. Used by + * HTMLPurifier_HTMLDefinition and HTMLPurifier_HTMLModule. + * @note This class is inspected by HTMLPurifier_Printer_HTMLDefinition. + * Please update that class too. + * @warning If you add new properties to this class, you MUST update + * the mergeIn() method. + */ +class HTMLPurifier_ElementDef +{ + + /** + * Does the definition work by itself, or is it created solely + * for the purpose of merging into another definition? + */ + public $standalone = true; + + /** + * Associative array of attribute name to HTMLPurifier_AttrDef + * @note Before being processed by HTMLPurifier_AttrCollections + * when modules are finalized during + * HTMLPurifier_HTMLDefinition->setup(), this array may also + * contain an array at index 0 that indicates which attribute + * collections to load into the full array. It may also + * contain string indentifiers in lieu of HTMLPurifier_AttrDef, + * see HTMLPurifier_AttrTypes on how they are expanded during + * HTMLPurifier_HTMLDefinition->setup() processing. + */ + public $attr = array(); + + /** + * Indexed list of tag's HTMLPurifier_AttrTransform to be done before validation + */ + public $attr_transform_pre = array(); + + /** + * Indexed list of tag's HTMLPurifier_AttrTransform to be done after validation + */ + public $attr_transform_post = array(); + + /** + * HTMLPurifier_ChildDef of this tag. + */ + public $child; + + /** + * Abstract string representation of internal ChildDef rules. See + * HTMLPurifier_ContentSets for how this is parsed and then transformed + * into an HTMLPurifier_ChildDef. + * @warning This is a temporary variable that is not available after + * being processed by HTMLDefinition + */ + public $content_model; + + /** + * Value of $child->type, used to determine which ChildDef to use, + * used in combination with $content_model. + * @warning This must be lowercase + * @warning This is a temporary variable that is not available after + * being processed by HTMLDefinition + */ + public $content_model_type; + + + + /** + * Does the element have a content model (#PCDATA | Inline)*? This + * is important for chameleon ins and del processing in + * HTMLPurifier_ChildDef_Chameleon. Dynamically set: modules don't + * have to worry about this one. + */ + public $descendants_are_inline = false; + + /** + * List of the names of required attributes this element has. Dynamically + * populated by HTMLPurifier_HTMLDefinition::getElement + */ + public $required_attr = array(); + + /** + * Lookup table of tags excluded from all descendants of this tag. + * @note SGML permits exclusions for all descendants, but this is + * not possible with DTDs or XML Schemas. W3C has elected to + * use complicated compositions of content_models to simulate + * exclusion for children, but we go the simpler, SGML-style + * route of flat-out exclusions, which correctly apply to + * all descendants and not just children. Note that the XHTML + * Modularization Abstract Modules are blithely unaware of such + * distinctions. + */ + public $excludes = array(); + + /** + * This tag is explicitly auto-closed by the following tags. + */ + public $autoclose = array(); + + /** + * If a foreign element is found in this element, test if it is + * allowed by this sub-element; if it is, instead of closing the + * current element, place it inside this element. + */ + public $wrap; + + /** + * Whether or not this is a formatting element affected by the + * "Active Formatting Elements" algorithm. + */ + public $formatting; + + /** + * Low-level factory constructor for creating new standalone element defs + */ + public static function create($content_model, $content_model_type, $attr) { + $def = new HTMLPurifier_ElementDef(); + $def->content_model = $content_model; + $def->content_model_type = $content_model_type; + $def->attr = $attr; + return $def; + } + + /** + * Merges the values of another element definition into this one. + * Values from the new element def take precedence if a value is + * not mergeable. + */ + public function mergeIn($def) { + + // later keys takes precedence + foreach($def->attr as $k => $v) { + if ($k === 0) { + // merge in the includes + // sorry, no way to override an include + foreach ($v as $v2) { + $this->attr[0][] = $v2; + } + continue; + } + if ($v === false) { + if (isset($this->attr[$k])) unset($this->attr[$k]); + continue; + } + $this->attr[$k] = $v; + } + $this->_mergeAssocArray($this->attr_transform_pre, $def->attr_transform_pre); + $this->_mergeAssocArray($this->attr_transform_post, $def->attr_transform_post); + $this->_mergeAssocArray($this->excludes, $def->excludes); + + if(!empty($def->content_model)) { + $this->content_model = + str_replace("#SUPER", $this->content_model, $def->content_model); + $this->child = false; + } + if(!empty($def->content_model_type)) { + $this->content_model_type = $def->content_model_type; + $this->child = false; + } + if(!is_null($def->child)) $this->child = $def->child; + if(!is_null($def->formatting)) $this->formatting = $def->formatting; + if($def->descendants_are_inline) $this->descendants_are_inline = $def->descendants_are_inline; + + } + + /** + * Merges one array into another, removes values which equal false + * @param $a1 Array by reference that is merged into + * @param $a2 Array that merges into $a1 + */ + private function _mergeAssocArray(&$a1, $a2) { + foreach ($a2 as $k => $v) { + if ($v === false) { + if (isset($a1[$k])) unset($a1[$k]); + continue; + } + $a1[$k] = $v; + } + } + +} + + + + + +/** + * A UTF-8 specific character encoder that handles cleaning and transforming. + * @note All functions in this class should be static. + */ +class HTMLPurifier_Encoder +{ + + /** + * Constructor throws fatal error if you attempt to instantiate class + */ + private function __construct() { + trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR); + } + + /** + * Error-handler that mutes errors, alternative to shut-up operator. + */ + public static function muteErrorHandler() {} + + /** + * Cleans a UTF-8 string for well-formedness and SGML validity + * + * It will parse according to UTF-8 and return a valid UTF8 string, with + * non-SGML codepoints excluded. + * + * @note Just for reference, the non-SGML code points are 0 to 31 and + * 127 to 159, inclusive. However, we allow code points 9, 10 + * and 13, which are the tab, line feed and carriage return + * respectively. 128 and above the code points map to multibyte + * UTF-8 representations. + * + * @note Fallback code adapted from utf8ToUnicode by Henri Sivonen and + * hsivonen@iki.fi at under the + * LGPL license. Notes on what changed are inside, but in general, + * the original code transformed UTF-8 text into an array of integer + * Unicode codepoints. Understandably, transforming that back to + * a string would be somewhat expensive, so the function was modded to + * directly operate on the string. However, this discourages code + * reuse, and the logic enumerated here would be useful for any + * function that needs to be able to understand UTF-8 characters. + * As of right now, only smart lossless character encoding converters + * would need that, and I'm probably not going to implement them. + * Once again, PHP 6 should solve all our problems. + */ + public static function cleanUTF8($str, $force_php = false) { + + // UTF-8 validity is checked since PHP 4.3.5 + // This is an optimization: if the string is already valid UTF-8, no + // need to do PHP stuff. 99% of the time, this will be the case. + // The regexp matches the XML char production, as well as well as excluding + // non-SGML codepoints U+007F to U+009F + if (preg_match('/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', $str)) { + return $str; + } + + $mState = 0; // cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // cached Unicode character + $mBytes = 1; // cached expected number of octets in the current sequence + + // original code involved an $out that was an array of Unicode + // codepoints. Instead of having to convert back into UTF-8, we've + // decided to directly append valid UTF-8 characters onto a string + // $out once they're done. $char accumulates raw bytes, while $mUcs4 + // turns into the Unicode code point, so there's some redundancy. + + $out = ''; + $char = ''; + + $len = strlen($str); + for($i = 0; $i < $len; $i++) { + $in = ord($str{$i}); + $char .= $str[$i]; // append byte to char + if (0 == $mState) { + // When mState is zero we expect either a US-ASCII character + // or a multi-octet sequence. + if (0 == (0x80 & ($in))) { + // US-ASCII, pass straight through. + if (($in <= 31 || $in == 127) && + !($in == 9 || $in == 13 || $in == 10) // save \r\t\n + ) { + // control characters, remove + } else { + $out .= $char; + } + // reset + $char = ''; + $mBytes = 1; + } elseif (0xC0 == (0xE0 & ($in))) { + // First octet of 2 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } elseif (0xE0 == (0xF0 & ($in))) { + // First octet of 3 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } elseif (0xF0 == (0xF8 & ($in))) { + // First octet of 4 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } elseif (0xF8 == (0xFC & ($in))) { + // First octet of 5 octet sequence. + // + // This is illegal because the encoded codepoint must be + // either: + // (a) not the shortest form or + // (b) outside the Unicode range of 0-0x10FFFF. + // Rather than trying to resynchronize, we will carry on + // until the end of the sequence and let the later error + // handling code catch it. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x03) << 24; + $mState = 4; + $mBytes = 5; + } elseif (0xFC == (0xFE & ($in))) { + // First octet of 6 octet sequence, see comments for 5 + // octet sequence. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 1) << 30; + $mState = 5; + $mBytes = 6; + } else { + // Current octet is neither in the US-ASCII range nor a + // legal first octet of a multi-octet sequence. + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char = ''; + } + } else { + // When mState is non-zero, we expect a continuation of the + // multi-octet sequence + if (0x80 == (0xC0 & ($in))) { + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + + if (0 == --$mState) { + // End of the multi-octet sequence. mUcs4 now contains + // the final Unicode codepoint to be output + + // Check for illegal sequences and codepoints. + + // From Unicode 3.1, non-shortest form is illegal + if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || + ((3 == $mBytes) && ($mUcs4 < 0x0800)) || + ((4 == $mBytes) && ($mUcs4 < 0x10000)) || + (4 < $mBytes) || + // From Unicode 3.2, surrogate characters = illegal + (($mUcs4 & 0xFFFFF800) == 0xD800) || + // Codepoints outside the Unicode range are illegal + ($mUcs4 > 0x10FFFF) + ) { + + } elseif (0xFEFF != $mUcs4 && // omit BOM + // check for valid Char unicode codepoints + ( + 0x9 == $mUcs4 || + 0xA == $mUcs4 || + 0xD == $mUcs4 || + (0x20 <= $mUcs4 && 0x7E >= $mUcs4) || + // 7F-9F is not strictly prohibited by XML, + // but it is non-SGML, and thus we don't allow it + (0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) || + (0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4) + ) + ) { + $out .= $char; + } + // initialize UTF8 cache (reset) + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char = ''; + } + } else { + // ((0xC0 & (*in) != 0x80) && (mState != 0)) + // Incomplete multi-octet sequence. + // used to result in complete fail, but we'll reset + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char =''; + } + } + } + return $out; + } + + /** + * Translates a Unicode codepoint into its corresponding UTF-8 character. + * @note Based on Feyd's function at + * , + * which is in public domain. + * @note While we're going to do code point parsing anyway, a good + * optimization would be to refuse to translate code points that + * are non-SGML characters. However, this could lead to duplication. + * @note This is very similar to the unichr function in + * maintenance/generate-entity-file.php (although this is superior, + * due to its sanity checks). + */ + + // +----------+----------+----------+----------+ + // | 33222222 | 22221111 | 111111 | | + // | 10987654 | 32109876 | 54321098 | 76543210 | bit + // +----------+----------+----------+----------+ + // | | | | 0xxxxxxx | 1 byte 0x00000000..0x0000007F + // | | | 110yyyyy | 10xxxxxx | 2 byte 0x00000080..0x000007FF + // | | 1110zzzz | 10yyyyyy | 10xxxxxx | 3 byte 0x00000800..0x0000FFFF + // | 11110www | 10wwzzzz | 10yyyyyy | 10xxxxxx | 4 byte 0x00010000..0x0010FFFF + // +----------+----------+----------+----------+ + // | 00000000 | 00011111 | 11111111 | 11111111 | Theoretical upper limit of legal scalars: 2097151 (0x001FFFFF) + // | 00000000 | 00010000 | 11111111 | 11111111 | Defined upper limit of legal scalar codes + // +----------+----------+----------+----------+ + + public static function unichr($code) { + if($code > 1114111 or $code < 0 or + ($code >= 55296 and $code <= 57343) ) { + // bits are set outside the "valid" range as defined + // by UNICODE 4.1.0 + return ''; + } + + $x = $y = $z = $w = 0; + if ($code < 128) { + // regular ASCII character + $x = $code; + } else { + // set up bits for UTF-8 + $x = ($code & 63) | 128; + if ($code < 2048) { + $y = (($code & 2047) >> 6) | 192; + } else { + $y = (($code & 4032) >> 6) | 128; + if($code < 65536) { + $z = (($code >> 12) & 15) | 224; + } else { + $z = (($code >> 12) & 63) | 128; + $w = (($code >> 18) & 7) | 240; + } + } + } + // set up the actual character + $ret = ''; + if($w) $ret .= chr($w); + if($z) $ret .= chr($z); + if($y) $ret .= chr($y); + $ret .= chr($x); + + return $ret; + } + + /** + * Converts a string to UTF-8 based on configuration. + */ + public static function convertToUTF8($str, $config, $context) { + $encoding = $config->get('Core.Encoding'); + if ($encoding === 'utf-8') return $str; + static $iconv = null; + if ($iconv === null) $iconv = function_exists('iconv'); + set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler')); + if ($iconv && !$config->get('Test.ForceNoIconv')) { + $str = iconv($encoding, 'utf-8//IGNORE', $str); + if ($str === false) { + // $encoding is not a valid encoding + restore_error_handler(); + trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR); + return ''; + } + // If the string is bjorked by Shift_JIS or a similar encoding + // that doesn't support all of ASCII, convert the naughty + // characters to their true byte-wise ASCII/UTF-8 equivalents. + $str = strtr($str, HTMLPurifier_Encoder::testEncodingSupportsASCII($encoding)); + restore_error_handler(); + return $str; + } elseif ($encoding === 'iso-8859-1') { + $str = utf8_encode($str); + restore_error_handler(); + return $str; + } + trigger_error('Encoding not supported, please install iconv', E_USER_ERROR); + } + + /** + * Converts a string from UTF-8 based on configuration. + * @note Currently, this is a lossy conversion, with unexpressable + * characters being omitted. + */ + public static function convertFromUTF8($str, $config, $context) { + $encoding = $config->get('Core.Encoding'); + if ($encoding === 'utf-8') return $str; + static $iconv = null; + if ($iconv === null) $iconv = function_exists('iconv'); + if ($escape = $config->get('Core.EscapeNonASCIICharacters')) { + $str = HTMLPurifier_Encoder::convertToASCIIDumbLossless($str); + } + set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler')); + if ($iconv && !$config->get('Test.ForceNoIconv')) { + // Undo our previous fix in convertToUTF8, otherwise iconv will barf + $ascii_fix = HTMLPurifier_Encoder::testEncodingSupportsASCII($encoding); + if (!$escape && !empty($ascii_fix)) { + $clear_fix = array(); + foreach ($ascii_fix as $utf8 => $native) $clear_fix[$utf8] = ''; + $str = strtr($str, $clear_fix); + } + $str = strtr($str, array_flip($ascii_fix)); + // Normal stuff + $str = iconv('utf-8', $encoding . '//IGNORE', $str); + restore_error_handler(); + return $str; + } elseif ($encoding === 'iso-8859-1') { + $str = utf8_decode($str); + restore_error_handler(); + return $str; + } + trigger_error('Encoding not supported', E_USER_ERROR); + } + + /** + * Lossless (character-wise) conversion of HTML to ASCII + * @param $str UTF-8 string to be converted to ASCII + * @returns ASCII encoded string with non-ASCII character entity-ized + * @warning Adapted from MediaWiki, claiming fair use: this is a common + * algorithm. If you disagree with this license fudgery, + * implement it yourself. + * @note Uses decimal numeric entities since they are best supported. + * @note This is a DUMB function: it has no concept of keeping + * character entities that the projected character encoding + * can allow. We could possibly implement a smart version + * but that would require it to also know which Unicode + * codepoints the charset supported (not an easy task). + * @note Sort of with cleanUTF8() but it assumes that $str is + * well-formed UTF-8 + */ + public static function convertToASCIIDumbLossless($str) { + $bytesleft = 0; + $result = ''; + $working = 0; + $len = strlen($str); + for( $i = 0; $i < $len; $i++ ) { + $bytevalue = ord( $str[$i] ); + if( $bytevalue <= 0x7F ) { //0xxx xxxx + $result .= chr( $bytevalue ); + $bytesleft = 0; + } elseif( $bytevalue <= 0xBF ) { //10xx xxxx + $working = $working << 6; + $working += ($bytevalue & 0x3F); + $bytesleft--; + if( $bytesleft <= 0 ) { + $result .= "&#" . $working . ";"; + } + } elseif( $bytevalue <= 0xDF ) { //110x xxxx + $working = $bytevalue & 0x1F; + $bytesleft = 1; + } elseif( $bytevalue <= 0xEF ) { //1110 xxxx + $working = $bytevalue & 0x0F; + $bytesleft = 2; + } else { //1111 0xxx + $working = $bytevalue & 0x07; + $bytesleft = 3; + } + } + return $result; + } + + /** + * This expensive function tests whether or not a given character + * encoding supports ASCII. 7/8-bit encodings like Shift_JIS will + * fail this test, and require special processing. Variable width + * encodings shouldn't ever fail. + * + * @param string $encoding Encoding name to test, as per iconv format + * @param bool $bypass Whether or not to bypass the precompiled arrays. + * @return Array of UTF-8 characters to their corresponding ASCII, + * which can be used to "undo" any overzealous iconv action. + */ + public static function testEncodingSupportsASCII($encoding, $bypass = false) { + static $encodings = array(); + if (!$bypass) { + if (isset($encodings[$encoding])) return $encodings[$encoding]; + $lenc = strtolower($encoding); + switch ($lenc) { + case 'shift_jis': + return array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~'); + case 'johab': + return array("\xE2\x82\xA9" => '\\'); + } + if (strpos($lenc, 'iso-8859-') === 0) return array(); + } + $ret = array(); + set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler')); + if (iconv('UTF-8', $encoding, 'a') === false) return false; + for ($i = 0x20; $i <= 0x7E; $i++) { // all printable ASCII chars + $c = chr($i); // UTF-8 char + $r = iconv('UTF-8', "$encoding//IGNORE", $c); // initial conversion + if ( + $r === '' || + // This line is needed for iconv implementations that do not + // omit characters that do not exist in the target character set + ($r === $c && iconv($encoding, 'UTF-8//IGNORE', $r) !== $c) + ) { + // Reverse engineer: what's the UTF-8 equiv of this byte + // sequence? This assumes that there's no variable width + // encoding that doesn't support ASCII. + $ret[iconv($encoding, 'UTF-8//IGNORE', $c)] = $c; + } + } + restore_error_handler(); + $encodings[$encoding] = $ret; + return $ret; + } + + +} + + + + + +/** + * Object that provides entity lookup table from entity name to character + */ +class HTMLPurifier_EntityLookup { + + /** + * Assoc array of entity name to character represented. + */ + public $table; + + /** + * Sets up the entity lookup table from the serialized file contents. + * @note The serialized contents are versioned, but were generated + * using the maintenance script generate_entity_file.php + * @warning This is not in constructor to help enforce the Singleton + */ + public function setup($file = false) { + if (!$file) { + $file = HTMLPURIFIER_PREFIX . '/HTMLPurifier/EntityLookup/entities.ser'; + } + $this->table = unserialize(file_get_contents($file)); + } + + /** + * Retrieves sole instance of the object. + * @param Optional prototype of custom lookup table to overload with. + */ + public static function instance($prototype = false) { + // no references, since PHP doesn't copy unless modified + static $instance = null; + if ($prototype) { + $instance = $prototype; + } elseif (!$instance) { + $instance = new HTMLPurifier_EntityLookup(); + $instance->setup(); + } + return $instance; + } + +} + + + + + +// if want to implement error collecting here, we'll need to use some sort +// of global data (probably trigger_error) because it's impossible to pass +// $config or $context to the callback functions. + +/** + * Handles referencing and derefencing character entities + */ +class HTMLPurifier_EntityParser +{ + + /** + * Reference to entity lookup table. + */ + protected $_entity_lookup; + + /** + * Callback regex string for parsing entities. + */ + protected $_substituteEntitiesRegex = +'/&(?:[#]x([a-fA-F0-9]+)|[#]0*(\d+)|([A-Za-z_:][A-Za-z0-9.\-_:]*));?/'; +// 1. hex 2. dec 3. string (XML style) + + + /** + * Decimal to parsed string conversion table for special entities. + */ + protected $_special_dec2str = + array( + 34 => '"', + 38 => '&', + 39 => "'", + 60 => '<', + 62 => '>' + ); + + /** + * Stripped entity names to decimal conversion table for special entities. + */ + protected $_special_ent2dec = + array( + 'quot' => 34, + 'amp' => 38, + 'lt' => 60, + 'gt' => 62 + ); + + /** + * Substitutes non-special entities with their parsed equivalents. Since + * running this whenever you have parsed character is t3h 5uck, we run + * it before everything else. + * + * @param $string String to have non-special entities parsed. + * @returns Parsed string. + */ + public function substituteNonSpecialEntities($string) { + // it will try to detect missing semicolons, but don't rely on it + return preg_replace_callback( + $this->_substituteEntitiesRegex, + array($this, 'nonSpecialEntityCallback'), + $string + ); + } + + /** + * Callback function for substituteNonSpecialEntities() that does the work. + * + * @param $matches PCRE matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @returns Replacement string. + */ + + protected function nonSpecialEntityCallback($matches) { + // replaces all but big five + $entity = $matches[0]; + $is_num = (@$matches[0][1] === '#'); + if ($is_num) { + $is_hex = (@$entity[2] === 'x'); + $code = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; + + // abort for special characters + if (isset($this->_special_dec2str[$code])) return $entity; + + return HTMLPurifier_Encoder::unichr($code); + } else { + if (isset($this->_special_ent2dec[$matches[3]])) return $entity; + if (!$this->_entity_lookup) { + $this->_entity_lookup = HTMLPurifier_EntityLookup::instance(); + } + if (isset($this->_entity_lookup->table[$matches[3]])) { + return $this->_entity_lookup->table[$matches[3]]; + } else { + return $entity; + } + } + } + + /** + * Substitutes only special entities with their parsed equivalents. + * + * @notice We try to avoid calling this function because otherwise, it + * would have to be called a lot (for every parsed section). + * + * @param $string String to have non-special entities parsed. + * @returns Parsed string. + */ + public function substituteSpecialEntities($string) { + return preg_replace_callback( + $this->_substituteEntitiesRegex, + array($this, 'specialEntityCallback'), + $string); + } + + /** + * Callback function for substituteSpecialEntities() that does the work. + * + * This callback has same syntax as nonSpecialEntityCallback(). + * + * @param $matches PCRE-style matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @returns Replacement string. + */ + protected function specialEntityCallback($matches) { + $entity = $matches[0]; + $is_num = (@$matches[0][1] === '#'); + if ($is_num) { + $is_hex = (@$entity[2] === 'x'); + $int = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; + return isset($this->_special_dec2str[$int]) ? + $this->_special_dec2str[$int] : + $entity; + } else { + return isset($this->_special_ent2dec[$matches[3]]) ? + $this->_special_ent2dec[$matches[3]] : + $entity; + } + } + +} + + + + + +/** + * Error collection class that enables HTML Purifier to report HTML + * problems back to the user + */ +class HTMLPurifier_ErrorCollector +{ + + /** + * Identifiers for the returned error array. These are purposely numeric + * so list() can be used. + */ + const LINENO = 0; + const SEVERITY = 1; + const MESSAGE = 2; + const CHILDREN = 3; + + protected $errors; + protected $_current; + protected $_stacks = array(array()); + protected $locale; + protected $generator; + protected $context; + + protected $lines = array(); + + public function __construct($context) { + $this->locale =& $context->get('Locale'); + $this->context = $context; + $this->_current =& $this->_stacks[0]; + $this->errors =& $this->_stacks[0]; + } + + /** + * Sends an error message to the collector for later use + * @param $severity int Error severity, PHP error style (don't use E_USER_) + * @param $msg string Error message text + * @param $subst1 string First substitution for $msg + * @param $subst2 string ... + */ + public function send($severity, $msg) { + + $args = array(); + if (func_num_args() > 2) { + $args = func_get_args(); + array_shift($args); + unset($args[0]); + } + + $token = $this->context->get('CurrentToken', true); + $line = $token ? $token->line : $this->context->get('CurrentLine', true); + $col = $token ? $token->col : $this->context->get('CurrentCol', true); + $attr = $this->context->get('CurrentAttr', true); + + // perform special substitutions, also add custom parameters + $subst = array(); + if (!is_null($token)) { + $args['CurrentToken'] = $token; + } + if (!is_null($attr)) { + $subst['$CurrentAttr.Name'] = $attr; + if (isset($token->attr[$attr])) $subst['$CurrentAttr.Value'] = $token->attr[$attr]; + } + + if (empty($args)) { + $msg = $this->locale->getMessage($msg); + } else { + $msg = $this->locale->formatMessage($msg, $args); + } + + if (!empty($subst)) $msg = strtr($msg, $subst); + + // (numerically indexed) + $error = array( + self::LINENO => $line, + self::SEVERITY => $severity, + self::MESSAGE => $msg, + self::CHILDREN => array() + ); + $this->_current[] = $error; + + + // NEW CODE BELOW ... + + $struct = null; + // Top-level errors are either: + // TOKEN type, if $value is set appropriately, or + // "syntax" type, if $value is null + $new_struct = new HTMLPurifier_ErrorStruct(); + $new_struct->type = HTMLPurifier_ErrorStruct::TOKEN; + if ($token) $new_struct->value = clone $token; + if (is_int($line) && is_int($col)) { + if (isset($this->lines[$line][$col])) { + $struct = $this->lines[$line][$col]; + } else { + $struct = $this->lines[$line][$col] = $new_struct; + } + // These ksorts may present a performance problem + ksort($this->lines[$line], SORT_NUMERIC); + } else { + if (isset($this->lines[-1])) { + $struct = $this->lines[-1]; + } else { + $struct = $this->lines[-1] = $new_struct; + } + } + ksort($this->lines, SORT_NUMERIC); + + // Now, check if we need to operate on a lower structure + if (!empty($attr)) { + $struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr); + if (!$struct->value) { + $struct->value = array($attr, 'PUT VALUE HERE'); + } + } + if (!empty($cssprop)) { + $struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop); + if (!$struct->value) { + // if we tokenize CSS this might be a little more difficult to do + $struct->value = array($cssprop, 'PUT VALUE HERE'); + } + } + + // Ok, structs are all setup, now time to register the error + $struct->addError($severity, $msg); + } + + /** + * Retrieves raw error data for custom formatter to use + * @param List of arrays in format of array(line of error, + * error severity, error message, + * recursive sub-errors array) + */ + public function getRaw() { + return $this->errors; + } + + /** + * Default HTML formatting implementation for error messages + * @param $config Configuration array, vital for HTML output nature + * @param $errors Errors array to display; used for recursion. + */ + public function getHTMLFormatted($config, $errors = null) { + $ret = array(); + + $this->generator = new HTMLPurifier_Generator($config, $this->context); + if ($errors === null) $errors = $this->errors; + + // 'At line' message needs to be removed + + // generation code for new structure goes here. It needs to be recursive. + foreach ($this->lines as $line => $col_array) { + if ($line == -1) continue; + foreach ($col_array as $col => $struct) { + $this->_renderStruct($ret, $struct, $line, $col); + } + } + if (isset($this->lines[-1])) { + $this->_renderStruct($ret, $this->lines[-1]); + } + + if (empty($errors)) { + return '

    ' . $this->locale->getMessage('ErrorCollector: No errors') . '

    '; + } else { + return '
    • ' . implode('
    • ', $ret) . '
    '; + } + + } + + private function _renderStruct(&$ret, $struct, $line = null, $col = null) { + $stack = array($struct); + $context_stack = array(array()); + while ($current = array_pop($stack)) { + $context = array_pop($context_stack); + foreach ($current->errors as $error) { + list($severity, $msg) = $error; + $string = ''; + $string .= '
    '; + // W3C uses an icon to indicate the severity of the error. + $error = $this->locale->getErrorName($severity); + $string .= "$error "; + if (!is_null($line) && !is_null($col)) { + $string .= "Line $line, Column $col: "; + } else { + $string .= 'End of Document: '; + } + $string .= '' . $this->generator->escape($msg) . ' '; + $string .= '
    '; + // Here, have a marker for the character on the column appropriate. + // Be sure to clip extremely long lines. + //$string .= '
    ';
    +                //$string .= '';
    +                //$string .= '
    '; + $ret[] = $string; + } + foreach ($current->children as $type => $array) { + $context[] = $current; + $stack = array_merge($stack, array_reverse($array, true)); + for ($i = count($array); $i > 0; $i--) { + $context_stack[] = $context; + } + } + } + } + +} + + + + + +/** + * Records errors for particular segments of an HTML document such as tokens, + * attributes or CSS properties. They can contain error structs (which apply + * to components of what they represent), but their main purpose is to hold + * errors applying to whatever struct is being used. + */ +class HTMLPurifier_ErrorStruct +{ + + /** + * Possible values for $children first-key. Note that top-level structures + * are automatically token-level. + */ + const TOKEN = 0; + const ATTR = 1; + const CSSPROP = 2; + + /** + * Type of this struct. + */ + public $type; + + /** + * Value of the struct we are recording errors for. There are various + * values for this: + * - TOKEN: Instance of HTMLPurifier_Token + * - ATTR: array('attr-name', 'value') + * - CSSPROP: array('prop-name', 'value') + */ + public $value; + + /** + * Errors registered for this structure. + */ + public $errors = array(); + + /** + * Child ErrorStructs that are from this structure. For example, a TOKEN + * ErrorStruct would contain ATTR ErrorStructs. This is a multi-dimensional + * array in structure: [TYPE]['identifier'] + */ + public $children = array(); + + public function getChild($type, $id) { + if (!isset($this->children[$type][$id])) { + $this->children[$type][$id] = new HTMLPurifier_ErrorStruct(); + $this->children[$type][$id]->type = $type; + } + return $this->children[$type][$id]; + } + + public function addError($severity, $message) { + $this->errors[] = array($severity, $message); + } + +} + + + + + +/** + * Global exception class for HTML Purifier; any exceptions we throw + * are from here. + */ +class HTMLPurifier_Exception extends Exception +{ + +} + + + + + +/** + * Represents a pre or post processing filter on HTML Purifier's output + * + * Sometimes, a little ad-hoc fixing of HTML has to be done before + * it gets sent through HTML Purifier: you can use filters to acheive + * this effect. For instance, YouTube videos can be preserved using + * this manner. You could have used a decorator for this task, but + * PHP's support for them is not terribly robust, so we're going + * to just loop through the filters. + * + * Filters should be exited first in, last out. If there are three filters, + * named 1, 2 and 3, the order of execution should go 1->preFilter, + * 2->preFilter, 3->preFilter, purify, 3->postFilter, 2->postFilter, + * 1->postFilter. + * + * @note Methods are not declared abstract as it is perfectly legitimate + * for an implementation not to want anything to happen on a step + */ + +class HTMLPurifier_Filter +{ + + /** + * Name of the filter for identification purposes + */ + public $name; + + /** + * Pre-processor function, handles HTML before HTML Purifier + */ + public function preFilter($html, $config, $context) { + return $html; + } + + /** + * Post-processor function, handles HTML after HTML Purifier + */ + public function postFilter($html, $config, $context) { + return $html; + } + +} + + + + + +/** + * Generates HTML from tokens. + * @todo Refactor interface so that configuration/context is determined + * upon instantiation, no need for messy generateFromTokens() calls + * @todo Make some of the more internal functions protected, and have + * unit tests work around that + */ +class HTMLPurifier_Generator +{ + + /** + * Whether or not generator should produce XML output + */ + private $_xhtml = true; + + /** + * :HACK: Whether or not generator should comment the insides of )#si', + array($this, 'scriptCallback'), $html); + } + + $html = $this->normalize($html, $config, $context); + + $cursor = 0; // our location in the text + $inside_tag = false; // whether or not we're parsing the inside of a tag + $array = array(); // result array + + // This is also treated to mean maintain *column* numbers too + $maintain_line_numbers = $config->get('Core.MaintainLineNumbers'); + + if ($maintain_line_numbers === null) { + // automatically determine line numbering by checking + // if error collection is on + $maintain_line_numbers = $config->get('Core.CollectErrors'); + } + + if ($maintain_line_numbers) { + $current_line = 1; + $current_col = 0; + $length = strlen($html); + } else { + $current_line = false; + $current_col = false; + $length = false; + } + $context->register('CurrentLine', $current_line); + $context->register('CurrentCol', $current_col); + $nl = "\n"; + // how often to manually recalculate. This will ALWAYS be right, + // but it's pretty wasteful. Set to 0 to turn off + $synchronize_interval = $config->get('Core.DirectLexLineNumberSyncInterval'); + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + // for testing synchronization + $loops = 0; + + while(++$loops) { + + // $cursor is either at the start of a token, or inside of + // a tag (i.e. there was a < immediately before it), as indicated + // by $inside_tag + + if ($maintain_line_numbers) { + + // $rcursor, however, is always at the start of a token. + $rcursor = $cursor - (int) $inside_tag; + + // Column number is cheap, so we calculate it every round. + // We're interested at the *end* of the newline string, so + // we need to add strlen($nl) == 1 to $nl_pos before subtracting it + // from our "rcursor" position. + $nl_pos = strrpos($html, $nl, $rcursor - $length); + $current_col = $rcursor - (is_bool($nl_pos) ? 0 : $nl_pos + 1); + + // recalculate lines + if ( + $synchronize_interval && // synchronization is on + $cursor > 0 && // cursor is further than zero + $loops % $synchronize_interval === 0 // time to synchronize! + ) { + $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor); + } + + } + + $position_next_lt = strpos($html, '<', $cursor); + $position_next_gt = strpos($html, '>', $cursor); + + // triggers on "asdf" but not "asdf " + // special case to set up context + if ($position_next_lt === $cursor) { + $inside_tag = true; + $cursor++; + } + + if (!$inside_tag && $position_next_lt !== false) { + // We are not inside tag and there still is another tag to parse + $token = new + HTMLPurifier_Token_Text( + $this->parseData( + substr( + $html, $cursor, $position_next_lt - $cursor + ) + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor); + } + $array[] = $token; + $cursor = $position_next_lt + 1; + $inside_tag = true; + continue; + } elseif (!$inside_tag) { + // We are not inside tag but there are no more tags + // If we're already at the end, break + if ($cursor === strlen($html)) break; + // Create Text of rest of string + $token = new + HTMLPurifier_Token_Text( + $this->parseData( + substr( + $html, $cursor + ) + ) + ); + if ($maintain_line_numbers) $token->rawPosition($current_line, $current_col); + $array[] = $token; + break; + } elseif ($inside_tag && $position_next_gt !== false) { + // We are in tag and it is well formed + // Grab the internals of the tag + $strlen_segment = $position_next_gt - $cursor; + + if ($strlen_segment < 1) { + // there's nothing to process! + $token = new HTMLPurifier_Token_Text('<'); + $cursor++; + continue; + } + + $segment = substr($html, $cursor, $strlen_segment); + + if ($segment === false) { + // somehow, we attempted to access beyond the end of + // the string, defense-in-depth, reported by Nate Abele + break; + } + + // Check if it's a comment + if ( + substr($segment, 0, 3) === '!--' + ) { + // re-determine segment length, looking for --> + $position_comment_end = strpos($html, '-->', $cursor); + if ($position_comment_end === false) { + // uh oh, we have a comment that extends to + // infinity. Can't be helped: set comment + // end position to end of string + if ($e) $e->send(E_WARNING, 'Lexer: Unclosed comment'); + $position_comment_end = strlen($html); + $end = true; + } else { + $end = false; + } + $strlen_segment = $position_comment_end - $cursor; + $segment = substr($html, $cursor, $strlen_segment); + $token = new + HTMLPurifier_Token_Comment( + substr( + $segment, 3, $strlen_segment - 3 + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment); + } + $array[] = $token; + $cursor = $end ? $position_comment_end : $position_comment_end + 3; + $inside_tag = false; + continue; + } + + // Check if it's an end tag + $is_end_tag = (strpos($segment,'/') === 0); + if ($is_end_tag) { + $type = substr($segment, 1); + $token = new HTMLPurifier_Token_End($type); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + $cursor = $position_next_gt + 1; + continue; + } + + // Check leading character is alnum, if not, we may + // have accidently grabbed an emoticon. Translate into + // text and go our merry way + if (!ctype_alpha($segment[0])) { + // XML: $segment[0] !== '_' && $segment[0] !== ':' + if ($e) $e->send(E_NOTICE, 'Lexer: Unescaped lt'); + $token = new HTMLPurifier_Token_Text('<'); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + continue; + } + + // Check if it is explicitly self closing, if so, remove + // trailing slash. Remember, we could have a tag like
    , so + // any later token processing scripts must convert improperly + // classified EmptyTags from StartTags. + $is_self_closing = (strrpos($segment,'/') === $strlen_segment-1); + if ($is_self_closing) { + $strlen_segment--; + $segment = substr($segment, 0, $strlen_segment); + } + + // Check if there are any attributes + $position_first_space = strcspn($segment, $this->_whitespace); + + if ($position_first_space >= $strlen_segment) { + if ($is_self_closing) { + $token = new HTMLPurifier_Token_Empty($segment); + } else { + $token = new HTMLPurifier_Token_Start($segment); + } + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + $cursor = $position_next_gt + 1; + continue; + } + + // Grab out all the data + $type = substr($segment, 0, $position_first_space); + $attribute_string = + trim( + substr( + $segment, $position_first_space + ) + ); + if ($attribute_string) { + $attr = $this->parseAttributeString( + $attribute_string + , $config, $context + ); + } else { + $attr = array(); + } + + if ($is_self_closing) { + $token = new HTMLPurifier_Token_Empty($type, $attr); + } else { + $token = new HTMLPurifier_Token_Start($type, $attr); + } + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $cursor = $position_next_gt + 1; + $inside_tag = false; + continue; + } else { + // inside tag, but there's no ending > sign + if ($e) $e->send(E_WARNING, 'Lexer: Missing gt'); + $token = new + HTMLPurifier_Token_Text( + '<' . + $this->parseData( + substr($html, $cursor) + ) + ); + if ($maintain_line_numbers) $token->rawPosition($current_line, $current_col); + // no cursor scroll? Hmm... + $array[] = $token; + break; + } + break; + } + + $context->destroy('CurrentLine'); + $context->destroy('CurrentCol'); + return $array; + } + + /** + * PHP 5.0.x compatible substr_count that implements offset and length + */ + protected function substrCount($haystack, $needle, $offset, $length) { + static $oldVersion; + if ($oldVersion === null) { + $oldVersion = version_compare(PHP_VERSION, '5.1', '<'); + } + if ($oldVersion) { + $haystack = substr($haystack, $offset, $length); + return substr_count($haystack, $needle); + } else { + return substr_count($haystack, $needle, $offset, $length); + } + } + + /** + * Takes the inside of an HTML tag and makes an assoc array of attributes. + * + * @param $string Inside of tag excluding name. + * @returns Assoc array of attributes. + */ + public function parseAttributeString($string, $config, $context) { + $string = (string) $string; // quick typecast + + if ($string == '') return array(); // no attributes + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + // let's see if we can abort as quickly as possible + // one equal sign, no spaces => one attribute + $num_equal = substr_count($string, '='); + $has_space = strpos($string, ' '); + if ($num_equal === 0 && !$has_space) { + // bool attribute + return array($string => $string); + } elseif ($num_equal === 1 && !$has_space) { + // only one attribute + list($key, $quoted_value) = explode('=', $string); + $quoted_value = trim($quoted_value); + if (!$key) { + if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); + return array(); + } + if (!$quoted_value) return array($key => ''); + $first_char = @$quoted_value[0]; + $last_char = @$quoted_value[strlen($quoted_value)-1]; + + $same_quote = ($first_char == $last_char); + $open_quote = ($first_char == '"' || $first_char == "'"); + + if ( $same_quote && $open_quote) { + // well behaved + $value = substr($quoted_value, 1, strlen($quoted_value) - 2); + } else { + // not well behaved + if ($open_quote) { + if ($e) $e->send(E_ERROR, 'Lexer: Missing end quote'); + $value = substr($quoted_value, 1); + } else { + $value = $quoted_value; + } + } + if ($value === false) $value = ''; + return array($key => $this->parseData($value)); + } + + // setup loop environment + $array = array(); // return assoc array of attributes + $cursor = 0; // current position in string (moves forward) + $size = strlen($string); // size of the string (stays the same) + + // if we have unquoted attributes, the parser expects a terminating + // space, so let's guarantee that there's always a terminating space. + $string .= ' '; + + while(true) { + + if ($cursor >= $size) { + break; + } + + $cursor += ($value = strspn($string, $this->_whitespace, $cursor)); + // grab the key + + $key_begin = $cursor; //we're currently at the start of the key + + // scroll past all characters that are the key (not whitespace or =) + $cursor += strcspn($string, $this->_whitespace . '=', $cursor); + + $key_end = $cursor; // now at the end of the key + + $key = substr($string, $key_begin, $key_end - $key_begin); + + if (!$key) { + if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); + $cursor += strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop + continue; // empty key + } + + // scroll past all whitespace + $cursor += strspn($string, $this->_whitespace, $cursor); + + if ($cursor >= $size) { + $array[$key] = $key; + break; + } + + // if the next character is an equal sign, we've got a regular + // pair, otherwise, it's a bool attribute + $first_char = @$string[$cursor]; + + if ($first_char == '=') { + // key="value" + + $cursor++; + $cursor += strspn($string, $this->_whitespace, $cursor); + + if ($cursor === false) { + $array[$key] = ''; + break; + } + + // we might be in front of a quote right now + + $char = @$string[$cursor]; + + if ($char == '"' || $char == "'") { + // it's quoted, end bound is $char + $cursor++; + $value_begin = $cursor; + $cursor = strpos($string, $char, $cursor); + $value_end = $cursor; + } else { + // it's not quoted, end bound is whitespace + $value_begin = $cursor; + $cursor += strcspn($string, $this->_whitespace, $cursor); + $value_end = $cursor; + } + + // we reached a premature end + if ($cursor === false) { + $cursor = $size; + $value_end = $cursor; + } + + $value = substr($string, $value_begin, $value_end - $value_begin); + if ($value === false) $value = ''; + $array[$key] = $this->parseData($value); + $cursor++; + + } else { + // boolattr + if ($key !== '') { + $array[$key] = $key; + } else { + // purely theoretical + if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + + } + } + return $array; + } + +} + + + + + +/** + * Composite strategy that runs multiple strategies on tokens. + */ +abstract class HTMLPurifier_Strategy_Composite extends HTMLPurifier_Strategy +{ + + /** + * List of strategies to run tokens through. + */ + protected $strategies = array(); + + abstract public function __construct(); + + public function execute($tokens, $config, $context) { + foreach ($this->strategies as $strategy) { + $tokens = $strategy->execute($tokens, $config, $context); + } + return $tokens; + } + +} + + + + + +/** + * Core strategy composed of the big four strategies. + */ +class HTMLPurifier_Strategy_Core extends HTMLPurifier_Strategy_Composite +{ + + public function __construct() { + $this->strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements(); + $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed(); + $this->strategies[] = new HTMLPurifier_Strategy_FixNesting(); + $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes(); + } + +} + + + + + +/** + * Takes a well formed list of tokens and fixes their nesting. + * + * HTML elements dictate which elements are allowed to be their children, + * for example, you can't have a p tag in a span tag. Other elements have + * much more rigorous definitions: tables, for instance, require a specific + * order for their elements. There are also constraints not expressible by + * document type definitions, such as the chameleon nature of ins/del + * tags and global child exclusions. + * + * The first major objective of this strategy is to iterate through all the + * nodes (not tokens) of the list of tokens and determine whether or not + * their children conform to the element's definition. If they do not, the + * child definition may optionally supply an amended list of elements that + * is valid or require that the entire node be deleted (and the previous + * node rescanned). + * + * The second objective is to ensure that explicitly excluded elements of + * an element do not appear in its children. Code that accomplishes this + * task is pervasive through the strategy, though the two are distinct tasks + * and could, theoretically, be seperated (although it's not recommended). + * + * @note Whether or not unrecognized children are silently dropped or + * translated into text depends on the child definitions. + * + * @todo Enable nodes to be bubbled out of the structure. + */ + +class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy +{ + + public function execute($tokens, $config, $context) { + //####################################################################// + // Pre-processing + + // get a copy of the HTML definition + $definition = $config->getHTMLDefinition(); + + // insert implicit "parent" node, will be removed at end. + // DEFINITION CALL + $parent_name = $definition->info_parent; + array_unshift($tokens, new HTMLPurifier_Token_Start($parent_name)); + $tokens[] = new HTMLPurifier_Token_End($parent_name); + + // setup the context variable 'IsInline', for chameleon processing + // is 'false' when we are not inline, 'true' when it must always + // be inline, and an integer when it is inline for a certain + // branch of the document tree + $is_inline = $definition->info_parent_def->descendants_are_inline; + $context->register('IsInline', $is_inline); + + // setup error collector + $e =& $context->get('ErrorCollector', true); + + //####################################################################// + // Loop initialization + + // stack that contains the indexes of all parents, + // $stack[count($stack)-1] being the current parent + $stack = array(); + + // stack that contains all elements that are excluded + // it is organized by parent elements, similar to $stack, + // but it is only populated when an element with exclusions is + // processed, i.e. there won't be empty exclusions. + $exclude_stack = array(); + + // variable that contains the start token while we are processing + // nodes. This enables error reporting to do its job + $start_token = false; + $context->register('CurrentToken', $start_token); + + //####################################################################// + // Loop + + // iterate through all start nodes. Determining the start node + // is complicated so it has been omitted from the loop construct + for ($i = 0, $size = count($tokens) ; $i < $size; ) { + + //################################################################// + // Gather information on children + + // child token accumulator + $child_tokens = array(); + + // scroll to the end of this node, report number, and collect + // all children + for ($j = $i, $depth = 0; ; $j++) { + if ($tokens[$j] instanceof HTMLPurifier_Token_Start) { + $depth++; + // skip token assignment on first iteration, this is the + // token we currently are on + if ($depth == 1) continue; + } elseif ($tokens[$j] instanceof HTMLPurifier_Token_End) { + $depth--; + // skip token assignment on last iteration, this is the + // end token of the token we're currently on + if ($depth == 0) break; + } + $child_tokens[] = $tokens[$j]; + } + + // $i is index of start token + // $j is index of end token + + $start_token = $tokens[$i]; // to make token available via CurrentToken + + //################################################################// + // Gather information on parent + + // calculate parent information + if ($count = count($stack)) { + $parent_index = $stack[$count-1]; + $parent_name = $tokens[$parent_index]->name; + if ($parent_index == 0) { + $parent_def = $definition->info_parent_def; + } else { + $parent_def = $definition->info[$parent_name]; + } + } else { + // processing as if the parent were the "root" node + // unknown info, it won't be used anyway, in the future, + // we may want to enforce one element only (this is + // necessary for HTML Purifier to clean entire documents + $parent_index = $parent_name = $parent_def = null; + } + + // calculate context + if ($is_inline === false) { + // check if conditions make it inline + if (!empty($parent_def) && $parent_def->descendants_are_inline) { + $is_inline = $count - 1; + } + } else { + // check if we're out of inline + if ($count === $is_inline) { + $is_inline = false; + } + } + + //################################################################// + // Determine whether element is explicitly excluded SGML-style + + // determine whether or not element is excluded by checking all + // parent exclusions. The array should not be very large, two + // elements at most. + $excluded = false; + if (!empty($exclude_stack)) { + foreach ($exclude_stack as $lookup) { + if (isset($lookup[$tokens[$i]->name])) { + $excluded = true; + // no need to continue processing + break; + } + } + } + + //################################################################// + // Perform child validation + + if ($excluded) { + // there is an exclusion, remove the entire node + $result = false; + $excludes = array(); // not used, but good to initialize anyway + } else { + // DEFINITION CALL + if ($i === 0) { + // special processing for the first node + $def = $definition->info_parent_def; + } else { + $def = $definition->info[$tokens[$i]->name]; + + } + + if (!empty($def->child)) { + // have DTD child def validate children + $result = $def->child->validateChildren( + $child_tokens, $config, $context); + } else { + // weird, no child definition, get rid of everything + $result = false; + } + + // determine whether or not this element has any exclusions + $excludes = $def->excludes; + } + + // $result is now a bool or array + + //################################################################// + // Process result by interpreting $result + + if ($result === true || $child_tokens === $result) { + // leave the node as is + + // register start token as a parental node start + $stack[] = $i; + + // register exclusions if there are any + if (!empty($excludes)) $exclude_stack[] = $excludes; + + // move cursor to next possible start node + $i++; + + } elseif($result === false) { + // remove entire node + + if ($e) { + if ($excluded) { + $e->send(E_ERROR, 'Strategy_FixNesting: Node excluded'); + } else { + $e->send(E_ERROR, 'Strategy_FixNesting: Node removed'); + } + } + + // calculate length of inner tokens and current tokens + $length = $j - $i + 1; + + // perform removal + array_splice($tokens, $i, $length); + + // update size + $size -= $length; + + // there is no start token to register, + // current node is now the next possible start node + // unless it turns out that we need to do a double-check + + // this is a rought heuristic that covers 100% of HTML's + // cases and 99% of all other cases. A child definition + // that would be tricked by this would be something like: + // ( | a b c) where it's all or nothing. Fortunately, + // our current implementation claims that that case would + // not allow empty, even if it did + if (!$parent_def->child->allow_empty) { + // we need to do a double-check + $i = $parent_index; + array_pop($stack); + } + + // PROJECTED OPTIMIZATION: Process all children elements before + // reprocessing parent node. + + } else { + // replace node with $result + + // calculate length of inner tokens + $length = $j - $i - 1; + + if ($e) { + if (empty($result) && $length) { + $e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed'); + } else { + $e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized'); + } + } + + // perform replacement + array_splice($tokens, $i + 1, $length, $result); + + // update size + $size -= $length; + $size += count($result); + + // register start token as a parental node start + $stack[] = $i; + + // register exclusions if there are any + if (!empty($excludes)) $exclude_stack[] = $excludes; + + // move cursor to next possible start node + $i++; + + } + + //################################################################// + // Scroll to next start node + + // We assume, at this point, that $i is the index of the token + // that is the first possible new start point for a node. + + // Test if the token indeed is a start tag, if not, move forward + // and test again. + $size = count($tokens); + while ($i < $size and !$tokens[$i] instanceof HTMLPurifier_Token_Start) { + if ($tokens[$i] instanceof HTMLPurifier_Token_End) { + // pop a token index off the stack if we ended a node + array_pop($stack); + // pop an exclusion lookup off exclusion stack if + // we ended node and that node had exclusions + if ($i == 0 || $i == $size - 1) { + // use specialized var if it's the super-parent + $s_excludes = $definition->info_parent_def->excludes; + } else { + $s_excludes = $definition->info[$tokens[$i]->name]->excludes; + } + if ($s_excludes) { + array_pop($exclude_stack); + } + } + $i++; + } + + } + + //####################################################################// + // Post-processing + + // remove implicit parent tokens at the beginning and end + array_shift($tokens); + array_pop($tokens); + + // remove context variables + $context->destroy('IsInline'); + $context->destroy('CurrentToken'); + + //####################################################################// + // Return + + return $tokens; + + } + +} + + + + + +/** + * Takes tokens makes them well-formed (balance end tags, etc.) + */ +class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy +{ + + /** + * Array stream of tokens being processed. + */ + protected $tokens; + + /** + * Current index in $tokens. + */ + protected $t; + + /** + * Current nesting of elements. + */ + protected $stack; + + /** + * Injectors active in this stream processing. + */ + protected $injectors; + + /** + * Current instance of HTMLPurifier_Config. + */ + protected $config; + + /** + * Current instance of HTMLPurifier_Context. + */ + protected $context; + + public function execute($tokens, $config, $context) { + + $definition = $config->getHTMLDefinition(); + + // local variables + $generator = new HTMLPurifier_Generator($config, $context); + $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); + $e = $context->get('ErrorCollector', true); + $t = false; // token index + $i = false; // injector index + $token = false; // the current token + $reprocess = false; // whether or not to reprocess the same token + $stack = array(); + + // member variables + $this->stack =& $stack; + $this->t =& $t; + $this->tokens =& $tokens; + $this->config = $config; + $this->context = $context; + + // context variables + $context->register('CurrentNesting', $stack); + $context->register('InputIndex', $t); + $context->register('InputTokens', $tokens); + $context->register('CurrentToken', $token); + + // -- begin INJECTOR -- + + $this->injectors = array(); + + $injectors = $config->getBatch('AutoFormat'); + $def_injectors = $definition->info_injector; + $custom_injectors = $injectors['Custom']; + unset($injectors['Custom']); // special case + foreach ($injectors as $injector => $b) { + // XXX: Fix with a legitimate lookup table of enabled filters + if (strpos($injector, '.') !== false) continue; + $injector = "HTMLPurifier_Injector_$injector"; + if (!$b) continue; + $this->injectors[] = new $injector; + } + foreach ($def_injectors as $injector) { + // assumed to be objects + $this->injectors[] = $injector; + } + foreach ($custom_injectors as $injector) { + if (!$injector) continue; + if (is_string($injector)) { + $injector = "HTMLPurifier_Injector_$injector"; + $injector = new $injector; + } + $this->injectors[] = $injector; + } + + // give the injectors references to the definition and context + // variables for performance reasons + foreach ($this->injectors as $ix => $injector) { + $error = $injector->prepare($config, $context); + if (!$error) continue; + array_splice($this->injectors, $ix, 1); // rm the injector + trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING); + } + + // -- end INJECTOR -- + + // a note on punting: + // In order to reduce code duplication, whenever some code needs + // to make HTML changes in order to make things "correct", the + // new HTML gets sent through the purifier, regardless of its + // status. This means that if we add a start token, because it + // was totally necessary, we don't have to update nesting; we just + // punt ($reprocess = true; continue;) and it does that for us. + + // isset is in loop because $tokens size changes during loop exec + for ( + $t = 0; + $t == 0 || isset($tokens[$t - 1]); + // only increment if we don't need to reprocess + $reprocess ? $reprocess = false : $t++ + ) { + + // check for a rewind + if (is_int($i) && $i >= 0) { + // possibility: disable rewinding if the current token has a + // rewind set on it already. This would offer protection from + // infinite loop, but might hinder some advanced rewinding. + $rewind_to = $this->injectors[$i]->getRewind(); + if (is_int($rewind_to) && $rewind_to < $t) { + if ($rewind_to < 0) $rewind_to = 0; + while ($t > $rewind_to) { + $t--; + $prev = $tokens[$t]; + // indicate that other injectors should not process this token, + // but we need to reprocess it + unset($prev->skip[$i]); + $prev->rewind = $i; + if ($prev instanceof HTMLPurifier_Token_Start) array_pop($this->stack); + elseif ($prev instanceof HTMLPurifier_Token_End) $this->stack[] = $prev->start; + } + } + $i = false; + } + + // handle case of document end + if (!isset($tokens[$t])) { + // kill processing if stack is empty + if (empty($this->stack)) break; + + // peek + $top_nesting = array_pop($this->stack); + $this->stack[] = $top_nesting; + + // send error + if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting); + } + + // append, don't splice, since this is the end + $tokens[] = new HTMLPurifier_Token_End($top_nesting->name); + + // punt! + $reprocess = true; + continue; + } + + $token = $tokens[$t]; + + //echo '
    '; printTokens($tokens, $t); printTokens($this->stack); + //flush(); + + // quick-check: if it's not a tag, no need to process + if (empty($token->is_tag)) { + if ($token instanceof HTMLPurifier_Token_Text) { + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) continue; + if ($token->rewind !== null && $token->rewind !== $i) continue; + $injector->handleText($token); + $this->processToken($token, $i); + $reprocess = true; + break; + } + } + // another possibility is a comment + continue; + } + + if (isset($definition->info[$token->name])) { + $type = $definition->info[$token->name]->child->type; + } else { + $type = false; // Type is unknown, treat accordingly + } + + // quick tag checks: anything that's *not* an end tag + $ok = false; + if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) { + // claims to be a start tag but is empty + $token = new HTMLPurifier_Token_Empty($token->name, $token->attr); + $ok = true; + } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) { + // claims to be empty but really is a start tag + $this->swap(new HTMLPurifier_Token_End($token->name)); + $this->insertBefore(new HTMLPurifier_Token_Start($token->name, $token->attr)); + // punt (since we had to modify the input stream in a non-trivial way) + $reprocess = true; + continue; + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + // real empty token + $ok = true; + } elseif ($token instanceof HTMLPurifier_Token_Start) { + // start tag + + // ...unless they also have to close their parent + if (!empty($this->stack)) { + + $parent = array_pop($this->stack); + $this->stack[] = $parent; + + if (isset($definition->info[$parent->name])) { + $elements = $definition->info[$parent->name]->child->getAllowedElements($config); + $autoclose = !isset($elements[$token->name]); + } else { + $autoclose = false; + } + + if ($autoclose && $definition->info[$token->name]->wrap) { + // Check if an element can be wrapped by another + // element to make it valid in a context (for + // example,
        needs a
      • in between) + $wrapname = $definition->info[$token->name]->wrap; + $wrapdef = $definition->info[$wrapname]; + $elements = $wrapdef->child->getAllowedElements($config); + $parent_elements = $definition->info[$parent->name]->child->getAllowedElements($config); + if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) { + $newtoken = new HTMLPurifier_Token_Start($wrapname); + $this->insertBefore($newtoken); + $reprocess = true; + continue; + } + } + + $carryover = false; + if ($autoclose && $definition->info[$parent->name]->formatting) { + $carryover = true; + } + + if ($autoclose) { + // errors need to be updated + $new_token = new HTMLPurifier_Token_End($parent->name); + $new_token->start = $parent; + if ($carryover) { + $element = clone $parent; + $element->armor['MakeWellFormed_TagClosedError'] = true; + $element->carryover = true; + $this->processToken(array($new_token, $token, $element)); + } else { + $this->insertBefore($new_token); + } + if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) { + if (!$carryover) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent); + } else { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent); + } + } + $reprocess = true; + continue; + } + + } + $ok = true; + } + + if ($ok) { + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) continue; + if ($token->rewind !== null && $token->rewind !== $i) continue; + $injector->handleElement($token); + $this->processToken($token, $i); + $reprocess = true; + break; + } + if (!$reprocess) { + // ah, nothing interesting happened; do normal processing + $this->swap($token); + if ($token instanceof HTMLPurifier_Token_Start) { + $this->stack[] = $token; + } elseif ($token instanceof HTMLPurifier_Token_End) { + throw new HTMLPurifier_Exception('Improper handling of end tag in start code; possible error in MakeWellFormed'); + } + } + continue; + } + + // sanity check: we should be dealing with a closing tag + if (!$token instanceof HTMLPurifier_Token_End) { + throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier'); + } + + // make sure that we have something open + if (empty($this->stack)) { + if ($escape_invalid_tags) { + if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text'); + $this->swap(new HTMLPurifier_Token_Text( + $generator->generateFromToken($token) + )); + } else { + $this->remove(); + if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed'); + } + $reprocess = true; + continue; + } + + // first, check for the simplest case: everything closes neatly. + // Eventually, everything passes through here; if there are problems + // we modify the input stream accordingly and then punt, so that + // the tokens get processed again. + $current_parent = array_pop($this->stack); + if ($current_parent->name == $token->name) { + $token->start = $current_parent; + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) continue; + if ($token->rewind !== null && $token->rewind !== $i) continue; + $injector->handleEnd($token); + $this->processToken($token, $i); + $this->stack[] = $current_parent; + $reprocess = true; + break; + } + continue; + } + + // okay, so we're trying to close the wrong tag + + // undo the pop previous pop + $this->stack[] = $current_parent; + + // scroll back the entire nest, trying to find our tag. + // (feature could be to specify how far you'd like to go) + $size = count($this->stack); + // -2 because -1 is the last element, but we already checked that + $skipped_tags = false; + for ($j = $size - 2; $j >= 0; $j--) { + if ($this->stack[$j]->name == $token->name) { + $skipped_tags = array_slice($this->stack, $j); + break; + } + } + + // we didn't find the tag, so remove + if ($skipped_tags === false) { + if ($escape_invalid_tags) { + $this->swap(new HTMLPurifier_Token_Text( + $generator->generateFromToken($token) + )); + if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text'); + } else { + $this->remove(); + if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed'); + } + $reprocess = true; + continue; + } + + // do errors, in REVERSE $j order: a,b,c with + $c = count($skipped_tags); + if ($e) { + for ($j = $c - 1; $j > 0; $j--) { + // notice we exclude $j == 0, i.e. the current ending tag, from + // the errors... + if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]); + } + } + } + + // insert tags, in FORWARD $j order: c,b,a with + $replace = array($token); + for ($j = 1; $j < $c; $j++) { + // ...as well as from the insertions + $new_token = new HTMLPurifier_Token_End($skipped_tags[$j]->name); + $new_token->start = $skipped_tags[$j]; + array_unshift($replace, $new_token); + if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) { + $element = clone $skipped_tags[$j]; + $element->carryover = true; + $element->armor['MakeWellFormed_TagClosedError'] = true; + $replace[] = $element; + } + } + $this->processToken($replace); + $reprocess = true; + continue; + } + + $context->destroy('CurrentNesting'); + $context->destroy('InputTokens'); + $context->destroy('InputIndex'); + $context->destroy('CurrentToken'); + + unset($this->injectors, $this->stack, $this->tokens, $this->t); + return $tokens; + } + + /** + * Processes arbitrary token values for complicated substitution patterns. + * In general: + * + * If $token is an array, it is a list of tokens to substitute for the + * current token. These tokens then get individually processed. If there + * is a leading integer in the list, that integer determines how many + * tokens from the stream should be removed. + * + * If $token is a regular token, it is swapped with the current token. + * + * If $token is false, the current token is deleted. + * + * If $token is an integer, that number of tokens (with the first token + * being the current one) will be deleted. + * + * @param $token Token substitution value + * @param $injector Injector that performed the substitution; default is if + * this is not an injector related operation. + */ + protected function processToken($token, $injector = -1) { + + // normalize forms of token + if (is_object($token)) $token = array(1, $token); + if (is_int($token)) $token = array($token); + if ($token === false) $token = array(1); + if (!is_array($token)) throw new HTMLPurifier_Exception('Invalid token type from injector'); + if (!is_int($token[0])) array_unshift($token, 1); + if ($token[0] === 0) throw new HTMLPurifier_Exception('Deleting zero tokens is not valid'); + + // $token is now an array with the following form: + // array(number nodes to delete, new node 1, new node 2, ...) + + $delete = array_shift($token); + $old = array_splice($this->tokens, $this->t, $delete, $token); + + if ($injector > -1) { + // determine appropriate skips + $oldskip = isset($old[0]) ? $old[0]->skip : array(); + foreach ($token as $object) { + $object->skip = $oldskip; + $object->skip[$injector] = true; + } + } + + } + + /** + * Inserts a token before the current token. Cursor now points to this token + */ + private function insertBefore($token) { + array_splice($this->tokens, $this->t, 0, array($token)); + } + + /** + * Removes current token. Cursor now points to new token occupying previously + * occupied space. + */ + private function remove() { + array_splice($this->tokens, $this->t, 1); + } + + /** + * Swap current token with new token. Cursor points to new token (no change). + */ + private function swap($token) { + $this->tokens[$this->t] = $token; + } + +} + + + + + +/** + * Removes all unrecognized tags from the list of tokens. + * + * This strategy iterates through all the tokens and removes unrecognized + * tokens. If a token is not recognized but a TagTransform is defined for + * that element, the element will be transformed accordingly. + */ + +class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy +{ + + public function execute($tokens, $config, $context) { + $definition = $config->getHTMLDefinition(); + $generator = new HTMLPurifier_Generator($config, $context); + $result = array(); + + $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); + $remove_invalid_img = $config->get('Core.RemoveInvalidImg'); + + // currently only used to determine if comments should be kept + $trusted = $config->get('HTML.Trusted'); + + $remove_script_contents = $config->get('Core.RemoveScriptContents'); + $hidden_elements = $config->get('Core.HiddenElements'); + + // remove script contents compatibility + if ($remove_script_contents === true) { + $hidden_elements['script'] = true; + } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) { + unset($hidden_elements['script']); + } + + $attr_validator = new HTMLPurifier_AttrValidator(); + + // removes tokens until it reaches a closing tag with its value + $remove_until = false; + + // converts comments into text tokens when this is equal to a tag name + $textify_comments = false; + + $token = false; + $context->register('CurrentToken', $token); + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + foreach($tokens as $token) { + if ($remove_until) { + if (empty($token->is_tag) || $token->name !== $remove_until) { + continue; + } + } + if (!empty( $token->is_tag )) { + // DEFINITION CALL + + // before any processing, try to transform the element + if ( + isset($definition->info_tag_transform[$token->name]) + ) { + $original_name = $token->name; + // there is a transformation for this tag + // DEFINITION CALL + $token = $definition-> + info_tag_transform[$token->name]-> + transform($token, $config, $context); + if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name); + } + + if (isset($definition->info[$token->name])) { + + // mostly everything's good, but + // we need to make sure required attributes are in order + if ( + ($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) && + $definition->info[$token->name]->required_attr && + ($token->name != 'img' || $remove_invalid_img) // ensure config option still works + ) { + $attr_validator->validateToken($token, $config, $context); + $ok = true; + foreach ($definition->info[$token->name]->required_attr as $name) { + if (!isset($token->attr[$name])) { + $ok = false; + break; + } + } + if (!$ok) { + if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name); + continue; + } + $token->armor['ValidateAttributes'] = true; + } + + if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) { + $textify_comments = $token->name; + } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) { + $textify_comments = false; + } + + } elseif ($escape_invalid_tags) { + // invalid tag, generate HTML representation and insert in + if ($e) $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text'); + $token = new HTMLPurifier_Token_Text( + $generator->generateFromToken($token) + ); + } else { + // check if we need to destroy all of the tag's children + // CAN BE GENERICIZED + if (isset($hidden_elements[$token->name])) { + if ($token instanceof HTMLPurifier_Token_Start) { + $remove_until = $token->name; + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + // do nothing: we're still looking + } else { + $remove_until = false; + } + if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed'); + } else { + if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed'); + } + continue; + } + } elseif ($token instanceof HTMLPurifier_Token_Comment) { + // textify comments in script tags when they are allowed + if ($textify_comments !== false) { + $data = $token->data; + $token = new HTMLPurifier_Token_Text($data); + } elseif ($trusted) { + // keep, but perform comment cleaning + if ($e) { + // perform check whether or not there's a trailing hyphen + if (substr($token->data, -1) == '-') { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed'); + } + } + $token->data = rtrim($token->data, '-'); + $found_double_hyphen = false; + while (strpos($token->data, '--') !== false) { + if ($e && !$found_double_hyphen) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed'); + } + $found_double_hyphen = true; // prevent double-erroring + $token->data = str_replace('--', '-', $token->data); + } + } else { + // strip comments + if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); + continue; + } + } elseif ($token instanceof HTMLPurifier_Token_Text) { + } else { + continue; + } + $result[] = $token; + } + if ($remove_until && $e) { + // we removed tokens until the end, throw error + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until); + } + + $context->destroy('CurrentToken'); + + return $result; + } + +} + + + + + +/** + * Validate all attributes in the tokens. + */ + +class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy +{ + + public function execute($tokens, $config, $context) { + + // setup validator + $validator = new HTMLPurifier_AttrValidator(); + + $token = false; + $context->register('CurrentToken', $token); + + foreach ($tokens as $key => $token) { + + // only process tokens that have attributes, + // namely start and empty tags + if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) continue; + + // skip tokens that are armored + if (!empty($token->armor['ValidateAttributes'])) continue; + + // note that we have no facilities here for removing tokens + $validator->validateToken($token, $config, $context); + + $tokens[$key] = $token; // for PHP 4 + } + $context->destroy('CurrentToken'); + + return $tokens; + } + +} + + + + + +/** + * Transforms FONT tags to the proper form (SPAN with CSS styling) + * + * This transformation takes the three proprietary attributes of FONT and + * transforms them into their corresponding CSS attributes. These are color, + * face, and size. + * + * @note Size is an interesting case because it doesn't map cleanly to CSS. + * Thanks to + * http://style.cleverchimp.com/font_size_intervals/altintervals.html + * for reasonable mappings. + * @warning This doesn't work completely correctly; specifically, this + * TagTransform operates before well-formedness is enforced, so + * the "active formatting elements" algorithm doesn't get applied. + */ +class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform +{ + + public $transform_to = 'span'; + + protected $_size_lookup = array( + '0' => 'xx-small', + '1' => 'xx-small', + '2' => 'small', + '3' => 'medium', + '4' => 'large', + '5' => 'x-large', + '6' => 'xx-large', + '7' => '300%', + '-1' => 'smaller', + '-2' => '60%', + '+1' => 'larger', + '+2' => '150%', + '+3' => '200%', + '+4' => '300%' + ); + + public function transform($tag, $config, $context) { + + if ($tag instanceof HTMLPurifier_Token_End) { + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + return $new_tag; + } + + $attr = $tag->attr; + $prepend_style = ''; + + // handle color transform + if (isset($attr['color'])) { + $prepend_style .= 'color:' . $attr['color'] . ';'; + unset($attr['color']); + } + + // handle face transform + if (isset($attr['face'])) { + $prepend_style .= 'font-family:' . $attr['face'] . ';'; + unset($attr['face']); + } + + // handle size transform + if (isset($attr['size'])) { + // normalize large numbers + if ($attr['size']{0} == '+' || $attr['size']{0} == '-') { + $size = (int) $attr['size']; + if ($size < -2) $attr['size'] = '-2'; + if ($size > 4) $attr['size'] = '+4'; + } else { + $size = (int) $attr['size']; + if ($size > 7) $attr['size'] = '7'; + } + if (isset($this->_size_lookup[$attr['size']])) { + $prepend_style .= 'font-size:' . + $this->_size_lookup[$attr['size']] . ';'; + } + unset($attr['size']); + } + + if ($prepend_style) { + $attr['style'] = isset($attr['style']) ? + $prepend_style . $attr['style'] : + $prepend_style; + } + + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + $new_tag->attr = $attr; + + return $new_tag; + + } +} + + + + + +/** + * Simple transformation, just change tag name to something else, + * and possibly add some styling. This will cover most of the deprecated + * tag cases. + */ +class HTMLPurifier_TagTransform_Simple extends HTMLPurifier_TagTransform +{ + + protected $style; + + /** + * @param $transform_to Tag name to transform to. + * @param $style CSS style to add to the tag + */ + public function __construct($transform_to, $style = null) { + $this->transform_to = $transform_to; + $this->style = $style; + } + + public function transform($tag, $config, $context) { + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + if (!is_null($this->style) && + ($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty) + ) { + $this->prependCSS($new_tag->attr, $this->style); + } + return $new_tag; + } + +} + + + + + +/** + * Concrete comment token class. Generally will be ignored. + */ +class HTMLPurifier_Token_Comment extends HTMLPurifier_Token +{ + public $data; /**< Character data within comment. */ + public $is_whitespace = true; + /** + * Transparent constructor. + * + * @param $data String comment data. + */ + public function __construct($data, $line = null, $col = null) { + $this->data = $data; + $this->line = $line; + $this->col = $col; + } +} + + + + + +/** + * Abstract class of a tag token (start, end or empty), and its behavior. + */ +class HTMLPurifier_Token_Tag extends HTMLPurifier_Token +{ + /** + * Static bool marker that indicates the class is a tag. + * + * This allows us to check objects with !empty($obj->is_tag) + * without having to use a function call is_a(). + */ + public $is_tag = true; + + /** + * The lower-case name of the tag, like 'a', 'b' or 'blockquote'. + * + * @note Strictly speaking, XML tags are case sensitive, so we shouldn't + * be lower-casing them, but these tokens cater to HTML tags, which are + * insensitive. + */ + public $name; + + /** + * Associative array of the tag's attributes. + */ + public $attr = array(); + + /** + * Non-overloaded constructor, which lower-cases passed tag name. + * + * @param $name String name. + * @param $attr Associative array of attributes. + */ + public function __construct($name, $attr = array(), $line = null, $col = null) { + $this->name = ctype_lower($name) ? $name : strtolower($name); + foreach ($attr as $key => $value) { + // normalization only necessary when key is not lowercase + if (!ctype_lower($key)) { + $new_key = strtolower($key); + if (!isset($attr[$new_key])) { + $attr[$new_key] = $attr[$key]; + } + if ($new_key !== $key) { + unset($attr[$key]); + } + } + } + $this->attr = $attr; + $this->line = $line; + $this->col = $col; + } +} + + + + + +/** + * Concrete empty token class. + */ +class HTMLPurifier_Token_Empty extends HTMLPurifier_Token_Tag +{ + +} + + + + + +/** + * Concrete end token class. + * + * @warning This class accepts attributes even though end tags cannot. This + * is for optimization reasons, as under normal circumstances, the Lexers + * do not pass attributes. + */ +class HTMLPurifier_Token_End extends HTMLPurifier_Token_Tag +{ + /** + * Token that started this node. Added by MakeWellFormed. Please + * do not edit this! + */ + public $start; +} + + + + + +/** + * Concrete start token class. + */ +class HTMLPurifier_Token_Start extends HTMLPurifier_Token_Tag +{ + +} + + + + + +/** + * Concrete text token class. + * + * Text tokens comprise of regular parsed character data (PCDATA) and raw + * character data (from the CDATA sections). Internally, their + * data is parsed with all entities expanded. Surprisingly, the text token + * does have a "tag name" called #PCDATA, which is how the DTD represents it + * in permissible child nodes. + */ +class HTMLPurifier_Token_Text extends HTMLPurifier_Token +{ + + public $name = '#PCDATA'; /**< PCDATA tag name compatible with DTD. */ + public $data; /**< Parsed character data of text. */ + public $is_whitespace; /**< Bool indicating if node is whitespace. */ + + /** + * Constructor, accepts data and determines if it is whitespace. + * + * @param $data String parsed character data. + */ + public function __construct($data, $line = null, $col = null) { + $this->data = $data; + $this->is_whitespace = ctype_space($data); + $this->line = $line; + $this->col = $col; + } + +} + + + + + +class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter +{ + public $name = 'DisableExternal'; + protected $ourHostParts = false; + public function prepare($config) { + $our_host = $config->getDefinition('URI')->host; + if ($our_host !== null) $this->ourHostParts = array_reverse(explode('.', $our_host)); + } + public function filter(&$uri, $config, $context) { + if (is_null($uri->host)) return true; + if ($this->ourHostParts === false) return false; + $host_parts = array_reverse(explode('.', $uri->host)); + foreach ($this->ourHostParts as $i => $x) { + if (!isset($host_parts[$i])) return false; + if ($host_parts[$i] != $this->ourHostParts[$i]) return false; + } + return true; + } +} + + + + + +class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal +{ + public $name = 'DisableExternalResources'; + public function filter(&$uri, $config, $context) { + if (!$context->get('EmbeddedURI', true)) return true; + return parent::filter($uri, $config, $context); + } +} + + + + + +class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter +{ + public $name = 'HostBlacklist'; + protected $blacklist = array(); + public function prepare($config) { + $this->blacklist = $config->get('URI.HostBlacklist'); + return true; + } + public function filter(&$uri, $config, $context) { + foreach($this->blacklist as $blacklisted_host_fragment) { + if (strpos($uri->host, $blacklisted_host_fragment) !== false) { + return false; + } + } + return true; + } +} + + + + + +// does not support network paths + +class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter +{ + public $name = 'MakeAbsolute'; + protected $base; + protected $basePathStack = array(); + public function prepare($config) { + $def = $config->getDefinition('URI'); + $this->base = $def->base; + if (is_null($this->base)) { + trigger_error('URI.MakeAbsolute is being ignored due to lack of value for URI.Base configuration', E_USER_WARNING); + return false; + } + $this->base->fragment = null; // fragment is invalid for base URI + $stack = explode('/', $this->base->path); + array_pop($stack); // discard last segment + $stack = $this->_collapseStack($stack); // do pre-parsing + $this->basePathStack = $stack; + return true; + } + public function filter(&$uri, $config, $context) { + if (is_null($this->base)) return true; // abort early + if ( + $uri->path === '' && is_null($uri->scheme) && + is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment) + ) { + // reference to current document + $uri = clone $this->base; + return true; + } + if (!is_null($uri->scheme)) { + // absolute URI already: don't change + if (!is_null($uri->host)) return true; + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) { + // scheme not recognized + return false; + } + if (!$scheme_obj->hierarchical) { + // non-hierarchal URI with explicit scheme, don't change + return true; + } + // special case: had a scheme but always is hierarchical and had no authority + } + if (!is_null($uri->host)) { + // network path, don't bother + return true; + } + if ($uri->path === '') { + $uri->path = $this->base->path; + } elseif ($uri->path[0] !== '/') { + // relative path, needs more complicated processing + $stack = explode('/', $uri->path); + $new_stack = array_merge($this->basePathStack, $stack); + if ($new_stack[0] !== '' && !is_null($this->base->host)) { + array_unshift($new_stack, ''); + } + $new_stack = $this->_collapseStack($new_stack); + $uri->path = implode('/', $new_stack); + } else { + // absolute path, but still we should collapse + $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); + } + // re-combine + $uri->scheme = $this->base->scheme; + if (is_null($uri->userinfo)) $uri->userinfo = $this->base->userinfo; + if (is_null($uri->host)) $uri->host = $this->base->host; + if (is_null($uri->port)) $uri->port = $this->base->port; + return true; + } + + /** + * Resolve dots and double-dots in a path stack + */ + private function _collapseStack($stack) { + $result = array(); + $is_folder = false; + for ($i = 0; isset($stack[$i]); $i++) { + $is_folder = false; + // absorb an internally duplicated slash + if ($stack[$i] == '' && $i && isset($stack[$i+1])) continue; + if ($stack[$i] == '..') { + if (!empty($result)) { + $segment = array_pop($result); + if ($segment === '' && empty($result)) { + // error case: attempted to back out too far: + // restore the leading slash + $result[] = ''; + } elseif ($segment === '..') { + $result[] = '..'; // cannot remove .. with .. + } + } else { + // relative path, preserve the double-dots + $result[] = '..'; + } + $is_folder = true; + continue; + } + if ($stack[$i] == '.') { + // silently absorb + $is_folder = true; + continue; + } + $result[] = $stack[$i]; + } + if ($is_folder) $result[] = ''; + return $result; + } +} + + + + + +class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter +{ + public $name = 'Munge'; + public $post = true; + private $target, $parser, $doEmbed, $secretKey; + + protected $replace = array(); + + public function prepare($config) { + $this->target = $config->get('URI.' . $this->name); + $this->parser = new HTMLPurifier_URIParser(); + $this->doEmbed = $config->get('URI.MungeResources'); + $this->secretKey = $config->get('URI.MungeSecretKey'); + return true; + } + public function filter(&$uri, $config, $context) { + if ($context->get('EmbeddedURI', true) && !$this->doEmbed) return true; + + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it + if (is_null($uri->host) || empty($scheme_obj->browsable)) { + return true; + } + // don't redirect if target host is our host + if ($uri->host === $config->getDefinition('URI')->host) { + return true; + } + + $this->makeReplace($uri, $config, $context); + $this->replace = array_map('rawurlencode', $this->replace); + + $new_uri = strtr($this->target, $this->replace); + $new_uri = $this->parser->parse($new_uri); + // don't redirect if the target host is the same as the + // starting host + if ($uri->host === $new_uri->host) return true; + $uri = $new_uri; // overwrite + return true; + } + + protected function makeReplace($uri, $config, $context) { + $string = $uri->toString(); + // always available + $this->replace['%s'] = $string; + $this->replace['%r'] = $context->get('EmbeddedURI', true); + $token = $context->get('CurrentToken', true); + $this->replace['%n'] = $token ? $token->name : null; + $this->replace['%m'] = $context->get('CurrentAttr', true); + $this->replace['%p'] = $context->get('CurrentCSSProperty', true); + // not always available + if ($this->secretKey) $this->replace['%t'] = sha1($this->secretKey . ':' . $string); + } + +} + + + + + +/** + * Implements data: URI for base64 encoded images supported by GD. + */ +class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme { + + public $browsable = true; + public $allowed_types = array( + // you better write validation code for other types if you + // decide to allow them + 'image/jpeg' => true, + 'image/gif' => true, + 'image/png' => true, + ); + + public function validate(&$uri, $config, $context) { + $result = explode(',', $uri->path, 2); + $is_base64 = false; + $charset = null; + $content_type = null; + if (count($result) == 2) { + list($metadata, $data) = $result; + // do some legwork on the metadata + $metas = explode(';', $metadata); + while(!empty($metas)) { + $cur = array_shift($metas); + if ($cur == 'base64') { + $is_base64 = true; + break; + } + if (substr($cur, 0, 8) == 'charset=') { + // doesn't match if there are arbitrary spaces, but + // whatever dude + if ($charset !== null) continue; // garbage + $charset = substr($cur, 8); // not used + } else { + if ($content_type !== null) continue; // garbage + $content_type = $cur; + } + } + } else { + $data = $result[0]; + } + if ($content_type !== null && empty($this->allowed_types[$content_type])) { + return false; + } + if ($charset !== null) { + // error; we don't allow plaintext stuff + $charset = null; + } + $data = rawurldecode($data); + if ($is_base64) { + $raw_data = base64_decode($data); + } else { + $raw_data = $data; + } + // XXX probably want to refactor this into a general mechanism + // for filtering arbitrary content types + $file = tempnam("/tmp", ""); + file_put_contents($file, $raw_data); + if (function_exists('exif_imagetype')) { + $image_code = exif_imagetype($file); + } elseif (function_exists('getimagesize')) { + set_error_handler(array($this, 'muteErrorHandler')); + $info = getimagesize($file); + restore_error_handler(); + if ($info == false) return false; + $image_code = $info[2]; + } else { + trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR); + } + $real_content_type = image_type_to_mime_type($image_code); + if ($real_content_type != $content_type) { + // we're nice guys; if the content type is something else we + // support, change it over + if (empty($this->allowed_types[$real_content_type])) return false; + $content_type = $real_content_type; + } + // ok, it's kosher, rewrite what we need + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + $uri->fragment = null; + $uri->query = null; + $uri->path = "$content_type;base64," . base64_encode($raw_data); + return true; + } + + public function muteErrorHandler($errno, $errstr) {} + +} + + + + +/** + * Validates ftp (File Transfer Protocol) URIs as defined by generic RFC 1738. + */ +class HTMLPurifier_URIScheme_ftp extends HTMLPurifier_URIScheme { + + public $default_port = 21; + public $browsable = true; // usually + public $hierarchical = true; + + public function validate(&$uri, $config, $context) { + parent::validate($uri, $config, $context); + $uri->query = null; + + // typecode check + $semicolon_pos = strrpos($uri->path, ';'); // reverse + if ($semicolon_pos !== false) { + $type = substr($uri->path, $semicolon_pos + 1); // no semicolon + $uri->path = substr($uri->path, 0, $semicolon_pos); + $type_ret = ''; + if (strpos($type, '=') !== false) { + // figure out whether or not the declaration is correct + list($key, $typecode) = explode('=', $type, 2); + if ($key !== 'type') { + // invalid key, tack it back on encoded + $uri->path .= '%3B' . $type; + } elseif ($typecode === 'a' || $typecode === 'i' || $typecode === 'd') { + $type_ret = ";type=$typecode"; + } + } else { + $uri->path .= '%3B' . $type; + } + $uri->path = str_replace(';', '%3B', $uri->path); + $uri->path .= $type_ret; + } + + return true; + } + +} + + + + + +/** + * Validates http (HyperText Transfer Protocol) as defined by RFC 2616 + */ +class HTMLPurifier_URIScheme_http extends HTMLPurifier_URIScheme { + + public $default_port = 80; + public $browsable = true; + public $hierarchical = true; + + public function validate(&$uri, $config, $context) { + parent::validate($uri, $config, $context); + $uri->userinfo = null; + return true; + } + +} + + + + + +/** + * Validates https (Secure HTTP) according to http scheme. + */ +class HTMLPurifier_URIScheme_https extends HTMLPurifier_URIScheme_http { + + public $default_port = 443; + +} + + + + + +// VERY RELAXED! Shouldn't cause problems, not even Firefox checks if the +// email is valid, but be careful! + +/** + * Validates mailto (for E-mail) according to RFC 2368 + * @todo Validate the email address + * @todo Filter allowed query parameters + */ + +class HTMLPurifier_URIScheme_mailto extends HTMLPurifier_URIScheme { + + public $browsable = false; + + public function validate(&$uri, $config, $context) { + parent::validate($uri, $config, $context); + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + // we need to validate path against RFC 2368's addr-spec + return true; + } + +} + + + + + +/** + * Validates news (Usenet) as defined by generic RFC 1738 + */ +class HTMLPurifier_URIScheme_news extends HTMLPurifier_URIScheme { + + public $browsable = false; + + public function validate(&$uri, $config, $context) { + parent::validate($uri, $config, $context); + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + $uri->query = null; + // typecode check needed on path + return true; + } + +} + + + + + +/** + * Validates nntp (Network News Transfer Protocol) as defined by generic RFC 1738 + */ +class HTMLPurifier_URIScheme_nntp extends HTMLPurifier_URIScheme { + + public $default_port = 119; + public $browsable = false; + + public function validate(&$uri, $config, $context) { + parent::validate($uri, $config, $context); + $uri->userinfo = null; + $uri->query = null; + return true; + } + +} + + + + + +/** + * Performs safe variable parsing based on types which can be used by + * users. This may not be able to represent all possible data inputs, + * however. + */ +class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser +{ + + protected function parseImplementation($var, $type, $allow_null) { + if ($allow_null && $var === null) return null; + switch ($type) { + // Note: if code "breaks" from the switch, it triggers a generic + // exception to be thrown. Specific errors can be specifically + // done here. + case self::MIXED : + case self::ISTRING : + case self::STRING : + case self::TEXT : + case self::ITEXT : + return $var; + case self::INT : + if (is_string($var) && ctype_digit($var)) $var = (int) $var; + return $var; + case self::FLOAT : + if ((is_string($var) && is_numeric($var)) || is_int($var)) $var = (float) $var; + return $var; + case self::BOOL : + if (is_int($var) && ($var === 0 || $var === 1)) { + $var = (bool) $var; + } elseif (is_string($var)) { + if ($var == 'on' || $var == 'true' || $var == '1') { + $var = true; + } elseif ($var == 'off' || $var == 'false' || $var == '0') { + $var = false; + } else { + throw new HTMLPurifier_VarParserException("Unrecognized value '$var' for $type"); + } + } + return $var; + case self::ALIST : + case self::HASH : + case self::LOOKUP : + if (is_string($var)) { + // special case: technically, this is an array with + // a single empty string item, but having an empty + // array is more intuitive + if ($var == '') return array(); + if (strpos($var, "\n") === false && strpos($var, "\r") === false) { + // simplistic string to array method that only works + // for simple lists of tag names or alphanumeric characters + $var = explode(',',$var); + } else { + $var = preg_split('/(,|[\n\r]+)/', $var); + } + // remove spaces + foreach ($var as $i => $j) $var[$i] = trim($j); + if ($type === self::HASH) { + // key:value,key2:value2 + $nvar = array(); + foreach ($var as $keypair) { + $c = explode(':', $keypair, 2); + if (!isset($c[1])) continue; + $nvar[$c[0]] = $c[1]; + } + $var = $nvar; + } + } + if (!is_array($var)) break; + $keys = array_keys($var); + if ($keys === array_keys($keys)) { + if ($type == self::ALIST) return $var; + elseif ($type == self::LOOKUP) { + $new = array(); + foreach ($var as $key) { + $new[$key] = true; + } + return $new; + } else break; + } + if ($type === self::LOOKUP) { + foreach ($var as $key => $value) { + $var[$key] = true; + } + } + return $var; + default: + $this->errorInconsistent(__CLASS__, $type); + } + $this->errorGeneric($var, $type); + } + +} + + + + + +/** + * This variable parser uses PHP's internal code engine. Because it does + * this, it can represent all inputs; however, it is dangerous and cannot + * be used by users. + */ +class HTMLPurifier_VarParser_Native extends HTMLPurifier_VarParser +{ + + protected function parseImplementation($var, $type, $allow_null) { + return $this->evalExpression($var); + } + + protected function evalExpression($expr) { + $var = null; + $result = eval("\$var = $expr;"); + if ($result === false) { + throw new HTMLPurifier_VarParserException("Fatal error in evaluated code"); + } + return $var; + } + +} + + + diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php new file mode 100644 index 00000000..c05668a7 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php @@ -0,0 +1,44 @@ +directives as $d) { + $schema->add( + $d->id->key, + $d->default, + $d->type, + $d->typeAllowsNull + ); + if ($d->allowed !== null) { + $schema->addAllowedValues( + $d->id->key, + $d->allowed + ); + } + foreach ($d->aliases as $alias) { + $schema->addAlias( + $alias->key, + $d->id->key + ); + } + if ($d->valueAliases !== null) { + $schema->addValueAliases( + $d->id->key, + $d->valueAliases + ); + } + } + $schema->postProcess(); + return $schema; + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php new file mode 100644 index 00000000..244561a3 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php @@ -0,0 +1,106 @@ +startElement('div'); + + $purifier = HTMLPurifier::getInstance(); + $html = $purifier->purify($html); + $this->writeAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + $this->writeRaw($html); + + $this->endElement(); // div + } + + protected function export($var) { + if ($var === array()) return 'array()'; + return var_export($var, true); + } + + public function build($interchange) { + // global access, only use as last resort + $this->interchange = $interchange; + + $this->setIndent(true); + $this->startDocument('1.0', 'UTF-8'); + $this->startElement('configdoc'); + $this->writeElement('title', $interchange->name); + + foreach ($interchange->directives as $directive) { + $this->buildDirective($directive); + } + + if ($this->namespace) $this->endElement(); // namespace + + $this->endElement(); // configdoc + $this->flush(); + } + + public function buildDirective($directive) { + + // Kludge, although I suppose having a notion of a "root namespace" + // certainly makes things look nicer when documentation is built. + // Depends on things being sorted. + if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) { + if ($this->namespace) $this->endElement(); // namespace + $this->namespace = $directive->id->getRootNamespace(); + $this->startElement('namespace'); + $this->writeAttribute('id', $this->namespace); + $this->writeElement('name', $this->namespace); + } + + $this->startElement('directive'); + $this->writeAttribute('id', $directive->id->toString()); + + $this->writeElement('name', $directive->id->getDirective()); + + $this->startElement('aliases'); + foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString()); + $this->endElement(); // aliases + + $this->startElement('constraints'); + if ($directive->version) $this->writeElement('version', $directive->version); + $this->startElement('type'); + if ($directive->typeAllowsNull) $this->writeAttribute('allow-null', 'yes'); + $this->text($directive->type); + $this->endElement(); // type + if ($directive->allowed) { + $this->startElement('allowed'); + foreach ($directive->allowed as $value => $x) $this->writeElement('value', $value); + $this->endElement(); // allowed + } + $this->writeElement('default', $this->export($directive->default)); + $this->writeAttribute('xml:space', 'preserve'); + if ($directive->external) { + $this->startElement('external'); + foreach ($directive->external as $project) $this->writeElement('project', $project); + $this->endElement(); + } + $this->endElement(); // constraints + + if ($directive->deprecatedVersion) { + $this->startElement('deprecated'); + $this->writeElement('version', $directive->deprecatedVersion); + $this->writeElement('use', $directive->deprecatedUse->toString()); + $this->endElement(); // deprecated + } + + $this->startElement('description'); + $this->writeHTMLDiv($directive->description); + $this->endElement(); // description + + $this->endElement(); // directive + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Exception.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Exception.php new file mode 100644 index 00000000..2671516c --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Exception.php @@ -0,0 +1,11 @@ + array(directive info) + */ + public $directives = array(); + + /** + * Adds a directive array to $directives + */ + public function addDirective($directive) { + if (isset($this->directives[$i = $directive->id->toString()])) { + throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'"); + } + $this->directives[$i] = $directive; + } + + /** + * Convenience function to perform standard validation. Throws exception + * on failed validation. + */ + public function validate() { + $validator = new HTMLPurifier_ConfigSchema_Validator(); + return $validator->validate($this); + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php new file mode 100644 index 00000000..ac8be0d9 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php @@ -0,0 +1,77 @@ + true). + * Null if all values are allowed. + */ + public $allowed; + + /** + * List of aliases for the directive, + * e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))). + */ + public $aliases = array(); + + /** + * Hash of value aliases, e.g. array('alt' => 'real'). Null if value + * aliasing is disabled (necessary for non-scalar types). + */ + public $valueAliases; + + /** + * Version of HTML Purifier the directive was introduced, e.g. '1.3.1'. + * Null if the directive has always existed. + */ + public $version; + + /** + * ID of directive that supercedes this old directive, is an instance + * of HTMLPurifier_ConfigSchema_Interchange_Id. Null if not deprecated. + */ + public $deprecatedUse; + + /** + * Version of HTML Purifier this directive was deprecated. Null if not + * deprecated. + */ + public $deprecatedVersion; + + /** + * List of external projects this directive depends on, e.g. array('CSSTidy'). + */ + public $external = array(); + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php new file mode 100644 index 00000000..b9b3c6f5 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php @@ -0,0 +1,37 @@ +key = $key; + } + + /** + * @warning This is NOT magic, to ensure that people don't abuse SPL and + * cause problems for PHP 5.0 support. + */ + public function toString() { + return $this->key; + } + + public function getRootNamespace() { + return substr($this->key, 0, strpos($this->key, ".")); + } + + public function getDirective() { + return substr($this->key, strpos($this->key, ".") + 1); + } + + public static function make($id) { + return new HTMLPurifier_ConfigSchema_Interchange_Id($id); + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php new file mode 100644 index 00000000..785b72ce --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php @@ -0,0 +1,180 @@ +varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native(); + } + + public static function buildFromDirectory($dir = null) { + $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); + $interchange = new HTMLPurifier_ConfigSchema_Interchange(); + return $builder->buildDir($interchange, $dir); + } + + public function buildDir($interchange, $dir = null) { + if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; + if (file_exists($dir . '/info.ini')) { + $info = parse_ini_file($dir . '/info.ini'); + $interchange->name = $info['name']; + } + + $files = array(); + $dh = opendir($dir); + while (false !== ($file = readdir($dh))) { + if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') { + continue; + } + $files[] = $file; + } + closedir($dh); + + sort($files); + foreach ($files as $file) { + $this->buildFile($interchange, $dir . '/' . $file); + } + + return $interchange; + } + + public function buildFile($interchange, $file) { + $parser = new HTMLPurifier_StringHashParser(); + $this->build( + $interchange, + new HTMLPurifier_StringHash( $parser->parseFile($file) ) + ); + } + + /** + * Builds an interchange object based on a hash. + * @param $interchange HTMLPurifier_ConfigSchema_Interchange object to build + * @param $hash HTMLPurifier_ConfigSchema_StringHash source data + */ + public function build($interchange, $hash) { + if (!$hash instanceof HTMLPurifier_StringHash) { + $hash = new HTMLPurifier_StringHash($hash); + } + if (!isset($hash['ID'])) { + throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID'); + } + if (strpos($hash['ID'], '.') === false) { + if (count($hash) == 2 && isset($hash['DESCRIPTION'])) { + $hash->offsetGet('DESCRIPTION'); // prevent complaining + } else { + throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace'); + } + } else { + $this->buildDirective($interchange, $hash); + } + $this->_findUnused($hash); + } + + public function buildDirective($interchange, $hash) { + $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive(); + + // These are required elements: + $directive->id = $this->id($hash->offsetGet('ID')); + $id = $directive->id->toString(); // convenience + + if (isset($hash['TYPE'])) { + $type = explode('/', $hash->offsetGet('TYPE')); + if (isset($type[1])) $directive->typeAllowsNull = true; + $directive->type = $type[0]; + } else { + throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined"); + } + + if (isset($hash['DEFAULT'])) { + try { + $directive->default = $this->varParser->parse($hash->offsetGet('DEFAULT'), $directive->type, $directive->typeAllowsNull); + } catch (HTMLPurifier_VarParserException $e) { + throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'"); + } + } + + if (isset($hash['DESCRIPTION'])) { + $directive->description = $hash->offsetGet('DESCRIPTION'); + } + + if (isset($hash['ALLOWED'])) { + $directive->allowed = $this->lookup($this->evalArray($hash->offsetGet('ALLOWED'))); + } + + if (isset($hash['VALUE-ALIASES'])) { + $directive->valueAliases = $this->evalArray($hash->offsetGet('VALUE-ALIASES')); + } + + if (isset($hash['ALIASES'])) { + $raw_aliases = trim($hash->offsetGet('ALIASES')); + $aliases = preg_split('/\s*,\s*/', $raw_aliases); + foreach ($aliases as $alias) { + $directive->aliases[] = $this->id($alias); + } + } + + if (isset($hash['VERSION'])) { + $directive->version = $hash->offsetGet('VERSION'); + } + + if (isset($hash['DEPRECATED-USE'])) { + $directive->deprecatedUse = $this->id($hash->offsetGet('DEPRECATED-USE')); + } + + if (isset($hash['DEPRECATED-VERSION'])) { + $directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION'); + } + + if (isset($hash['EXTERNAL'])) { + $directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL'))); + } + + $interchange->addDirective($directive); + } + + /** + * Evaluates an array PHP code string without array() wrapper + */ + protected function evalArray($contents) { + return eval('return array('. $contents .');'); + } + + /** + * Converts an array list into a lookup array. + */ + protected function lookup($array) { + $ret = array(); + foreach ($array as $val) $ret[$val] = true; + return $ret; + } + + /** + * Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id + * object based on a string Id. + */ + protected function id($id) { + return HTMLPurifier_ConfigSchema_Interchange_Id::make($id); + } + + /** + * Triggers errors for any unused keys passed in the hash; such keys + * may indicate typos, missing values, etc. + * @param $hash Instance of ConfigSchema_StringHash to check. + */ + protected function _findUnused($hash) { + $accessed = $hash->getAccessed(); + foreach ($hash as $k => $v) { + if (!isset($accessed[$k])) { + trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE); + } + } + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Validator.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Validator.php new file mode 100644 index 00000000..f374f6a0 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/Validator.php @@ -0,0 +1,206 @@ +parser = new HTMLPurifier_VarParser(); + } + + /** + * Validates a fully-formed interchange object. Throws an + * HTMLPurifier_ConfigSchema_Exception if there's a problem. + */ + public function validate($interchange) { + $this->interchange = $interchange; + $this->aliases = array(); + // PHP is a bit lax with integer <=> string conversions in + // arrays, so we don't use the identical !== comparison + foreach ($interchange->directives as $i => $directive) { + $id = $directive->id->toString(); + if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'"); + $this->validateDirective($directive); + } + return true; + } + + /** + * Validates a HTMLPurifier_ConfigSchema_Interchange_Id object. + */ + public function validateId($id) { + $id_string = $id->toString(); + $this->context[] = "id '$id_string'"; + if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) { + // handled by InterchangeBuilder + $this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id'); + } + // keys are now unconstrained (we might want to narrow down to A-Za-z0-9.) + // we probably should check that it has at least one namespace + $this->with($id, 'key') + ->assertNotEmpty() + ->assertIsString(); // implicit assertIsString handled by InterchangeBuilder + array_pop($this->context); + } + + /** + * Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object. + */ + public function validateDirective($d) { + $id = $d->id->toString(); + $this->context[] = "directive '$id'"; + $this->validateId($d->id); + + $this->with($d, 'description') + ->assertNotEmpty(); + + // BEGIN - handled by InterchangeBuilder + $this->with($d, 'type') + ->assertNotEmpty(); + $this->with($d, 'typeAllowsNull') + ->assertIsBool(); + try { + // This also tests validity of $d->type + $this->parser->parse($d->default, $d->type, $d->typeAllowsNull); + } catch (HTMLPurifier_VarParserException $e) { + $this->error('default', 'had error: ' . $e->getMessage()); + } + // END - handled by InterchangeBuilder + + if (!is_null($d->allowed) || !empty($d->valueAliases)) { + // allowed and valueAliases require that we be dealing with + // strings, so check for that early. + $d_int = HTMLPurifier_VarParser::$types[$d->type]; + if (!isset(HTMLPurifier_VarParser::$stringTypes[$d_int])) { + $this->error('type', 'must be a string type when used with allowed or value aliases'); + } + } + + $this->validateDirectiveAllowed($d); + $this->validateDirectiveValueAliases($d); + $this->validateDirectiveAliases($d); + + array_pop($this->context); + } + + /** + * Extra validation if $allowed member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + */ + public function validateDirectiveAllowed($d) { + if (is_null($d->allowed)) return; + $this->with($d, 'allowed') + ->assertNotEmpty() + ->assertIsLookup(); // handled by InterchangeBuilder + if (is_string($d->default) && !isset($d->allowed[$d->default])) { + $this->error('default', 'must be an allowed value'); + } + $this->context[] = 'allowed'; + foreach ($d->allowed as $val => $x) { + if (!is_string($val)) $this->error("value $val", 'must be a string'); + } + array_pop($this->context); + } + + /** + * Extra validation if $valueAliases member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + */ + public function validateDirectiveValueAliases($d) { + if (is_null($d->valueAliases)) return; + $this->with($d, 'valueAliases') + ->assertIsArray(); // handled by InterchangeBuilder + $this->context[] = 'valueAliases'; + foreach ($d->valueAliases as $alias => $real) { + if (!is_string($alias)) $this->error("alias $alias", 'must be a string'); + if (!is_string($real)) $this->error("alias target $real from alias '$alias'", 'must be a string'); + if ($alias === $real) { + $this->error("alias '$alias'", "must not be an alias to itself"); + } + } + if (!is_null($d->allowed)) { + foreach ($d->valueAliases as $alias => $real) { + if (isset($d->allowed[$alias])) { + $this->error("alias '$alias'", 'must not be an allowed value'); + } elseif (!isset($d->allowed[$real])) { + $this->error("alias '$alias'", 'must be an alias to an allowed value'); + } + } + } + array_pop($this->context); + } + + /** + * Extra validation if $aliases member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + */ + public function validateDirectiveAliases($d) { + $this->with($d, 'aliases') + ->assertIsArray(); // handled by InterchangeBuilder + $this->context[] = 'aliases'; + foreach ($d->aliases as $alias) { + $this->validateId($alias); + $s = $alias->toString(); + if (isset($this->interchange->directives[$s])) { + $this->error("alias '$s'", 'collides with another directive'); + } + if (isset($this->aliases[$s])) { + $other_directive = $this->aliases[$s]; + $this->error("alias '$s'", "collides with alias for directive '$other_directive'"); + } + $this->aliases[$s] = $d->id->toString(); + } + array_pop($this->context); + } + + // protected helper functions + + /** + * Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom + * for validating simple member variables of objects. + */ + protected function with($obj, $member) { + return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member); + } + + /** + * Emits an error, providing helpful context. + */ + protected function error($target, $msg) { + if ($target !== false) $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext(); + else $prefix = ucfirst($this->getFormattedContext()); + throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg)); + } + + /** + * Returns a formatted context string. + */ + protected function getFormattedContext() { + return implode(' in ', array_reverse($this->context)); + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php new file mode 100644 index 00000000..b95aea18 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php @@ -0,0 +1,66 @@ +context = $context; + $this->obj = $obj; + $this->member = $member; + $this->contents =& $obj->$member; + } + + public function assertIsString() { + if (!is_string($this->contents)) $this->error('must be a string'); + return $this; + } + + public function assertIsBool() { + if (!is_bool($this->contents)) $this->error('must be a boolean'); + return $this; + } + + public function assertIsArray() { + if (!is_array($this->contents)) $this->error('must be an array'); + return $this; + } + + public function assertNotNull() { + if ($this->contents === null) $this->error('must not be null'); + return $this; + } + + public function assertAlnum() { + $this->assertIsString(); + if (!ctype_alnum($this->contents)) $this->error('must be alphanumeric'); + return $this; + } + + public function assertNotEmpty() { + if (empty($this->contents)) $this->error('must not be empty'); + return $this; + } + + public function assertIsLookup() { + $this->assertIsArray(); + foreach ($this->contents as $v) { + if ($v !== true) $this->error('must be a lookup array'); + } + return $this; + } + + protected function error($msg) { + throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg); + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema.ser b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema.ser new file mode 100644 index 00000000..22b8d54a Binary files /dev/null and b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema.ser differ diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt new file mode 100644 index 00000000..0517fed0 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt @@ -0,0 +1,8 @@ +Attr.AllowedClasses +TYPE: lookup/null +VERSION: 4.0.0 +DEFAULT: null +--DESCRIPTION-- +List of allowed class values in the class attribute. By default, this is null, +which means all classes are allowed. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt new file mode 100644 index 00000000..249edd64 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt @@ -0,0 +1,12 @@ +Attr.AllowedFrameTargets +TYPE: lookup +DEFAULT: array() +--DESCRIPTION-- +Lookup table of all allowed link frame targets. Some commonly used link +targets include _blank, _self, _parent and _top. Values should be +lowercase, as validation will be done in a case-sensitive manner despite +W3C's recommendation. XHTML 1.0 Strict does not permit the target attribute +so this directive will have no effect in that doctype. XHTML 1.1 does not +enable the Target module by default, you will have to manually enable it +(see the module documentation for more details.) +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt new file mode 100644 index 00000000..9a8fa6a2 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt @@ -0,0 +1,9 @@ +Attr.AllowedRel +TYPE: lookup +VERSION: 1.6.0 +DEFAULT: array() +--DESCRIPTION-- +List of allowed forward document relationships in the rel attribute. Common +values may be nofollow or print. By default, this is empty, meaning that no +document relationships are allowed. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt new file mode 100644 index 00000000..b0178834 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt @@ -0,0 +1,9 @@ +Attr.AllowedRev +TYPE: lookup +VERSION: 1.6.0 +DEFAULT: array() +--DESCRIPTION-- +List of allowed reverse document relationships in the rev attribute. This +attribute is a bit of an edge-case; if you don't know what it is for, stay +away. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt new file mode 100644 index 00000000..e774b823 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt @@ -0,0 +1,19 @@ +Attr.ClassUseCDATA +TYPE: bool/null +DEFAULT: null +VERSION: 4.0.0 +--DESCRIPTION-- +If null, class will auto-detect the doctype and, if matching XHTML 1.1 or +XHTML 2.0, will use the restrictive NMTOKENS specification of class. Otherwise, +it will use a relaxed CDATA definition. If true, the relaxed CDATA definition +is forced; if false, the NMTOKENS definition is forced. To get behavior +of HTML Purifier prior to 4.0.0, set this directive to false. + +Some rational behind the auto-detection: +in previous versions of HTML Purifier, it was assumed that the form of +class was NMTOKENS, as specified by the XHTML Modularization (representing +XHTML 1.1 and XHTML 2.0). The DTDs for HTML 4.01 and XHTML 1.0, however +specify class as CDATA. HTML 5 effectively defines it as CDATA, but +with the additional constraint that each name should be unique (this is not +explicitly outlined in previous specifications). +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt new file mode 100644 index 00000000..533165e1 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt @@ -0,0 +1,11 @@ +Attr.DefaultImageAlt +TYPE: string/null +DEFAULT: null +VERSION: 3.2.0 +--DESCRIPTION-- +This is the content of the alt tag of an image if the user had not +previously specified an alt attribute. This applies to all images without +a valid alt attribute, as opposed to %Attr.DefaultInvalidImageAlt, which +only applies to invalid images, and overrides in the case of an invalid image. +Default behavior with null is to use the basename of the src tag for the alt. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt new file mode 100644 index 00000000..9eb7e384 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt @@ -0,0 +1,9 @@ +Attr.DefaultInvalidImage +TYPE: string +DEFAULT: '' +--DESCRIPTION-- +This is the default image an img tag will be pointed to if it does not have +a valid src attribute. In future versions, we may allow the image tag to +be removed completely, but due to design issues, this is not possible right +now. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt new file mode 100644 index 00000000..2f17bf47 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt @@ -0,0 +1,8 @@ +Attr.DefaultInvalidImageAlt +TYPE: string +DEFAULT: 'Invalid image' +--DESCRIPTION-- +This is the content of the alt tag of an invalid image if the user had not +previously specified an alt attribute. It has no effect when the image is +valid but there was no alt attribute present. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt new file mode 100644 index 00000000..52654b53 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt @@ -0,0 +1,10 @@ +Attr.DefaultTextDir +TYPE: string +DEFAULT: 'ltr' +--DESCRIPTION-- +Defines the default text direction (ltr or rtl) of the document being +parsed. This generally is the same as the value of the dir attribute in +HTML, or ltr if that is not specified. +--ALLOWED-- +'ltr', 'rtl' +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt new file mode 100644 index 00000000..6440d210 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt @@ -0,0 +1,16 @@ +Attr.EnableID +TYPE: bool +DEFAULT: false +VERSION: 1.2.0 +--DESCRIPTION-- +Allows the ID attribute in HTML. This is disabled by default due to the +fact that without proper configuration user input can easily break the +validation of a webpage by specifying an ID that is already on the +surrounding HTML. If you don't mind throwing caution to the wind, enable +this directive, but I strongly recommend you also consider blacklisting IDs +you use (%Attr.IDBlacklist) or prefixing all user supplied IDs +(%Attr.IDPrefix). When set to true HTML Purifier reverts to the behavior of +pre-1.2.0 versions. +--ALIASES-- +HTML.EnableAttrID +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt new file mode 100644 index 00000000..f31d226f --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt @@ -0,0 +1,8 @@ +Attr.ForbiddenClasses +TYPE: lookup +VERSION: 4.0.0 +DEFAULT: array() +--DESCRIPTION-- +List of forbidden class values in the class attribute. By default, this is +empty, which means that no classes are forbidden. See also %Attr.AllowedClasses. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt new file mode 100644 index 00000000..5f2b5e3d --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt @@ -0,0 +1,5 @@ +Attr.IDBlacklist +TYPE: list +DEFAULT: array() +DESCRIPTION: Array of IDs not allowed in the document. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt new file mode 100644 index 00000000..6f582458 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt @@ -0,0 +1,9 @@ +Attr.IDBlacklistRegexp +TYPE: string/null +VERSION: 1.6.0 +DEFAULT: NULL +--DESCRIPTION-- +PCRE regular expression to be matched against all IDs. If the expression is +matches, the ID is rejected. Use this with care: may cause significant +degradation. ID matching is done after all other validation. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt new file mode 100644 index 00000000..cc49d43f --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt @@ -0,0 +1,12 @@ +Attr.IDPrefix +TYPE: string +VERSION: 1.2.0 +DEFAULT: '' +--DESCRIPTION-- +String to prefix to IDs. If you have no idea what IDs your pages may use, +you may opt to simply add a prefix to all user-submitted ID attributes so +that they are still usable, but will not conflict with core page IDs. +Example: setting the directive to 'user_' will result in a user submitted +'foo' to become 'user_foo' Be sure to set %HTML.EnableAttrID to true +before using this. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt new file mode 100644 index 00000000..2c5924a7 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt @@ -0,0 +1,14 @@ +Attr.IDPrefixLocal +TYPE: string +VERSION: 1.2.0 +DEFAULT: '' +--DESCRIPTION-- +Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If you +need to allow multiple sets of user content on web page, you may need to +have a seperate prefix that changes with each iteration. This way, +seperately submitted user content displayed on the same page doesn't +clobber each other. Ideal values are unique identifiers for the content it +represents (i.e. the id of the row in the database). Be sure to add a +seperator (like an underscore) at the end. Warning: this directive will +not work unless %Attr.IDPrefix is set to a non-empty value! +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt new file mode 100644 index 00000000..d5caa1bb --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt @@ -0,0 +1,31 @@ +AutoFormat.AutoParagraph +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + This directive turns on auto-paragraphing, where double newlines are + converted in to paragraphs whenever possible. Auto-paragraphing: +

        +
          +
        • Always applies to inline elements or text in the root node,
        • +
        • Applies to inline elements or text with double newlines in nodes + that allow paragraph tags,
        • +
        • Applies to double newlines in paragraph tags
        • +
        +

        + p tags must be allowed for this directive to take effect. + We do not use br tags for paragraphing, as that is + semantically incorrect. +

        +

        + To prevent auto-paragraphing as a content-producer, refrain from using + double-newlines except to specify a new paragraph or in contexts where + it has special meaning (whitespace usually has no meaning except in + tags like pre, so this should not be difficult.) To prevent + the paragraphing of inline text adjacent to block elements, wrap them + in div tags (the behavior is slightly different outside of + the root node.) +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt new file mode 100644 index 00000000..2a476481 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt @@ -0,0 +1,12 @@ +AutoFormat.Custom +TYPE: list +VERSION: 2.0.1 +DEFAULT: array() +--DESCRIPTION-- + +

        + This directive can be used to add custom auto-format injectors. + Specify an array of injector names (class name minus the prefix) + or concrete implementations. Injector class must exist. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt new file mode 100644 index 00000000..663064a3 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt @@ -0,0 +1,11 @@ +AutoFormat.DisplayLinkURI +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + This directive turns on the in-text display of URIs in <a> tags, and disables + those links. For example, example becomes + example (http://example.com). +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt new file mode 100644 index 00000000..3a48ba96 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt @@ -0,0 +1,12 @@ +AutoFormat.Linkify +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + This directive turns on linkification, auto-linking http, ftp and + https URLs. a tags with the href attribute + must be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt new file mode 100644 index 00000000..db58b134 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt @@ -0,0 +1,12 @@ +AutoFormat.PurifierLinkify.DocURL +TYPE: string +VERSION: 2.0.1 +DEFAULT: '#%s' +ALIASES: AutoFormatParam.PurifierLinkifyDocURL +--DESCRIPTION-- +

        + Location of configuration documentation to link to, let %s substitute + into the configuration's namespace and directive names sans the percent + sign. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt new file mode 100644 index 00000000..7996488b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt @@ -0,0 +1,12 @@ +AutoFormat.PurifierLinkify +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + Internal auto-formatter that converts configuration directives in + syntax %Namespace.Directive to links. a tags + with the href attribute must be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt new file mode 100644 index 00000000..35c393b4 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt @@ -0,0 +1,11 @@ +AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions +TYPE: lookup +VERSION: 4.0.0 +DEFAULT: array('td' => true, 'th' => true) +--DESCRIPTION-- +

        + When %AutoFormat.RemoveEmpty and %AutoFormat.RemoveEmpty.RemoveNbsp + are enabled, this directive defines what HTML elements should not be + removede if they have only a non-breaking space in them. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt new file mode 100644 index 00000000..ca17eb1d --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt @@ -0,0 +1,15 @@ +AutoFormat.RemoveEmpty.RemoveNbsp +TYPE: bool +VERSION: 4.0.0 +DEFAULT: false +--DESCRIPTION-- +

        + When enabled, HTML Purifier will treat any elements that contain only + non-breaking spaces as well as regular whitespace as empty, and remove + them when %AutoForamt.RemoveEmpty is enabled. +

        +

        + See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements + that don't have this behavior applied to them. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt new file mode 100644 index 00000000..34657ba4 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt @@ -0,0 +1,46 @@ +AutoFormat.RemoveEmpty +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + When enabled, HTML Purifier will attempt to remove empty elements that + contribute no semantic information to the document. The following types + of nodes will be removed: +

        +
        • + Tags with no attributes and no content, and that are not empty + elements (remove <a></a> but not + <br />), and +
        • +
        • + Tags with no content, except for:
            +
          • The colgroup element, or
          • +
          • + Elements with the id or name attribute, + when those attributes are permitted on those elements. +
          • +
        • +
        +

        + Please be very careful when using this functionality; while it may not + seem that empty elements contain useful information, they can alter the + layout of a document given appropriate styling. This directive is most + useful when you are processing machine-generated HTML, please avoid using + it on regular user HTML. +

        +

        + Elements that contain only whitespace will be treated as empty. Non-breaking + spaces, however, do not count as whitespace. See + %AutoFormat.RemoveEmpty.RemoveNbsp for alternate behavior. +

        +

        + This algorithm is not perfect; you may still notice some empty tags, + particularly if a node had elements, but those elements were later removed + because they were not permitted in that context, or tags that, after + being auto-closed by another tag, where empty. This is for safety reasons + to prevent clever code from breaking validation. The general rule of thumb: + if a tag looked empty on the way in, it will get removed; if HTML Purifier + made it empty, it will stay. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt new file mode 100644 index 00000000..dde990ab --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt @@ -0,0 +1,11 @@ +AutoFormat.RemoveSpansWithoutAttributes +TYPE: bool +VERSION: 4.0.1 +DEFAULT: false +--DESCRIPTION-- +

        + This directive causes span tags without any attributes + to be removed. It will also remove spans that had all attributes + removed during processing. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt new file mode 100644 index 00000000..b324608f --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt @@ -0,0 +1,8 @@ +CSS.AllowImportant +TYPE: bool +DEFAULT: false +VERSION: 3.1.0 +--DESCRIPTION-- +This parameter determines whether or not !important cascade modifiers should +be allowed in user CSS. If false, !important will stripped. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt new file mode 100644 index 00000000..748be0ee --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt @@ -0,0 +1,11 @@ +CSS.AllowTricky +TYPE: bool +DEFAULT: false +VERSION: 3.1.0 +--DESCRIPTION-- +This parameter determines whether or not to allow "tricky" CSS properties and +values. Tricky CSS properties/values can drastically modify page layout or +be used for deceptive practices but do not directly constitute a security risk. +For example, display:none; is considered a tricky property that +will only be allowed if this directive is set to true. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt new file mode 100644 index 00000000..460112eb --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt @@ -0,0 +1,18 @@ +CSS.AllowedProperties +TYPE: lookup/null +VERSION: 3.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If HTML Purifier's style attributes set is unsatisfactory for your needs, + you can overload it with your own list of tags to allow. Note that this + method is subtractive: it does its job by taking away from HTML Purifier + usual feature set, so you cannot add an attribute that HTML Purifier never + supported in the first place. +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt new file mode 100644 index 00000000..5cb7dda3 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt @@ -0,0 +1,11 @@ +CSS.DefinitionRev +TYPE: int +VERSION: 2.0.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition. See + %HTML.DefinitionRev for details. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt new file mode 100644 index 00000000..7a329147 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt @@ -0,0 +1,16 @@ +CSS.MaxImgLength +TYPE: string/null +DEFAULT: '1200px' +VERSION: 3.1.1 +--DESCRIPTION-- +

        + This parameter sets the maximum allowed length on img tags, + effectively the width and height properties. + Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %HTML.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the CSS max is a number with + a unit). +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt new file mode 100644 index 00000000..148eedb8 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt @@ -0,0 +1,10 @@ +CSS.Proprietary +TYPE: bool +VERSION: 3.0.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Whether or not to allow safe, proprietary CSS values. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt new file mode 100644 index 00000000..c486724c --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt @@ -0,0 +1,14 @@ +Cache.DefinitionImpl +TYPE: string/null +VERSION: 2.0.0 +DEFAULT: 'Serializer' +--DESCRIPTION-- + +This directive defines which method to use when caching definitions, +the complex data-type that makes HTML Purifier tick. Set to null +to disable caching (not recommended, as you will see a definite +performance degradation). + +--ALIASES-- +Core.DefinitionCache +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt new file mode 100644 index 00000000..54036507 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt @@ -0,0 +1,13 @@ +Cache.SerializerPath +TYPE: string/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Absolute path with no trailing slash to store serialized definitions in. + Default is within the + HTML Purifier library inside DefinitionCache/Serializer. This + path must be writable by the webserver. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt new file mode 100644 index 00000000..568cbf3b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt @@ -0,0 +1,18 @@ +Core.AggressivelyFixLt +TYPE: bool +VERSION: 2.1.0 +DEFAULT: true +--DESCRIPTION-- +

        + This directive enables aggressive pre-filter fixes HTML Purifier can + perform in order to ensure that open angled-brackets do not get killed + during parsing stage. Enabling this will result in two preg_replace_callback + calls and at least two preg_replace calls for every HTML document parsed; + if your users make very well-formed HTML, you can set this directive false. + This has no effect when DirectLex is used. +

        +

        + Notice: This directive's default turned from false to true + in HTML Purifier 3.2.0. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt new file mode 100644 index 00000000..d7317911 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt @@ -0,0 +1,12 @@ +Core.CollectErrors +TYPE: bool +VERSION: 2.0.0 +DEFAULT: false +--DESCRIPTION-- + +Whether or not to collect errors found while filtering the document. This +is a useful way to give feedback to your users. Warning: +Currently this feature is very patchy and experimental, with lots of +possible error messages not yet implemented. It will not cause any +problems, but it may not help your users either. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt new file mode 100644 index 00000000..08b381d3 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt @@ -0,0 +1,28 @@ +Core.ColorKeywords +TYPE: hash +VERSION: 2.0.0 +--DEFAULT-- +array ( + 'maroon' => '#800000', + 'red' => '#FF0000', + 'orange' => '#FFA500', + 'yellow' => '#FFFF00', + 'olive' => '#808000', + 'purple' => '#800080', + 'fuchsia' => '#FF00FF', + 'white' => '#FFFFFF', + 'lime' => '#00FF00', + 'green' => '#008000', + 'navy' => '#000080', + 'blue' => '#0000FF', + 'aqua' => '#00FFFF', + 'teal' => '#008080', + 'black' => '#000000', + 'silver' => '#C0C0C0', + 'gray' => '#808080', +) +--DESCRIPTION-- + +Lookup array of color names to six digit hexadecimal number corresponding +to color, with preceding hash mark. Used when parsing colors. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt new file mode 100644 index 00000000..64b114fc --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt @@ -0,0 +1,14 @@ +Core.ConvertDocumentToFragment +TYPE: bool +DEFAULT: true +--DESCRIPTION-- + +This parameter determines whether or not the filter should convert +input that is a full document with html and body tags to a fragment +of just the contents of a body tag. This parameter is simply something +HTML Purifier can do during an edge-case: for most inputs, this +processing is not necessary. + +--ALIASES-- +Core.AcceptFullDocuments +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt new file mode 100644 index 00000000..36f16e07 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt @@ -0,0 +1,17 @@ +Core.DirectLexLineNumberSyncInterval +TYPE: int +VERSION: 2.0.0 +DEFAULT: 0 +--DESCRIPTION-- + +

        + Specifies the number of tokens the DirectLex line number tracking + implementations should process before attempting to resyncronize the + current line count by manually counting all previous new-lines. When + at 0, this functionality is disabled. Lower values will decrease + performance, and this is only strictly necessary if the counting + algorithm is buggy (in which case you should report it as a bug). + This has no effect when %Core.MaintainLineNumbers is disabled or DirectLex is + not being used. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt new file mode 100644 index 00000000..8bfb47c3 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt @@ -0,0 +1,15 @@ +Core.Encoding +TYPE: istring +DEFAULT: 'utf-8' +--DESCRIPTION-- +If for some reason you are unable to convert all webpages to UTF-8, you can +use this directive as a stop-gap compatibility change to let HTML Purifier +deal with non UTF-8 input. This technique has notable deficiencies: +absolutely no characters outside of the selected character encoding will be +preserved, not even the ones that have been ampersand escaped (this is due +to a UTF-8 specific feature that automatically resolves all +entities), making it pretty useless for anything except the most I18N-blind +applications, although %Core.EscapeNonASCIICharacters offers fixes this +trouble with another tradeoff. This directive only accepts ISO-8859-1 if +iconv is not enabled. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt new file mode 100644 index 00000000..4d5b5055 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt @@ -0,0 +1,10 @@ +Core.EscapeInvalidChildren +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When true, a child is found that is not allowed in the context of the +parent element will be transformed into text as if it were ASCII. When +false, that element and all internal tags will be dropped, though text will +be preserved. There is no option for dropping the element but preserving +child nodes. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt new file mode 100644 index 00000000..a7a5b249 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt @@ -0,0 +1,7 @@ +Core.EscapeInvalidTags +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When true, invalid tags will be written back to the document as plain text. +Otherwise, they are silently dropped. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt new file mode 100644 index 00000000..abb49994 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt @@ -0,0 +1,13 @@ +Core.EscapeNonASCIICharacters +TYPE: bool +VERSION: 1.4.0 +DEFAULT: false +--DESCRIPTION-- +This directive overcomes a deficiency in %Core.Encoding by blindly +converting all non-ASCII characters into decimal numeric entities before +converting it to its native encoding. This means that even characters that +can be expressed in the non-UTF-8 encoding will be entity-ized, which can +be a real downer for encodings like Big5. It also assumes that the ASCII +repetoire is available, although this is the case for almost all encodings. +Anyway, use UTF-8! +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt new file mode 100644 index 00000000..915391ed --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt @@ -0,0 +1,19 @@ +Core.HiddenElements +TYPE: lookup +--DEFAULT-- +array ( + 'script' => true, + 'style' => true, +) +--DESCRIPTION-- + +

        + This directive is a lookup array of elements which should have their + contents removed when they are not allowed by the HTML definition. + For example, the contents of a script tag are not + normally shown in a document, so if script tags are to be removed, + their contents should be removed to. This is opposed to a b + tag, which defines some presentational changes but does not hide its + contents. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt new file mode 100644 index 00000000..233fca14 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt @@ -0,0 +1,10 @@ +Core.Language +TYPE: string +VERSION: 2.0.0 +DEFAULT: 'en' +--DESCRIPTION-- + +ISO 639 language code for localizable things in HTML Purifier to use, +which is mainly error reporting. There is currently only an English (en) +translation, so this directive is currently useless. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt new file mode 100644 index 00000000..8983e2cc --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt @@ -0,0 +1,34 @@ +Core.LexerImpl +TYPE: mixed/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + This parameter determines what lexer implementation can be used. The + valid values are: +

        +
        +
        null
        +
        + Recommended, the lexer implementation will be auto-detected based on + your PHP-version and configuration. +
        +
        string lexer identifier
        +
        + This is a slim way of manually overridding the implementation. + Currently recognized values are: DOMLex (the default PHP5 +implementation) + and DirectLex (the default PHP4 implementation). Only use this if + you know what you are doing: usually, the auto-detection will + manage things for cases you aren't even aware of. +
        +
        object lexer instance
        +
        + Super-advanced: you can specify your own, custom, implementation that + implements the interface defined by HTMLPurifier_Lexer. + I may remove this option simply because I don't expect anyone + to use it. +
        +
        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt new file mode 100644 index 00000000..eb841a75 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt @@ -0,0 +1,16 @@ +Core.MaintainLineNumbers +TYPE: bool/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If true, HTML Purifier will add line number information to all tokens. + This is useful when error reporting is turned on, but can result in + significant performance degradation and should not be used when + unnecessary. This directive must be used with the DirectLex lexer, + as the DOMLex lexer does not (yet) support this functionality. + If the value is null, an appropriate value will be selected based + on other configuration. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt new file mode 100644 index 00000000..4070c2a0 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt @@ -0,0 +1,12 @@ +Core.RemoveInvalidImg +TYPE: bool +DEFAULT: true +VERSION: 1.3.0 +--DESCRIPTION-- + +

        + This directive enables pre-emptive URI checking in img + tags, as the attribute validation strategy is not authorized to + remove elements from the document. Revert to pre-1.3.0 behavior by setting to false. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt new file mode 100644 index 00000000..a4cd966d --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt @@ -0,0 +1,12 @@ +Core.RemoveScriptContents +TYPE: bool/null +DEFAULT: NULL +VERSION: 2.0.0 +DEPRECATED-VERSION: 2.1.0 +DEPRECATED-USE: Core.HiddenElements +--DESCRIPTION-- +

        + This directive enables HTML Purifier to remove not only script tags + but all of their contents. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt new file mode 100644 index 00000000..3db50ef2 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt @@ -0,0 +1,11 @@ +Filter.Custom +TYPE: list +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This directive can be used to add custom filters; it is nearly the + equivalent of the now deprecated HTMLPurifier->addFilter() + method. Specify an array of concrete implementations. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt new file mode 100644 index 00000000..16829bcd --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt @@ -0,0 +1,14 @@ +Filter.ExtractStyleBlocks.Escaping +TYPE: bool +VERSION: 3.0.0 +DEFAULT: true +ALIASES: Filter.ExtractStyleBlocksEscaping, FilterParam.ExtractStyleBlocksEscaping +--DESCRIPTION-- + +

        + Whether or not to escape the dangerous characters <, > and & + as \3C, \3E and \26, respectively. This is can be safely set to false + if the contents of StyleBlocks will be placed in an external stylesheet, + where there is no risk of it being interpreted as HTML. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt new file mode 100644 index 00000000..7f95f54d --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt @@ -0,0 +1,29 @@ +Filter.ExtractStyleBlocks.Scope +TYPE: string/null +VERSION: 3.0.0 +DEFAULT: NULL +ALIASES: Filter.ExtractStyleBlocksScope, FilterParam.ExtractStyleBlocksScope +--DESCRIPTION-- + +

        + If you would like users to be able to define external stylesheets, but + only allow them to specify CSS declarations for a specific node and + prevent them from fiddling with other elements, use this directive. + It accepts any valid CSS selector, and will prepend this to any + CSS declaration extracted from the document. For example, if this + directive is set to #user-content and a user uses the + selector a:hover, the final selector will be + #user-content a:hover. +

        +

        + The comma shorthand may be used; consider the above example, with + #user-content, #user-content2, the final selector will + be #user-content a:hover, #user-content2 a:hover. +

        +

        + Warning: It is possible for users to bypass this measure + using a naughty + selector. This is a bug in CSS Tidy 1.3, not HTML + Purifier, and I am working to get it fixed. Until then, HTML Purifier + performs a basic check to prevent this. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt new file mode 100644 index 00000000..6c231b2d --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt @@ -0,0 +1,16 @@ +Filter.ExtractStyleBlocks.TidyImpl +TYPE: mixed/null +VERSION: 3.1.0 +DEFAULT: NULL +ALIASES: FilterParam.ExtractStyleBlocksTidyImpl +--DESCRIPTION-- +

        + If left NULL, HTML Purifier will attempt to instantiate a csstidy + class to use for internal cleaning. This will usually be good enough. +

        +

        + However, for trusted user input, you can set this to false to + disable cleaning. In addition, you can supply your own concrete implementation + of Tidy's interface to use, although I don't know why you'd want to do that. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt new file mode 100644 index 00000000..078d0874 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt @@ -0,0 +1,74 @@ +Filter.ExtractStyleBlocks +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +EXTERNAL: CSSTidy +--DESCRIPTION-- +

        + This directive turns on the style block extraction filter, which removes + style blocks from input HTML, cleans them up with CSSTidy, + and places them in the StyleBlocks context variable, for further + use by you, usually to be placed in an external stylesheet, or a + style block in the head of your document. +

        +

        + Sample usage: +

        +
        ';
        +?>
        +
        +
        +
        +  Filter.ExtractStyleBlocks
        +body {color:#F00;} Some text';
        +
        +    $config = HTMLPurifier_Config::createDefault();
        +    $config->set('Filter', 'ExtractStyleBlocks', true);
        +    $purifier = new HTMLPurifier($config);
        +
        +    $html = $purifier->purify($dirty);
        +
        +    // This implementation writes the stylesheets to the styles/ directory.
        +    // You can also echo the styles inside the document, but it's a bit
        +    // more difficult to make sure they get interpreted properly by
        +    // browsers; try the usual CSS armoring techniques.
        +    $styles = $purifier->context->get('StyleBlocks');
        +    $dir = 'styles/';
        +    if (!is_dir($dir)) mkdir($dir);
        +    $hash = sha1($_GET['html']);
        +    foreach ($styles as $i => $style) {
        +        file_put_contents($name = $dir . $hash . "_$i");
        +        echo '';
        +    }
        +?>
        +
        +
        +  
        + +
        + + +]]>
        +

        + Warning: It is possible for a user to mount an + imagecrash attack using this CSS. Counter-measures are difficult; + it is not simply enough to limit the range of CSS lengths (using + relative lengths with many nesting levels allows for large values + to be attained without actually specifying them in the stylesheet), + and the flexible nature of selectors makes it difficult to selectively + disable lengths on image tags (HTML Purifier, however, does disable + CSS width and height in inline styling). There are probably two effective + counter measures: an explicit width and height set to auto in all + images in your document (unlikely) or the disabling of width and + height (somewhat reasonable). Whether or not these measures should be + used is left to the reader. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt new file mode 100644 index 00000000..7fa6536b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt @@ -0,0 +1,11 @@ +Filter.YouTube +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + This directive enables YouTube video embedding in HTML Purifier. Check + this document + on embedding videos for more information on what this filter does. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt new file mode 100644 index 00000000..3e231d2d --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt @@ -0,0 +1,22 @@ +HTML.Allowed +TYPE: itext/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + This is a convenience directive that rolls the functionality of + %HTML.AllowedElements and %HTML.AllowedAttributes into one directive. + Specify elements and attributes that are allowed using: + element1[attr1|attr2],element2.... You can also use + newlines instead of commas to separate elements. +

        +

        + Warning: + All of the constraints on the component directives are still enforced. + The syntax is a subset of TinyMCE's valid_elements + whitelist: directly copy-pasting it here will probably result in + broken whitelists. If %HTML.AllowedElements or %HTML.AllowedAttributes + are set, this directive has no effect. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt new file mode 100644 index 00000000..fcf093f1 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt @@ -0,0 +1,19 @@ +HTML.AllowedAttributes +TYPE: lookup/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If HTML Purifier's attribute set is unsatisfactory, overload it! + The syntax is "tag.attr" or "*.attr" for the global attributes + (style, id, class, dir, lang, xml:lang). +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. For + example, %HTML.EnableAttrID will take precedence over *.id in this + directive. You must set that directive to true before you can use + IDs at all. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt new file mode 100644 index 00000000..888d5581 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt @@ -0,0 +1,18 @@ +HTML.AllowedElements +TYPE: lookup/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + If HTML Purifier's tag set is unsatisfactory for your needs, you + can overload it with your own list of tags to allow. Note that this + method is subtractive: it does its job by taking away from HTML Purifier + usual feature set, so you cannot add a tag that HTML Purifier never + supported in the first place (like embed, form or head). If you + change this, you probably also want to change %HTML.AllowedAttributes. +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt new file mode 100644 index 00000000..5a59a55c --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt @@ -0,0 +1,20 @@ +HTML.AllowedModules +TYPE: lookup/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + A doctype comes with a set of usual modules to use. Without having + to mucking about with the doctypes, you can quickly activate or + disable these modules by specifying which modules you wish to allow + with this directive. This is most useful for unit testing specific + modules, although end users may find it useful for their own ends. +

        +

        + If you specify a module that does not exist, the manager will silently + fail to use it, so be careful! User-defined modules are not affected + by this directive. Modules defined in %HTML.CoreModules are not + affected by this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt new file mode 100644 index 00000000..151fb7b8 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt @@ -0,0 +1,11 @@ +HTML.Attr.Name.UseCDATA +TYPE: bool +DEFAULT: false +VERSION: 4.0.0 +--DESCRIPTION-- +The W3C specification DTD defines the name attribute to be CDATA, not ID, due +to limitations of DTD. In certain documents, this relaxed behavior is desired, +whether it is to specify duplicate names, or to specify names that would be +illegal IDs (for example, names that begin with a digit.) Set this configuration +directive to true to use the relaxed parsing rules. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt new file mode 100644 index 00000000..45ae469e --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt @@ -0,0 +1,18 @@ +HTML.BlockWrapper +TYPE: string +VERSION: 1.3.0 +DEFAULT: 'p' +--DESCRIPTION-- + +

        + String name of element to wrap inline elements that are inside a block + context. This only occurs in the children of blockquote in strict mode. +

        +

        + Example: by default value, + <blockquote>Foo</blockquote> would become + <blockquote><p>Foo</p></blockquote>. + The <p> tags can be replaced with whatever you desire, + as long as it is a block level element. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt new file mode 100644 index 00000000..52461887 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt @@ -0,0 +1,23 @@ +HTML.CoreModules +TYPE: lookup +VERSION: 2.0.0 +--DEFAULT-- +array ( + 'Structure' => true, + 'Text' => true, + 'Hypertext' => true, + 'List' => true, + 'NonXMLCommonAttributes' => true, + 'XMLCommonAttributes' => true, + 'CommonAttributes' => true, +) +--DESCRIPTION-- + +

        + Certain modularized doctypes (XHTML, namely), have certain modules + that must be included for the doctype to be an conforming document + type: put those modules here. By default, XHTML's core modules + are used. You can set this to a blank array to disable core module + protection, but this is not recommended. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt new file mode 100644 index 00000000..a64e3d7c --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt @@ -0,0 +1,9 @@ +HTML.CustomDoctype +TYPE: string/null +VERSION: 2.0.1 +DEFAULT: NULL +--DESCRIPTION-- + +A custom doctype for power-users who defined there own document +type. This directive only applies when %HTML.Doctype is blank. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt new file mode 100644 index 00000000..103db754 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt @@ -0,0 +1,33 @@ +HTML.DefinitionID +TYPE: string/null +DEFAULT: NULL +VERSION: 2.0.0 +--DESCRIPTION-- + +

        + Unique identifier for a custom-built HTML definition. If you edit + the raw version of the HTMLDefinition, introducing changes that the + configuration object does not reflect, you must specify this variable. + If you change your custom edits, you should change this directive, or + clear your cache. Example: +

        +
        +$config = HTMLPurifier_Config::createDefault();
        +$config->set('HTML', 'DefinitionID', '1');
        +$def = $config->getHTMLDefinition();
        +$def->addAttribute('a', 'tabindex', 'Number');
        +
        +

        + In the above example, the configuration is still at the defaults, but + using the advanced API, an extra attribute has been added. The + configuration object normally has no way of knowing that this change + has taken place, so it needs an extra directive: %HTML.DefinitionID. + If someone else attempts to use the default configuration, these two + pieces of code will not clobber each other in the cache, since one has + an extra directive attached to it. +

        +

        + You must specify a value to this directive to use the + advanced API features. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt new file mode 100644 index 00000000..229ae026 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt @@ -0,0 +1,16 @@ +HTML.DefinitionRev +TYPE: int +VERSION: 2.0.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition specified in + %HTML.DefinitionID. This serves the same purpose: uniquely identifying + your custom definition, but this one does so in a chronological + context: revision 3 is more up-to-date then revision 2. Thus, when + this gets incremented, the cache handling is smart enough to clean + up any older revisions of your definition as well as flush the + cache. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt new file mode 100644 index 00000000..9dab497f --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt @@ -0,0 +1,11 @@ +HTML.Doctype +TYPE: string/null +DEFAULT: NULL +--DESCRIPTION-- +Doctype to use during filtering. Technically speaking this is not actually +a doctype (as it does not identify a corresponding DTD), but we are using +this name for sake of simplicity. When non-blank, this will override any +older directives like %HTML.XHTML or %HTML.Strict. +--ALLOWED-- +'HTML 4.01 Transitional', 'HTML 4.01 Strict', 'XHTML 1.0 Transitional', 'XHTML 1.0 Strict', 'XHTML 1.1' +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt new file mode 100644 index 00000000..57358f9b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt @@ -0,0 +1,21 @@ +HTML.ForbiddenAttributes +TYPE: lookup +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + While this directive is similar to %HTML.AllowedAttributes, for + forwards-compatibility with XML, this attribute has a different syntax. Instead of + tag.attr, use tag@attr. To disallow href + attributes in a tags, set this directive to + a@href. You can also disallow an attribute globally with + attr or *@attr (either syntax is fine; the latter + is provided for consistency with %HTML.AllowedAttributes). +

        +

        + Warning: This directive complements %HTML.ForbiddenElements, + accordingly, check + out that directive for a discussion of why you + should think twice before using this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt new file mode 100644 index 00000000..93a53e14 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt @@ -0,0 +1,20 @@ +HTML.ForbiddenElements +TYPE: lookup +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This was, perhaps, the most requested feature ever in HTML + Purifier. Please don't abuse it! This is the logical inverse of + %HTML.AllowedElements, and it will override that directive, or any + other directive. +

        +

        + If possible, %HTML.Allowed is recommended over this directive, because it + can sometimes be difficult to tell whether or not you've forbidden all of + the behavior you would like to disallow. If you forbid img + with the expectation of preventing images on your site, you'll be in for + a nasty surprise when people start using the background-image + CSS property. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt new file mode 100644 index 00000000..e424c386 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt @@ -0,0 +1,14 @@ +HTML.MaxImgLength +TYPE: int/null +DEFAULT: 1200 +VERSION: 3.1.1 +--DESCRIPTION-- +

        + This directive controls the maximum number of pixels in the width and + height attributes in img tags. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %CSS.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the HTML max is an integer). +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt new file mode 100644 index 00000000..62e8e160 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt @@ -0,0 +1,12 @@ +HTML.Parent +TYPE: string +VERSION: 1.3.0 +DEFAULT: 'div' +--DESCRIPTION-- + +

        + String name of element that HTML fragment passed to library will be + inserted in. An interesting variation would be using span as the + parent element, meaning that only inline tags would be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt new file mode 100644 index 00000000..dfb72049 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt @@ -0,0 +1,12 @@ +HTML.Proprietary +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to allow proprietary elements and attributes in your + documents, as per HTMLPurifier_HTMLModule_Proprietary. + Warning: This can cause your documents to stop + validating! +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt new file mode 100644 index 00000000..cdda09a4 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt @@ -0,0 +1,13 @@ +HTML.SafeEmbed +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit embed tags in documents, with a number of extra + security features added to prevent script execution. This is similar to + what websites like MySpace do to embed tags. Embed is a proprietary + element and will cause your website to stop validating; you should + see if you can use %Output.FlashCompat with %HTML.SafeObject instead + first.

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt new file mode 100644 index 00000000..ceb342e2 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt @@ -0,0 +1,13 @@ +HTML.SafeObject +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit object tags in documents, with a number of extra + security features added to prevent script execution. This is similar to + what websites like MySpace do to object tags. You should also enable + %Output.FlashCompat in order to generate Internet Explorer + compatibility code for your object tags. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt new file mode 100644 index 00000000..a8b1de56 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt @@ -0,0 +1,9 @@ +HTML.Strict +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +DEPRECATED-VERSION: 1.7.0 +DEPRECATED-USE: HTML.Doctype +--DESCRIPTION-- +Determines whether or not to use Transitional (loose) or Strict rulesets. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt new file mode 100644 index 00000000..b4c271b7 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt @@ -0,0 +1,8 @@ +HTML.TidyAdd +TYPE: lookup +VERSION: 2.0.0 +DEFAULT: array() +--DESCRIPTION-- + +Fixes to add to the default set of Tidy fixes as per your level. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt new file mode 100644 index 00000000..4186ccd0 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt @@ -0,0 +1,24 @@ +HTML.TidyLevel +TYPE: string +VERSION: 2.0.0 +DEFAULT: 'medium' +--DESCRIPTION-- + +

        General level of cleanliness the Tidy module should enforce. +There are four allowed values:

        +
        +
        none
        +
        No extra tidying should be done
        +
        light
        +
        Only fix elements that would be discarded otherwise due to + lack of support in doctype
        +
        medium
        +
        Enforce best practices
        +
        heavy
        +
        Transform all deprecated elements and attributes to standards + compliant equivalents
        +
        + +--ALLOWED-- +'none', 'light', 'medium', 'heavy' +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt new file mode 100644 index 00000000..996762bd --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt @@ -0,0 +1,8 @@ +HTML.TidyRemove +TYPE: lookup +VERSION: 2.0.0 +DEFAULT: array() +--DESCRIPTION-- + +Fixes to remove from the default set of Tidy fixes as per your level. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt new file mode 100644 index 00000000..89133b1a --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt @@ -0,0 +1,8 @@ +HTML.Trusted +TYPE: bool +VERSION: 2.0.0 +DEFAULT: false +--DESCRIPTION-- +Indicates whether or not the user input is trusted or not. If the input is +trusted, a more expansive set of allowed tags and attributes will be used. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt new file mode 100644 index 00000000..2a47e384 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt @@ -0,0 +1,11 @@ +HTML.XHTML +TYPE: bool +DEFAULT: true +VERSION: 1.1.0 +DEPRECATED-VERSION: 1.7.0 +DEPRECATED-USE: HTML.Doctype +--DESCRIPTION-- +Determines whether or not output is XHTML 1.0 or HTML 4.01 flavor. +--ALIASES-- +Core.XHTML +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt new file mode 100644 index 00000000..08921fde --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt @@ -0,0 +1,10 @@ +Output.CommentScriptContents +TYPE: bool +VERSION: 2.0.0 +DEFAULT: true +--DESCRIPTION-- +Determines whether or not HTML Purifier should attempt to fix up the +contents of script tags for legacy browsers with comments. +--ALIASES-- +Core.CommentScriptContents +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt new file mode 100644 index 00000000..93398e85 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt @@ -0,0 +1,11 @@ +Output.FlashCompat +TYPE: bool +VERSION: 4.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + If true, HTML Purifier will generate Internet Explorer compatibility + code for all object code. This is highly recommended if you enable + %HTML.SafeObject. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt new file mode 100644 index 00000000..79f8ad82 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt @@ -0,0 +1,13 @@ +Output.Newline +TYPE: string/null +VERSION: 2.0.1 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Newline string to format final output with. If left null, HTML Purifier + will auto-detect the default newline type of the system and use that; + you can manually override it here. Remember, \r\n is Windows, \r + is Mac, and \n is Unix. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt new file mode 100644 index 00000000..232b0236 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt @@ -0,0 +1,14 @@ +Output.SortAttr +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + If true, HTML Purifier will sort attributes by name before writing them back + to the document, converting a tag like: <el b="" a="" c="" /> + to <el a="" b="" c="" />. This is a workaround for + a bug in FCKeditor which causes it to swap attributes order, adding noise + to text diffs. If you're not seeing this bug, chances are, you don't need + this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt new file mode 100644 index 00000000..06bab00a --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt @@ -0,0 +1,25 @@ +Output.TidyFormat +TYPE: bool +VERSION: 1.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Determines whether or not to run Tidy on the final output for pretty + formatting reasons, such as indentation and wrap. +

        +

        + This can greatly improve readability for editors who are hand-editing + the HTML, but is by no means necessary as HTML Purifier has already + fixed all major errors the HTML may have had. Tidy is a non-default + extension, and this directive will silently fail if Tidy is not + available. +

        +

        + If you are looking to make the overall look of your page's source + better, I recommend running Tidy on the entire page rather than just + user-content (after all, the indentation relative to the containing + blocks will be incorrect). +

        +--ALIASES-- +Core.TidyFormat +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt new file mode 100644 index 00000000..071bc029 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt @@ -0,0 +1,7 @@ +Test.ForceNoIconv +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When set to true, HTMLPurifier_Encoder will act as if iconv does not exist +and use only pure PHP implementations. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt new file mode 100644 index 00000000..ae3a913f --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt @@ -0,0 +1,17 @@ +URI.AllowedSchemes +TYPE: lookup +--DEFAULT-- +array ( + 'http' => true, + 'https' => true, + 'mailto' => true, + 'ftp' => true, + 'nntp' => true, + 'news' => true, +) +--DESCRIPTION-- +Whitelist that defines the schemes that a URI is allowed to have. This +prevents XSS attacks from using pseudo-schemes like javascript or mocha. +There is also support for the data URI scheme, but it is not +enabled by default. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt new file mode 100644 index 00000000..876f0680 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt @@ -0,0 +1,17 @@ +URI.Base +TYPE: string/null +VERSION: 2.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + The base URI is the URI of the document this purified HTML will be + inserted into. This information is important if HTML Purifier needs + to calculate absolute URIs from relative URIs, such as when %URI.MakeAbsolute + is on. You may use a non-absolute URI for this value, but behavior + may vary (%URI.MakeAbsolute deals nicely with both absolute and + relative paths, but forwards-compatibility is not guaranteed). + Warning: If set, the scheme on this URI + overrides the one specified by %URI.DefaultScheme. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt new file mode 100644 index 00000000..728e378c --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt @@ -0,0 +1,10 @@ +URI.DefaultScheme +TYPE: string +DEFAULT: 'http' +--DESCRIPTION-- + +

        + Defines through what scheme the output will be served, in order to + select the proper object validator when no scheme information is present. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt new file mode 100644 index 00000000..f05312ba --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt @@ -0,0 +1,11 @@ +URI.DefinitionID +TYPE: string/null +VERSION: 2.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Unique identifier for a custom-built URI definition. If you want + to add custom URIFilters, you must specify this value. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt new file mode 100644 index 00000000..80cfea93 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt @@ -0,0 +1,11 @@ +URI.DefinitionRev +TYPE: int +VERSION: 2.1.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition. See + %HTML.DefinitionRev for details. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt new file mode 100644 index 00000000..71ce025a --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt @@ -0,0 +1,14 @@ +URI.Disable +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Disables all URIs in all forms. Not sure why you'd want to do that + (after all, the Internet's founded on the notion of a hyperlink). +

        + +--ALIASES-- +Attr.DisableURI +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt new file mode 100644 index 00000000..13c122c8 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt @@ -0,0 +1,11 @@ +URI.DisableExternal +TYPE: bool +VERSION: 1.2.0 +DEFAULT: false +--DESCRIPTION-- +Disables links to external websites. This is a highly effective anti-spam +and anti-pagerank-leech measure, but comes at a hefty price: nolinks or +images outside of your domain will be allowed. Non-linkified URIs will +still be preserved. If you want to be able to link to subdomains or use +absolute URIs, specify %URI.Host for your website. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt new file mode 100644 index 00000000..abcc1efd --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt @@ -0,0 +1,13 @@ +URI.DisableExternalResources +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- +Disables the embedding of external resources, preventing users from +embedding things like images from other hosts. This prevents access +tracking (good for email viewers), bandwidth leeching, cross-site request +forging, goatse.cx posting, and other nasties, but also results in a loss +of end-user functionality (they can't directly post a pic they posted from +Flickr anymore). Use it if you don't have a robust user-content moderation +team. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt new file mode 100644 index 00000000..51e6ea91 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt @@ -0,0 +1,12 @@ +URI.DisableResources +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Disables embedding resources, essentially meaning no pictures. You can + still link to them though. See %URI.DisableExternalResources for why + this might be a good idea. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt new file mode 100644 index 00000000..ee83b121 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt @@ -0,0 +1,19 @@ +URI.Host +TYPE: string/null +VERSION: 1.2.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Defines the domain name of the server, so we can determine whether or + an absolute URI is from your website or not. Not strictly necessary, + as users should be using relative URIs to reference resources on your + website. It will, however, let you use absolute URIs to link to + subdomains of the domain you post here: i.e. example.com will allow + sub.example.com. However, higher up domains will still be excluded: + if you set %URI.Host to sub.example.com, example.com will be blocked. + Note: This directive overrides %URI.Base because + a given page may be on a sub-domain, but you wish HTML Purifier to be + more relaxed and allow some of the parent domains too. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt new file mode 100644 index 00000000..0b6df762 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt @@ -0,0 +1,9 @@ +URI.HostBlacklist +TYPE: list +VERSION: 1.3.0 +DEFAULT: array() +--DESCRIPTION-- +List of strings that are forbidden in the host of any URI. Use it to kill +domain names of spam, etc. Note that it will catch anything in the domain, +so moo.com will catch moo.com.example.com. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt new file mode 100644 index 00000000..4214900a --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt @@ -0,0 +1,13 @@ +URI.MakeAbsolute +TYPE: bool +VERSION: 2.1.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Converts all URIs into absolute forms. This is useful when the HTML + being filtered assumes a specific base path, but will actually be + viewed in a different context (and setting an alternate base URI is + not possible). %URI.Base must be set for this directive to work. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt new file mode 100644 index 00000000..58c81dcc --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt @@ -0,0 +1,83 @@ +URI.Munge +TYPE: string/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Munges all browsable (usually http, https and ftp) + absolute URIs into another URI, usually a URI redirection service. + This directive accepts a URI, formatted with a %s where + the url-encoded original URI should be inserted (sample: + http://www.google.com/url?q=%s). +

        +

        + Uses for this directive: +

        +
          +
        • + Prevent PageRank leaks, while being fairly transparent + to users (you may also want to add some client side JavaScript to + override the text in the statusbar). Notice: + Many security experts believe that this form of protection does not deter spam-bots. +
        • +
        • + Redirect users to a splash page telling them they are leaving your + website. While this is poor usability practice, it is often mandated + in corporate environments. +
        • +
        +

        + Prior to HTML Purifier 3.1.1, this directive also enabled the munging + of browsable external resources, which could break things if your redirection + script was a splash page or used meta tags. To revert to + previous behavior, please use %URI.MungeResources. +

        +

        + You may want to also use %URI.MungeSecretKey along with this directive + in order to enforce what URIs your redirector script allows. Open + redirector scripts can be a security risk and negatively affect the + reputation of your domain name. +

        +

        + Starting with HTML Purifier 3.1.1, there is also these substitutions: +

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        KeyDescriptionExample <a href="">
        %r1 - The URI embeds a resource
        (blank) - The URI is merely a link
        %nThe name of the tag this URI came froma
        %mThe name of the attribute this URI came fromhref
        %pThe name of the CSS property this URI came from, or blank if irrelevant
        +

        + Admittedly, these letters are somewhat arbitrary; the only stipulation + was that they couldn't be a through f. r is for resource (I would have preferred + e, but you take what you can get), n is for name, m + was picked because it came after n (and I couldn't use a), p is for + property. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt new file mode 100644 index 00000000..6fce0fdc --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt @@ -0,0 +1,17 @@ +URI.MungeResources +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + If true, any URI munging directives like %URI.Munge + will also apply to embedded resources, such as <img src="">. + Be careful enabling this directive if you have a redirector script + that does not use the Location HTTP header; all of your images + and other embedded resources will break. +

        +

        + Warning: It is strongly advised you use this in conjunction + %URI.MungeSecretKey to mitigate the security risk of an open redirector. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt new file mode 100644 index 00000000..0d00f62e --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt @@ -0,0 +1,30 @@ +URI.MungeSecretKey +TYPE: string/null +VERSION: 3.1.1 +DEFAULT: NULL +--DESCRIPTION-- +

        + This directive enables secure checksum generation along with %URI.Munge. + It should be set to a secure key that is not shared with anyone else. + The checksum can be placed in the URI using %t. Use of this checksum + affords an additional level of protection by allowing a redirector + to check if a URI has passed through HTML Purifier with this line: +

        + +
        $checksum === sha1($secret_key . ':' . $url)
        + +

        + If the output is TRUE, the redirector script should accept the URI. +

        + +

        + Please note that it would still be possible for an attacker to procure + secure hashes en-mass by abusing your website's Preview feature or the + like, but this service affords an additional level of protection + that should be combined with website blacklisting. +

        + +

        + Remember this has no effect if %URI.Munge is not on. +

        +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt new file mode 100644 index 00000000..23331a4e --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt @@ -0,0 +1,9 @@ +URI.OverrideAllowedSchemes +TYPE: bool +DEFAULT: true +--DESCRIPTION-- +If this is set to true (which it is by default), you can override +%URI.AllowedSchemes by simply registering a HTMLPurifier_URIScheme to the +registry. If false, you will also have to update that directive in order +to add more schemes. +--# vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/info.ini b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/info.ini new file mode 100644 index 00000000..5de4505e --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/ConfigSchema/schema/info.ini @@ -0,0 +1,3 @@ +name = "HTML Purifier" + +; vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/EntityLookup/entities.ser b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/EntityLookup/entities.ser new file mode 100644 index 00000000..f2b8b8f2 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/EntityLookup/entities.ser @@ -0,0 +1 @@ +a:246:{s:4:"nbsp";s:2:" ";s:5:"iexcl";s:2:"¡";s:4:"cent";s:2:"¢";s:5:"pound";s:2:"£";s:6:"curren";s:2:"¤";s:3:"yen";s:2:"Â¥";s:6:"brvbar";s:2:"¦";s:4:"sect";s:2:"§";s:3:"uml";s:2:"¨";s:4:"copy";s:2:"©";s:4:"ordf";s:2:"ª";s:5:"laquo";s:2:"«";s:3:"not";s:2:"¬";s:3:"shy";s:2:"­";s:3:"reg";s:2:"®";s:4:"macr";s:2:"¯";s:3:"deg";s:2:"°";s:6:"plusmn";s:2:"±";s:5:"acute";s:2:"´";s:5:"micro";s:2:"µ";s:4:"para";s:2:"¶";s:6:"middot";s:2:"·";s:5:"cedil";s:2:"¸";s:4:"ordm";s:2:"º";s:5:"raquo";s:2:"»";s:6:"iquest";s:2:"¿";s:6:"Agrave";s:2:"À";s:6:"Aacute";s:2:"Ã";s:5:"Acirc";s:2:"Â";s:6:"Atilde";s:2:"Ã";s:4:"Auml";s:2:"Ä";s:5:"Aring";s:2:"Ã…";s:5:"AElig";s:2:"Æ";s:6:"Ccedil";s:2:"Ç";s:6:"Egrave";s:2:"È";s:6:"Eacute";s:2:"É";s:5:"Ecirc";s:2:"Ê";s:4:"Euml";s:2:"Ë";s:6:"Igrave";s:2:"ÃŒ";s:6:"Iacute";s:2:"Ã";s:5:"Icirc";s:2:"ÃŽ";s:4:"Iuml";s:2:"Ã";s:3:"ETH";s:2:"Ã";s:6:"Ntilde";s:2:"Ñ";s:6:"Ograve";s:2:"Ã’";s:6:"Oacute";s:2:"Ó";s:5:"Ocirc";s:2:"Ô";s:6:"Otilde";s:2:"Õ";s:4:"Ouml";s:2:"Ö";s:5:"times";s:2:"×";s:6:"Oslash";s:2:"Ø";s:6:"Ugrave";s:2:"Ù";s:6:"Uacute";s:2:"Ú";s:5:"Ucirc";s:2:"Û";s:4:"Uuml";s:2:"Ãœ";s:6:"Yacute";s:2:"Ã";s:5:"THORN";s:2:"Þ";s:5:"szlig";s:2:"ß";s:6:"agrave";s:2:"à";s:6:"aacute";s:2:"á";s:5:"acirc";s:2:"â";s:6:"atilde";s:2:"ã";s:4:"auml";s:2:"ä";s:5:"aring";s:2:"Ã¥";s:5:"aelig";s:2:"æ";s:6:"ccedil";s:2:"ç";s:6:"egrave";s:2:"è";s:6:"eacute";s:2:"é";s:5:"ecirc";s:2:"ê";s:4:"euml";s:2:"ë";s:6:"igrave";s:2:"ì";s:6:"iacute";s:2:"í";s:5:"icirc";s:2:"î";s:4:"iuml";s:2:"ï";s:3:"eth";s:2:"ð";s:6:"ntilde";s:2:"ñ";s:6:"ograve";s:2:"ò";s:6:"oacute";s:2:"ó";s:5:"ocirc";s:2:"ô";s:6:"otilde";s:2:"õ";s:4:"ouml";s:2:"ö";s:6:"divide";s:2:"÷";s:6:"oslash";s:2:"ø";s:6:"ugrave";s:2:"ù";s:6:"uacute";s:2:"ú";s:5:"ucirc";s:2:"û";s:4:"uuml";s:2:"ü";s:6:"yacute";s:2:"ý";s:5:"thorn";s:2:"þ";s:4:"yuml";s:2:"ÿ";s:4:"quot";s:1:""";s:3:"amp";s:1:"&";s:2:"lt";s:1:"<";s:2:"gt";s:1:">";s:4:"apos";s:1:"'";s:5:"OElig";s:2:"Å’";s:5:"oelig";s:2:"Å“";s:6:"Scaron";s:2:"Å ";s:6:"scaron";s:2:"Å¡";s:4:"Yuml";s:2:"Ÿ";s:4:"circ";s:2:"ˆ";s:5:"tilde";s:2:"Ëœ";s:4:"ensp";s:3:" ";s:4:"emsp";s:3:" ";s:6:"thinsp";s:3:" ";s:4:"zwnj";s:3:"‌";s:3:"zwj";s:3:"â€";s:3:"lrm";s:3:"‎";s:3:"rlm";s:3:"â€";s:5:"ndash";s:3:"–";s:5:"mdash";s:3:"—";s:5:"lsquo";s:3:"‘";s:5:"rsquo";s:3:"’";s:5:"sbquo";s:3:"‚";s:5:"ldquo";s:3:"“";s:5:"rdquo";s:3:"â€";s:5:"bdquo";s:3:"„";s:6:"dagger";s:3:"†";s:6:"Dagger";s:3:"‡";s:6:"permil";s:3:"‰";s:6:"lsaquo";s:3:"‹";s:6:"rsaquo";s:3:"›";s:4:"euro";s:3:"€";s:4:"fnof";s:2:"Æ’";s:5:"Alpha";s:2:"Α";s:4:"Beta";s:2:"Î’";s:5:"Gamma";s:2:"Γ";s:5:"Delta";s:2:"Δ";s:7:"Epsilon";s:2:"Ε";s:4:"Zeta";s:2:"Ζ";s:3:"Eta";s:2:"Η";s:5:"Theta";s:2:"Θ";s:4:"Iota";s:2:"Ι";s:5:"Kappa";s:2:"Κ";s:6:"Lambda";s:2:"Λ";s:2:"Mu";s:2:"Îœ";s:2:"Nu";s:2:"Î";s:2:"Xi";s:2:"Ξ";s:7:"Omicron";s:2:"Ο";s:2:"Pi";s:2:"Π";s:3:"Rho";s:2:"Ρ";s:5:"Sigma";s:2:"Σ";s:3:"Tau";s:2:"Τ";s:7:"Upsilon";s:2:"Î¥";s:3:"Phi";s:2:"Φ";s:3:"Chi";s:2:"Χ";s:3:"Psi";s:2:"Ψ";s:5:"Omega";s:2:"Ω";s:5:"alpha";s:2:"α";s:4:"beta";s:2:"β";s:5:"gamma";s:2:"γ";s:5:"delta";s:2:"δ";s:7:"epsilon";s:2:"ε";s:4:"zeta";s:2:"ζ";s:3:"eta";s:2:"η";s:5:"theta";s:2:"θ";s:4:"iota";s:2:"ι";s:5:"kappa";s:2:"κ";s:6:"lambda";s:2:"λ";s:2:"mu";s:2:"μ";s:2:"nu";s:2:"ν";s:2:"xi";s:2:"ξ";s:7:"omicron";s:2:"ο";s:2:"pi";s:2:"Ï€";s:3:"rho";s:2:"Ï";s:6:"sigmaf";s:2:"Ï‚";s:5:"sigma";s:2:"σ";s:3:"tau";s:2:"Ï„";s:7:"upsilon";s:2:"Ï…";s:3:"phi";s:2:"φ";s:3:"chi";s:2:"χ";s:3:"psi";s:2:"ψ";s:5:"omega";s:2:"ω";s:8:"thetasym";s:2:"Ï‘";s:5:"upsih";s:2:"Ï’";s:3:"piv";s:2:"Ï–";s:4:"bull";s:3:"•";s:6:"hellip";s:3:"…";s:5:"prime";s:3:"′";s:5:"Prime";s:3:"″";s:5:"oline";s:3:"‾";s:5:"frasl";s:3:"â„";s:6:"weierp";s:3:"℘";s:5:"image";s:3:"â„‘";s:4:"real";s:3:"â„œ";s:5:"trade";s:3:"â„¢";s:7:"alefsym";s:3:"ℵ";s:4:"larr";s:3:"â†";s:4:"uarr";s:3:"↑";s:4:"rarr";s:3:"→";s:4:"darr";s:3:"↓";s:4:"harr";s:3:"↔";s:5:"crarr";s:3:"↵";s:4:"lArr";s:3:"â‡";s:4:"uArr";s:3:"⇑";s:4:"rArr";s:3:"⇒";s:4:"dArr";s:3:"⇓";s:4:"hArr";s:3:"⇔";s:6:"forall";s:3:"∀";s:4:"part";s:3:"∂";s:5:"exist";s:3:"∃";s:5:"empty";s:3:"∅";s:5:"nabla";s:3:"∇";s:4:"isin";s:3:"∈";s:5:"notin";s:3:"∉";s:2:"ni";s:3:"∋";s:4:"prod";s:3:"âˆ";s:3:"sum";s:3:"∑";s:5:"minus";s:3:"−";s:6:"lowast";s:3:"∗";s:5:"radic";s:3:"√";s:4:"prop";s:3:"âˆ";s:5:"infin";s:3:"∞";s:3:"ang";s:3:"∠";s:3:"and";s:3:"∧";s:2:"or";s:3:"∨";s:3:"cap";s:3:"∩";s:3:"cup";s:3:"∪";s:3:"int";s:3:"∫";s:3:"sim";s:3:"∼";s:4:"cong";s:3:"≅";s:5:"asymp";s:3:"≈";s:2:"ne";s:3:"≠";s:5:"equiv";s:3:"≡";s:2:"le";s:3:"≤";s:2:"ge";s:3:"≥";s:3:"sub";s:3:"⊂";s:3:"sup";s:3:"⊃";s:4:"nsub";s:3:"⊄";s:4:"sube";s:3:"⊆";s:4:"supe";s:3:"⊇";s:5:"oplus";s:3:"⊕";s:6:"otimes";s:3:"⊗";s:4:"perp";s:3:"⊥";s:4:"sdot";s:3:"â‹…";s:5:"lceil";s:3:"⌈";s:5:"rceil";s:3:"⌉";s:6:"lfloor";s:3:"⌊";s:6:"rfloor";s:3:"⌋";s:4:"lang";s:3:"〈";s:4:"rang";s:3:"〉";s:3:"loz";s:3:"â—Š";s:6:"spades";s:3:"â™ ";s:5:"clubs";s:3:"♣";s:6:"hearts";s:3:"♥";s:5:"diams";s:3:"♦";} \ No newline at end of file diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php new file mode 100644 index 00000000..bbf78a66 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php @@ -0,0 +1,135 @@ + blocks from input HTML, cleans them up + * using CSSTidy, and then places them in $purifier->context->get('StyleBlocks') + * so they can be used elsewhere in the document. + * + * @note + * See tests/HTMLPurifier/Filter/ExtractStyleBlocksTest.php for + * sample usage. + * + * @note + * This filter can also be used on stylesheets not included in the + * document--something purists would probably prefer. Just directly + * call HTMLPurifier_Filter_ExtractStyleBlocks->cleanCSS() + */ +class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter +{ + + public $name = 'ExtractStyleBlocks'; + private $_styleMatches = array(); + private $_tidy; + + public function __construct() { + $this->_tidy = new csstidy(); + } + + /** + * Save the contents of CSS blocks to style matches + * @param $matches preg_replace style $matches array + */ + protected function styleCallback($matches) { + $this->_styleMatches[] = $matches[1]; + } + + /** + * Removes inline #isU', array($this, 'styleCallback'), $html); + $style_blocks = $this->_styleMatches; + $this->_styleMatches = array(); // reset + $context->register('StyleBlocks', $style_blocks); // $context must not be reused + if ($this->_tidy) { + foreach ($style_blocks as &$style) { + $style = $this->cleanCSS($style, $config, $context); + } + } + return $html; + } + + /** + * Takes CSS (the stuff found in in a font-family prop). + if ($config->get('Filter.ExtractStyleBlocks.Escaping')) { + $css = str_replace( + array('<', '>', '&'), + array('\3C ', '\3E ', '\26 '), + $css + ); + } + return $css; + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Filter/YouTube.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Filter/YouTube.php new file mode 100644 index 00000000..23df221e --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Filter/YouTube.php @@ -0,0 +1,39 @@ +]+>.+?'. + 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?
  • #s'; + $pre_replace = '\1'; + return preg_replace($pre_regex, $pre_replace, $html); + } + + public function postFilter($html, $config, $context) { + $post_regex = '#((?:v|cp)/[A-Za-z0-9\-_=]+)#'; + return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html); + } + + protected function armorUrl($url) { + return str_replace('--', '--', $url); + } + + protected function postFilterCallback($matches) { + $url = $this->armorUrl($matches[1]); + return ''. + ''. + ''. + ''; + + } +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/classes/en-x-test.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/classes/en-x-test.php new file mode 100644 index 00000000..d52fcb7a --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/classes/en-x-test.php @@ -0,0 +1,12 @@ + 'HTML Purifier X' +); + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/messages/en-x-testmini.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/messages/en-x-testmini.php new file mode 100644 index 00000000..806c83fb --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/messages/en-x-testmini.php @@ -0,0 +1,12 @@ + 'HTML Purifier XNone' +); + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/messages/en.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/messages/en.php new file mode 100644 index 00000000..8d7b5736 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Language/messages/en.php @@ -0,0 +1,63 @@ + 'HTML Purifier', + +// for unit testing purposes +'LanguageFactoryTest: Pizza' => 'Pizza', +'LanguageTest: List' => '$1', +'LanguageTest: Hash' => '$1.Keys; $1.Values', + +'Item separator' => ', ', +'Item separator last' => ' and ', // non-Harvard style + +'ErrorCollector: No errors' => 'No errors detected. However, because error reporting is still incomplete, there may have been errors that the error collector was not notified of; please inspect the output HTML carefully.', +'ErrorCollector: At line' => ' at line $line', +'ErrorCollector: Incidental errors' => 'Incidental errors', + +'Lexer: Unclosed comment' => 'Unclosed comment', +'Lexer: Unescaped lt' => 'Unescaped less-than sign (<) should be <', +'Lexer: Missing gt' => 'Missing greater-than sign (>), previous less-than sign (<) should be escaped', +'Lexer: Missing attribute key' => 'Attribute declaration has no key', +'Lexer: Missing end quote' => 'Attribute declaration has no end quote', +'Lexer: Extracted body' => 'Removed document metadata tags', + +'Strategy_RemoveForeignElements: Tag transform' => '<$1> element transformed into $CurrentToken.Serialized', +'Strategy_RemoveForeignElements: Missing required attribute' => '$CurrentToken.Compact element missing required attribute $1', +'Strategy_RemoveForeignElements: Foreign element to text' => 'Unrecognized $CurrentToken.Serialized tag converted to text', +'Strategy_RemoveForeignElements: Foreign element removed' => 'Unrecognized $CurrentToken.Serialized tag removed', +'Strategy_RemoveForeignElements: Comment removed' => 'Comment containing "$CurrentToken.Data" removed', +'Strategy_RemoveForeignElements: Foreign meta element removed' => 'Unrecognized $CurrentToken.Serialized meta tag and all descendants removed', +'Strategy_RemoveForeignElements: Token removed to end' => 'Tags and text starting from $1 element where removed to end', +'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' => 'Trailing hyphen(s) in comment removed', +'Strategy_RemoveForeignElements: Hyphens in comment collapsed' => 'Double hyphens in comments are not allowed, and were collapsed into single hyphens', + +'Strategy_MakeWellFormed: Unnecessary end tag removed' => 'Unnecessary $CurrentToken.Serialized tag removed', +'Strategy_MakeWellFormed: Unnecessary end tag to text' => 'Unnecessary $CurrentToken.Serialized tag converted to text', +'Strategy_MakeWellFormed: Tag auto closed' => '$1.Compact started on line $1.Line auto-closed by $CurrentToken.Compact', +'Strategy_MakeWellFormed: Tag carryover' => '$1.Compact started on line $1.Line auto-continued into $CurrentToken.Compact', +'Strategy_MakeWellFormed: Stray end tag removed' => 'Stray $CurrentToken.Serialized tag removed', +'Strategy_MakeWellFormed: Stray end tag to text' => 'Stray $CurrentToken.Serialized tag converted to text', +'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized', +'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document', + +'Strategy_FixNesting: Node removed' => '$CurrentToken.Compact node removed', +'Strategy_FixNesting: Node excluded' => '$CurrentToken.Compact node removed due to descendant exclusion by ancestor element', +'Strategy_FixNesting: Node reorganized' => 'Contents of $CurrentToken.Compact node reorganized to enforce its content model', +'Strategy_FixNesting: Node contents removed' => 'Contents of $CurrentToken.Compact node removed', + +'AttrValidator: Attributes transformed' => 'Attributes on $CurrentToken.Compact transformed from $1.Keys to $2.Keys', +'AttrValidator: Attribute removed' => '$CurrentAttr.Name attribute on $CurrentToken.Compact removed', + +); + +$errorNames = array( + E_ERROR => 'Error', + E_WARNING => 'Warning', + E_NOTICE => 'Notice' +); + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Lexer/PEARSax3.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Lexer/PEARSax3.php new file mode 100644 index 00000000..1d358c7b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Lexer/PEARSax3.php @@ -0,0 +1,139 @@ +tokens = array(); + $this->last_token_was_empty = false; + + $string = $this->normalize($string, $config, $context); + + $this->parent_handler = set_error_handler(array($this, 'muteStrictErrorHandler')); + + $parser = new XML_HTMLSax3(); + $parser->set_object($this); + $parser->set_element_handler('openHandler','closeHandler'); + $parser->set_data_handler('dataHandler'); + $parser->set_escape_handler('escapeHandler'); + + // doesn't seem to work correctly for attributes + $parser->set_option('XML_OPTION_ENTITIES_PARSED', 1); + + $parser->parse($string); + + restore_error_handler(); + + return $this->tokens; + + } + + /** + * Open tag event handler, interface is defined by PEAR package. + */ + public function openHandler(&$parser, $name, $attrs, $closed) { + // entities are not resolved in attrs + foreach ($attrs as $key => $attr) { + $attrs[$key] = $this->parseData($attr); + } + if ($closed) { + $this->tokens[] = new HTMLPurifier_Token_Empty($name, $attrs); + $this->last_token_was_empty = true; + } else { + $this->tokens[] = new HTMLPurifier_Token_Start($name, $attrs); + } + $this->stack[] = $name; + return true; + } + + /** + * Close tag event handler, interface is defined by PEAR package. + */ + public function closeHandler(&$parser, $name) { + // HTMLSax3 seems to always send empty tags an extra close tag + // check and ignore if you see it: + // [TESTME] to make sure it doesn't overreach + if ($this->last_token_was_empty) { + $this->last_token_was_empty = false; + return true; + } + $this->tokens[] = new HTMLPurifier_Token_End($name); + if (!empty($this->stack)) array_pop($this->stack); + return true; + } + + /** + * Data event handler, interface is defined by PEAR package. + */ + public function dataHandler(&$parser, $data) { + $this->last_token_was_empty = false; + $this->tokens[] = new HTMLPurifier_Token_Text($data); + return true; + } + + /** + * Escaped text handler, interface is defined by PEAR package. + */ + public function escapeHandler(&$parser, $data) { + if (strpos($data, '--') === 0) { + // remove trailing and leading double-dashes + $data = substr($data, 2); + if (strlen($data) >= 2 && substr($data, -2) == "--") { + $data = substr($data, 0, -2); + } + if (isset($this->stack[sizeof($this->stack) - 1]) && + $this->stack[sizeof($this->stack) - 1] == "style") { + $this->tokens[] = new HTMLPurifier_Token_Text($data); + } else { + $this->tokens[] = new HTMLPurifier_Token_Comment($data); + } + $this->last_token_was_empty = false; + } + // CDATA is handled elsewhere, but if it was handled here: + //if (strpos($data, '[CDATA[') === 0) { + // $this->tokens[] = new HTMLPurifier_Token_Text( + // substr($data, 7, strlen($data) - 9) ); + //} + return true; + } + + /** + * An error handler that mutes strict errors + */ + public function muteStrictErrorHandler($errno, $errstr, $errfile=null, $errline=null, $errcontext=null) { + if ($errno == E_STRICT) return; + return call_user_func($this->parent_handler, $errno, $errstr, $errfile, $errline, $errcontext); + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Lexer/PH5P.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Lexer/PH5P.php new file mode 100644 index 00000000..fa1bf973 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Lexer/PH5P.php @@ -0,0 +1,3906 @@ +normalize($html, $config, $context); + $new_html = $this->wrapHTML($new_html, $config, $context); + try { + $parser = new HTML5($new_html); + $doc = $parser->save(); + } catch (DOMException $e) { + // Uh oh, it failed. Punt to DirectLex. + $lexer = new HTMLPurifier_Lexer_DirectLex(); + $context->register('PH5PError', $e); // save the error, so we can detect it + return $lexer->tokenizeHTML($html, $config, $context); // use original HTML + } + $tokens = array(); + $this->tokenizeDOM( + $doc->getElementsByTagName('html')->item(0)-> // + getElementsByTagName('body')->item(0)-> // + getElementsByTagName('div')->item(0) //
    + , $tokens); + return $tokens; + } + +} + +/* + +Copyright 2007 Jeroen van der Meer + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +class HTML5 { + private $data; + private $char; + private $EOF; + private $state; + private $tree; + private $token; + private $content_model; + private $escape = false; + private $entities = array('AElig;','AElig','AMP;','AMP','Aacute;','Aacute', + 'Acirc;','Acirc','Agrave;','Agrave','Alpha;','Aring;','Aring','Atilde;', + 'Atilde','Auml;','Auml','Beta;','COPY;','COPY','Ccedil;','Ccedil','Chi;', + 'Dagger;','Delta;','ETH;','ETH','Eacute;','Eacute','Ecirc;','Ecirc','Egrave;', + 'Egrave','Epsilon;','Eta;','Euml;','Euml','GT;','GT','Gamma;','Iacute;', + 'Iacute','Icirc;','Icirc','Igrave;','Igrave','Iota;','Iuml;','Iuml','Kappa;', + 'LT;','LT','Lambda;','Mu;','Ntilde;','Ntilde','Nu;','OElig;','Oacute;', + 'Oacute','Ocirc;','Ocirc','Ograve;','Ograve','Omega;','Omicron;','Oslash;', + 'Oslash','Otilde;','Otilde','Ouml;','Ouml','Phi;','Pi;','Prime;','Psi;', + 'QUOT;','QUOT','REG;','REG','Rho;','Scaron;','Sigma;','THORN;','THORN', + 'TRADE;','Tau;','Theta;','Uacute;','Uacute','Ucirc;','Ucirc','Ugrave;', + 'Ugrave','Upsilon;','Uuml;','Uuml','Xi;','Yacute;','Yacute','Yuml;','Zeta;', + 'aacute;','aacute','acirc;','acirc','acute;','acute','aelig;','aelig', + 'agrave;','agrave','alefsym;','alpha;','amp;','amp','and;','ang;','apos;', + 'aring;','aring','asymp;','atilde;','atilde','auml;','auml','bdquo;','beta;', + 'brvbar;','brvbar','bull;','cap;','ccedil;','ccedil','cedil;','cedil', + 'cent;','cent','chi;','circ;','clubs;','cong;','copy;','copy','crarr;', + 'cup;','curren;','curren','dArr;','dagger;','darr;','deg;','deg','delta;', + 'diams;','divide;','divide','eacute;','eacute','ecirc;','ecirc','egrave;', + 'egrave','empty;','emsp;','ensp;','epsilon;','equiv;','eta;','eth;','eth', + 'euml;','euml','euro;','exist;','fnof;','forall;','frac12;','frac12', + 'frac14;','frac14','frac34;','frac34','frasl;','gamma;','ge;','gt;','gt', + 'hArr;','harr;','hearts;','hellip;','iacute;','iacute','icirc;','icirc', + 'iexcl;','iexcl','igrave;','igrave','image;','infin;','int;','iota;', + 'iquest;','iquest','isin;','iuml;','iuml','kappa;','lArr;','lambda;','lang;', + 'laquo;','laquo','larr;','lceil;','ldquo;','le;','lfloor;','lowast;','loz;', + 'lrm;','lsaquo;','lsquo;','lt;','lt','macr;','macr','mdash;','micro;','micro', + 'middot;','middot','minus;','mu;','nabla;','nbsp;','nbsp','ndash;','ne;', + 'ni;','not;','not','notin;','nsub;','ntilde;','ntilde','nu;','oacute;', + 'oacute','ocirc;','ocirc','oelig;','ograve;','ograve','oline;','omega;', + 'omicron;','oplus;','or;','ordf;','ordf','ordm;','ordm','oslash;','oslash', + 'otilde;','otilde','otimes;','ouml;','ouml','para;','para','part;','permil;', + 'perp;','phi;','pi;','piv;','plusmn;','plusmn','pound;','pound','prime;', + 'prod;','prop;','psi;','quot;','quot','rArr;','radic;','rang;','raquo;', + 'raquo','rarr;','rceil;','rdquo;','real;','reg;','reg','rfloor;','rho;', + 'rlm;','rsaquo;','rsquo;','sbquo;','scaron;','sdot;','sect;','sect','shy;', + 'shy','sigma;','sigmaf;','sim;','spades;','sub;','sube;','sum;','sup1;', + 'sup1','sup2;','sup2','sup3;','sup3','sup;','supe;','szlig;','szlig','tau;', + 'there4;','theta;','thetasym;','thinsp;','thorn;','thorn','tilde;','times;', + 'times','trade;','uArr;','uacute;','uacute','uarr;','ucirc;','ucirc', + 'ugrave;','ugrave','uml;','uml','upsih;','upsilon;','uuml;','uuml','weierp;', + 'xi;','yacute;','yacute','yen;','yen','yuml;','yuml','zeta;','zwj;','zwnj;'); + + const PCDATA = 0; + const RCDATA = 1; + const CDATA = 2; + const PLAINTEXT = 3; + + const DOCTYPE = 0; + const STARTTAG = 1; + const ENDTAG = 2; + const COMMENT = 3; + const CHARACTR = 4; + const EOF = 5; + + public function __construct($data) { + $data = str_replace("\r\n", "\n", $data); + $data = str_replace("\r", null, $data); + + $this->data = $data; + $this->char = -1; + $this->EOF = strlen($data); + $this->tree = new HTML5TreeConstructer; + $this->content_model = self::PCDATA; + + $this->state = 'data'; + + while($this->state !== null) { + $this->{$this->state.'State'}(); + } + } + + public function save() { + return $this->tree->save(); + } + + private function char() { + return ($this->char < $this->EOF) + ? $this->data[$this->char] + : false; + } + + private function character($s, $l = 0) { + if($s + $l < $this->EOF) { + if($l === 0) { + return $this->data[$s]; + } else { + return substr($this->data, $s, $l); + } + } + } + + private function characters($char_class, $start) { + return preg_replace('#^(['.$char_class.']+).*#s', '\\1', substr($this->data, $start)); + } + + private function dataState() { + // Consume the next input character + $this->char++; + $char = $this->char(); + + if($char === '&' && ($this->content_model === self::PCDATA || $this->content_model === self::RCDATA)) { + /* U+0026 AMPERSAND (&) + When the content model flag is set to one of the PCDATA or RCDATA + states: switch to the entity data state. Otherwise: treat it as per + the "anything else" entry below. */ + $this->state = 'entityData'; + + } elseif($char === '-') { + /* If the content model flag is set to either the RCDATA state or + the CDATA state, and the escape flag is false, and there are at + least three characters before this one in the input stream, and the + last four characters in the input stream, including this one, are + U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, + and U+002D HYPHEN-MINUS (""), + set the escape flag to false. */ + if(($this->content_model === self::RCDATA || + $this->content_model === self::CDATA) && $this->escape === true && + $this->character($this->char, 3) === '-->') { + $this->escape = false; + } + + /* In any case, emit the input character as a character token. + Stay in the data state. */ + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => $char + )); + + } elseif($this->char === $this->EOF) { + /* EOF + Emit an end-of-file token. */ + $this->EOF(); + + } elseif($this->content_model === self::PLAINTEXT) { + /* When the content model flag is set to the PLAINTEXT state + THIS DIFFERS GREATLY FROM THE SPEC: Get the remaining characters of + the text and emit it as a character token. */ + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => substr($this->data, $this->char) + )); + + $this->EOF(); + + } else { + /* Anything else + THIS DIFFERS GREATLY FROM THE SPEC: Get as many character that + otherwise would also be treated as a character token and emit it + as a single character token. Stay in the data state. */ + $len = strcspn($this->data, '<&', $this->char); + $char = substr($this->data, $this->char, $len); + $this->char += $len - 1; + + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => $char + )); + + $this->state = 'data'; + } + } + + private function entityDataState() { + // Attempt to consume an entity. + $entity = $this->entity(); + + // If nothing is returned, emit a U+0026 AMPERSAND character token. + // Otherwise, emit the character token that was returned. + $char = (!$entity) ? '&' : $entity; + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => $char + )); + + // Finally, switch to the data state. + $this->state = 'data'; + } + + private function tagOpenState() { + switch($this->content_model) { + case self::RCDATA: + case self::CDATA: + /* If the next input character is a U+002F SOLIDUS (/) character, + consume it and switch to the close tag open state. If the next + input character is not a U+002F SOLIDUS (/) character, emit a + U+003C LESS-THAN SIGN character token and switch to the data + state to process the next input character. */ + if($this->character($this->char + 1) === '/') { + $this->char++; + $this->state = 'closeTagOpen'; + + } else { + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => '<' + )); + + $this->state = 'data'; + } + break; + + case self::PCDATA: + // If the content model flag is set to the PCDATA state + // Consume the next input character: + $this->char++; + $char = $this->char(); + + if($char === '!') { + /* U+0021 EXCLAMATION MARK (!) + Switch to the markup declaration open state. */ + $this->state = 'markupDeclarationOpen'; + + } elseif($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the close tag open state. */ + $this->state = 'closeTagOpen'; + + } elseif(preg_match('/^[A-Za-z]$/', $char)) { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new start tag token, set its tag name to the lowercase + version of the input character (add 0x0020 to the character's code + point), then switch to the tag name state. (Don't emit the token + yet; further details will be filled in before it is emitted.) */ + $this->token = array( + 'name' => strtolower($char), + 'type' => self::STARTTAG, + 'attr' => array() + ); + + $this->state = 'tagName'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit a U+003C LESS-THAN SIGN character token and a + U+003E GREATER-THAN SIGN character token. Switch to the data state. */ + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => '<>' + )); + + $this->state = 'data'; + + } elseif($char === '?') { + /* U+003F QUESTION MARK (?) + Parse error. Switch to the bogus comment state. */ + $this->state = 'bogusComment'; + + } else { + /* Anything else + Parse error. Emit a U+003C LESS-THAN SIGN character token and + reconsume the current input character in the data state. */ + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => '<' + )); + + $this->char--; + $this->state = 'data'; + } + break; + } + } + + private function closeTagOpenState() { + $next_node = strtolower($this->characters('A-Za-z', $this->char + 1)); + $the_same = count($this->tree->stack) > 0 && $next_node === end($this->tree->stack)->nodeName; + + if(($this->content_model === self::RCDATA || $this->content_model === self::CDATA) && + (!$the_same || ($the_same && (!preg_match('/[\t\n\x0b\x0c >\/]/', + $this->character($this->char + 1 + strlen($next_node))) || $this->EOF === $this->char)))) { + /* If the content model flag is set to the RCDATA or CDATA states then + examine the next few characters. If they do not match the tag name of + the last start tag token emitted (case insensitively), or if they do but + they are not immediately followed by one of the following characters: + * U+0009 CHARACTER TABULATION + * U+000A LINE FEED (LF) + * U+000B LINE TABULATION + * U+000C FORM FEED (FF) + * U+0020 SPACE + * U+003E GREATER-THAN SIGN (>) + * U+002F SOLIDUS (/) + * EOF + ...then there is a parse error. Emit a U+003C LESS-THAN SIGN character + token, a U+002F SOLIDUS character token, and switch to the data state + to process the next input character. */ + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => 'state = 'data'; + + } else { + /* Otherwise, if the content model flag is set to the PCDATA state, + or if the next few characters do match that tag name, consume the + next input character: */ + $this->char++; + $char = $this->char(); + + if(preg_match('/^[A-Za-z]$/', $char)) { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new end tag token, set its tag name to the lowercase version + of the input character (add 0x0020 to the character's code point), then + switch to the tag name state. (Don't emit the token yet; further details + will be filled in before it is emitted.) */ + $this->token = array( + 'name' => strtolower($char), + 'type' => self::ENDTAG + ); + + $this->state = 'tagName'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Switch to the data state. */ + $this->state = 'data'; + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F + SOLIDUS character token. Reconsume the EOF character in the data state. */ + $this->emitToken(array( + 'type' => self::CHARACTR, + 'data' => 'char--; + $this->state = 'data'; + + } else { + /* Parse error. Switch to the bogus comment state. */ + $this->state = 'bogusComment'; + } + } + } + + private function tagNameState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } elseif($char === '/') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } else { + /* Anything else + Append the current input character to the current tag token's tag name. + Stay in the tag name state. */ + $this->token['name'] .= strtolower($char); + $this->state = 'tagName'; + } + } + + private function beforeAttributeNameState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($char === '/') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Stay in the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = array( + 'name' => strtolower($char), + 'value' => null + ); + + $this->state = 'attributeName'; + } + } + + private function attributeNameState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $this->state = 'afterAttributeName'; + + } elseif($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($char === '/' && $this->character($this->char + 1) !== '>') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's name. + Stay in the attribute name state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['name'] .= strtolower($char); + + $this->state = 'attributeName'; + } + } + + private function afterAttributeNameState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after attribute name state. */ + $this->state = 'afterAttributeName'; + + } elseif($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($char === '/' && $this->character($this->char + 1) !== '>') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the + before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = array( + 'name' => strtolower($char), + 'value' => null + ); + + $this->state = 'attributeName'; + } + } + + private function beforeAttributeValueState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the attribute value (double-quoted) state. */ + $this->state = 'attributeValueDoubleQuoted'; + + } elseif($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the attribute value (unquoted) state and reconsume + this input character. */ + $this->char--; + $this->state = 'attributeValueUnquoted'; + + } elseif($char === '\'') { + /* U+0027 APOSTROPHE (') + Switch to the attribute value (single-quoted) state. */ + $this->state = 'attributeValueSingleQuoted'; + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Switch to the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueUnquoted'; + } + } + + private function attributeValueDoubleQuotedState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState('double'); + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the character + in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (double-quoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueDoubleQuoted'; + } + } + + private function attributeValueSingleQuotedState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if($char === '\'') { + /* U+0022 QUOTATION MARK (') + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState('single'); + + } elseif($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the character + in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (single-quoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueSingleQuoted'; + } + } + + private function attributeValueUnquotedState() { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState(); + + } elseif($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueUnquoted'; + } + } + + private function entityInAttributeValueState() { + // Attempt to consume an entity. + $entity = $this->entity(); + + // If nothing is returned, append a U+0026 AMPERSAND character to the + // current attribute's value. Otherwise, emit the character token that + // was returned. + $char = (!$entity) + ? '&' + : $entity; + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + } + + private function bogusCommentState() { + /* Consume every character up to the first U+003E GREATER-THAN SIGN + character (>) or the end of the file (EOF), whichever comes first. Emit + a comment token whose data is the concatenation of all the characters + starting from and including the character that caused the state machine + to switch into the bogus comment state, up to and including the last + consumed character before the U+003E character, if any, or up to the + end of the file otherwise. (If the comment was started by the end of + the file (EOF), the token is empty.) */ + $data = $this->characters('^>', $this->char); + $this->emitToken(array( + 'data' => $data, + 'type' => self::COMMENT + )); + + $this->char += strlen($data); + + /* Switch to the data state. */ + $this->state = 'data'; + + /* If the end of the file was reached, reconsume the EOF character. */ + if($this->char === $this->EOF) { + $this->char = $this->EOF - 1; + } + } + + private function markupDeclarationOpenState() { + /* If the next two characters are both U+002D HYPHEN-MINUS (-) + characters, consume those two characters, create a comment token whose + data is the empty string, and switch to the comment state. */ + if($this->character($this->char + 1, 2) === '--') { + $this->char += 2; + $this->state = 'comment'; + $this->token = array( + 'data' => null, + 'type' => self::COMMENT + ); + + /* Otherwise if the next seven chacacters are a case-insensitive match + for the word "DOCTYPE", then consume those characters and switch to the + DOCTYPE state. */ + } elseif(strtolower($this->character($this->char + 1, 7)) === 'doctype') { + $this->char += 7; + $this->state = 'doctype'; + + /* Otherwise, is is a parse error. Switch to the bogus comment state. + The next character that is consumed, if any, is the first character + that will be in the comment. */ + } else { + $this->char++; + $this->state = 'bogusComment'; + } + } + + private function commentState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + /* U+002D HYPHEN-MINUS (-) */ + if($char === '-') { + /* Switch to the comment dash state */ + $this->state = 'commentDash'; + + /* EOF */ + } elseif($this->char === $this->EOF) { + /* Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + /* Anything else */ + } else { + /* Append the input character to the comment token's data. Stay in + the comment state. */ + $this->token['data'] .= $char; + } + } + + private function commentDashState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + /* U+002D HYPHEN-MINUS (-) */ + if($char === '-') { + /* Switch to the comment end state */ + $this->state = 'commentEnd'; + + /* EOF */ + } elseif($this->char === $this->EOF) { + /* Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + /* Anything else */ + } else { + /* Append a U+002D HYPHEN-MINUS (-) character and the input + character to the comment token's data. Switch to the comment state. */ + $this->token['data'] .= '-'.$char; + $this->state = 'comment'; + } + } + + private function commentEndState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($char === '-') { + $this->token['data'] .= '-'; + + } elseif($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['data'] .= '--'.$char; + $this->state = 'comment'; + } + } + + private function doctypeState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + $this->state = 'beforeDoctypeName'; + + } else { + $this->char--; + $this->state = 'beforeDoctypeName'; + } + } + + private function beforeDoctypeNameState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + // Stay in the before DOCTYPE name state. + + } elseif(preg_match('/^[a-z]$/', $char)) { + $this->token = array( + 'name' => strtoupper($char), + 'type' => self::DOCTYPE, + 'error' => true + ); + + $this->state = 'doctypeName'; + + } elseif($char === '>') { + $this->emitToken(array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + )); + + $this->state = 'data'; + + } elseif($this->char === $this->EOF) { + $this->emitToken(array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + )); + + $this->char--; + $this->state = 'data'; + + } else { + $this->token = array( + 'name' => $char, + 'type' => self::DOCTYPE, + 'error' => true + ); + + $this->state = 'doctypeName'; + } + } + + private function doctypeNameState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + $this->state = 'AfterDoctypeName'; + + } elseif($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif(preg_match('/^[a-z]$/', $char)) { + $this->token['name'] .= strtoupper($char); + + } elseif($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['name'] .= $char; + } + + $this->token['error'] = ($this->token['name'] === 'HTML') + ? false + : true; + } + + private function afterDoctypeNameState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + // Stay in the DOCTYPE name state. + + } elseif($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['error'] = true; + $this->state = 'bogusDoctype'; + } + } + + private function bogusDoctypeState() { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + // Stay in the bogus DOCTYPE state. + } + } + + private function entity() { + $start = $this->char; + + // This section defines how to consume an entity. This definition is + // used when parsing entities in text and in attributes. + + // The behaviour depends on the identity of the next character (the + // one immediately after the U+0026 AMPERSAND character): + + switch($this->character($this->char + 1)) { + // U+0023 NUMBER SIGN (#) + case '#': + + // The behaviour further depends on the character after the + // U+0023 NUMBER SIGN: + switch($this->character($this->char + 1)) { + // U+0078 LATIN SMALL LETTER X + // U+0058 LATIN CAPITAL LETTER X + case 'x': + case 'X': + // Follow the steps below, but using the range of + // characters U+0030 DIGIT ZERO through to U+0039 DIGIT + // NINE, U+0061 LATIN SMALL LETTER A through to U+0066 + // LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER + // A, through to U+0046 LATIN CAPITAL LETTER F (in other + // words, 0-9, A-F, a-f). + $char = 1; + $char_class = '0-9A-Fa-f'; + break; + + // Anything else + default: + // Follow the steps below, but using the range of + // characters U+0030 DIGIT ZERO through to U+0039 DIGIT + // NINE (i.e. just 0-9). + $char = 0; + $char_class = '0-9'; + break; + } + + // Consume as many characters as match the range of characters + // given above. + $this->char++; + $e_name = $this->characters($char_class, $this->char + $char + 1); + $entity = $this->character($start, $this->char); + $cond = strlen($e_name) > 0; + + // The rest of the parsing happens bellow. + break; + + // Anything else + default: + // Consume the maximum number of characters possible, with the + // consumed characters case-sensitively matching one of the + // identifiers in the first column of the entities table. + $e_name = $this->characters('0-9A-Za-z;', $this->char + 1); + $len = strlen($e_name); + + for($c = 1; $c <= $len; $c++) { + $id = substr($e_name, 0, $c); + $this->char++; + + if(in_array($id, $this->entities)) { + if ($e_name[$c-1] !== ';') { + if ($c < $len && $e_name[$c] == ';') { + $this->char++; // consume extra semicolon + } + } + $entity = $id; + break; + } + } + + $cond = isset($entity); + // The rest of the parsing happens bellow. + break; + } + + if(!$cond) { + // If no match can be made, then this is a parse error. No + // characters are consumed, and nothing is returned. + $this->char = $start; + return false; + } + + // Return a character token for the character corresponding to the + // entity name (as given by the second column of the entities table). + return html_entity_decode('&'.$entity.';', ENT_QUOTES, 'UTF-8'); + } + + private function emitToken($token) { + $emit = $this->tree->emitToken($token); + + if(is_int($emit)) { + $this->content_model = $emit; + + } elseif($token['type'] === self::ENDTAG) { + $this->content_model = self::PCDATA; + } + } + + private function EOF() { + $this->state = null; + $this->tree->emitToken(array( + 'type' => self::EOF + )); + } +} + +class HTML5TreeConstructer { + public $stack = array(); + + private $phase; + private $mode; + private $dom; + private $foster_parent = null; + private $a_formatting = array(); + + private $head_pointer = null; + private $form_pointer = null; + + private $scoping = array('button','caption','html','marquee','object','table','td','th'); + private $formatting = array('a','b','big','em','font','i','nobr','s','small','strike','strong','tt','u'); + private $special = array('address','area','base','basefont','bgsound', + 'blockquote','body','br','center','col','colgroup','dd','dir','div','dl', + 'dt','embed','fieldset','form','frame','frameset','h1','h2','h3','h4','h5', + 'h6','head','hr','iframe','image','img','input','isindex','li','link', + 'listing','menu','meta','noembed','noframes','noscript','ol','optgroup', + 'option','p','param','plaintext','pre','script','select','spacer','style', + 'tbody','textarea','tfoot','thead','title','tr','ul','wbr'); + + // The different phases. + const INIT_PHASE = 0; + const ROOT_PHASE = 1; + const MAIN_PHASE = 2; + const END_PHASE = 3; + + // The different insertion modes for the main phase. + const BEFOR_HEAD = 0; + const IN_HEAD = 1; + const AFTER_HEAD = 2; + const IN_BODY = 3; + const IN_TABLE = 4; + const IN_CAPTION = 5; + const IN_CGROUP = 6; + const IN_TBODY = 7; + const IN_ROW = 8; + const IN_CELL = 9; + const IN_SELECT = 10; + const AFTER_BODY = 11; + const IN_FRAME = 12; + const AFTR_FRAME = 13; + + // The different types of elements. + const SPECIAL = 0; + const SCOPING = 1; + const FORMATTING = 2; + const PHRASING = 3; + + const MARKER = 0; + + public function __construct() { + $this->phase = self::INIT_PHASE; + $this->mode = self::BEFOR_HEAD; + $this->dom = new DOMDocument; + + $this->dom->encoding = 'UTF-8'; + $this->dom->preserveWhiteSpace = true; + $this->dom->substituteEntities = true; + $this->dom->strictErrorChecking = false; + } + + // Process tag tokens + public function emitToken($token) { + switch($this->phase) { + case self::INIT_PHASE: return $this->initPhase($token); break; + case self::ROOT_PHASE: return $this->rootElementPhase($token); break; + case self::MAIN_PHASE: return $this->mainPhase($token); break; + case self::END_PHASE : return $this->trailingEndPhase($token); break; + } + } + + private function initPhase($token) { + /* Initially, the tree construction stage must handle each token + emitted from the tokenisation stage as follows: */ + + /* A DOCTYPE token that is marked as being in error + A comment token + A start tag token + An end tag token + A character token that is not one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE + An end-of-file token */ + if((isset($token['error']) && $token['error']) || + $token['type'] === HTML5::COMMENT || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF || + ($token['type'] === HTML5::CHARACTR && isset($token['data']) && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']))) { + /* This specification does not define how to handle this case. In + particular, user agents may ignore the entirety of this specification + altogether for such documents, and instead invoke special parse modes + with a greater emphasis on backwards compatibility. */ + + $this->phase = self::ROOT_PHASE; + return $this->rootElementPhase($token); + + /* A DOCTYPE token marked as being correct */ + } elseif(isset($token['error']) && !$token['error']) { + /* Append a DocumentType node to the Document node, with the name + attribute set to the name given in the DOCTYPE token (which will be + "HTML"), and the other attributes specific to DocumentType objects + set to null, empty lists, or the empty string as appropriate. */ + $doctype = new DOMDocumentType(null, null, 'HTML'); + + /* Then, switch to the root element phase of the tree construction + stage. */ + $this->phase = self::ROOT_PHASE; + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif(isset($token['data']) && preg_match('/^[\t\n\x0b\x0c ]+$/', + $token['data'])) { + /* Append that character to the Document node. */ + $text = $this->dom->createTextNode($token['data']); + $this->dom->appendChild($text); + } + } + + private function rootElementPhase($token) { + /* After the initial phase, as each token is emitted from the tokenisation + stage, it must be processed as described in this section. */ + + /* A DOCTYPE token */ + if($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append that character to the Document node. */ + $text = $this->dom->createTextNode($token['data']); + $this->dom->appendChild($text); + + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED + (FF), or U+0020 SPACE + A start tag token + An end tag token + An end-of-file token */ + } elseif(($token['type'] === HTML5::CHARACTR && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF) { + /* Create an HTMLElement node with the tag name html, in the HTML + namespace. Append it to the Document object. Switch to the main + phase and reprocess the current token. */ + $html = $this->dom->createElement('html'); + $this->dom->appendChild($html); + $this->stack[] = $html; + + $this->phase = self::MAIN_PHASE; + return $this->mainPhase($token); + } + } + + private function mainPhase($token) { + /* Tokens in the main phase must be handled as follows: */ + + /* A DOCTYPE token */ + if($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A start tag token with the tag name "html" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') { + /* If this start tag token was not the first start tag token, then + it is a parse error. */ + + /* For each attribute on the token, check to see if the attribute + is already present on the top element of the stack of open elements. + If it is not, add the attribute and its corresponding value to that + element. */ + foreach($token['attr'] as $attr) { + if(!$this->stack[0]->hasAttribute($attr['name'])) { + $this->stack[0]->setAttribute($attr['name'], $attr['value']); + } + } + + /* An end-of-file token */ + } elseif($token['type'] === HTML5::EOF) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Anything else. */ + } else { + /* Depends on the insertion mode: */ + switch($this->mode) { + case self::BEFOR_HEAD: return $this->beforeHead($token); break; + case self::IN_HEAD: return $this->inHead($token); break; + case self::AFTER_HEAD: return $this->afterHead($token); break; + case self::IN_BODY: return $this->inBody($token); break; + case self::IN_TABLE: return $this->inTable($token); break; + case self::IN_CAPTION: return $this->inCaption($token); break; + case self::IN_CGROUP: return $this->inColumnGroup($token); break; + case self::IN_TBODY: return $this->inTableBody($token); break; + case self::IN_ROW: return $this->inRow($token); break; + case self::IN_CELL: return $this->inCell($token); break; + case self::IN_SELECT: return $this->inSelect($token); break; + case self::AFTER_BODY: return $this->afterBody($token); break; + case self::IN_FRAME: return $this->inFrameset($token); break; + case self::AFTR_FRAME: return $this->afterFrameset($token); break; + case self::END_PHASE: return $this->trailingEndPhase($token); break; + } + } + } + + private function beforeHead($token) { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token with the tag name "head" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') { + /* Create an element for the token, append the new element to the + current node and push it onto the stack of open elements. */ + $element = $this->insertElement($token); + + /* Set the head element pointer to this new element node. */ + $this->head_pointer = $element; + + /* Change the insertion mode to "in head". */ + $this->mode = self::IN_HEAD; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title". Or an end tag with the tag name "html". + Or a character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or any other start tag token */ + } elseif($token['type'] === HTML5::STARTTAG || + ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') || + ($token['type'] === HTML5::CHARACTR && !preg_match('/^[\t\n\x0b\x0c ]$/', + $token['data']))) { + /* Act as if a start tag token with the tag name "head" and no + attributes had been seen, then reprocess the current token. */ + $this->beforeHead(array( + 'name' => 'head', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + return $this->inHead($token); + + /* Any other end tag */ + } elseif($token['type'] === HTML5::ENDTAG) { + /* Parse error. Ignore the token. */ + } + } + + private function inHead($token) { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. + + THIS DIFFERS FROM THE SPEC: If the current node is either a title, style + or script element, append the character to the current node regardless + of its content. */ + if(($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || ( + $token['type'] === HTML5::CHARACTR && in_array(end($this->stack)->nodeName, + array('title', 'style', 'script')))) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + } elseif($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('title', 'style', 'script'))) { + array_pop($this->stack); + return HTML5::PCDATA; + + /* A start tag with the tag name "title" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + } else { + $element = $this->insertElement($token); + } + + /* Switch the tokeniser's content model flag to the RCDATA state. */ + return HTML5::RCDATA; + + /* A start tag with the tag name "style" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + } else { + $this->insertElement($token); + } + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + + /* A start tag with the tag name "script" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') { + /* Create an element for the token. */ + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + + /* A start tag with the tag name "base", "link", or "meta" */ + } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('base', 'link', 'meta'))) { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + array_pop($this->stack); + + } else { + $this->insertElement($token); + } + + /* An end tag with the tag name "head" */ + } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') { + /* If the current node is a head element, pop the current node off + the stack of open elements. */ + if($this->head_pointer->isSameNode(end($this->stack))) { + array_pop($this->stack); + + /* Otherwise, this is a parse error. */ + } else { + // k + } + + /* Change the insertion mode to "after head". */ + $this->mode = self::AFTER_HEAD; + + /* A start tag with the tag name "head" or an end tag except "html". */ + } elseif(($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') || + ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html')) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* If the current node is a head element, act as if an end tag + token with the tag name "head" had been seen. */ + if($this->head_pointer->isSameNode(end($this->stack))) { + $this->inHead(array( + 'name' => 'head', + 'type' => HTML5::ENDTAG + )); + + /* Otherwise, change the insertion mode to "after head". */ + } else { + $this->mode = self::AFTER_HEAD; + } + + /* Then, reprocess the current token. */ + return $this->afterHead($token); + } + } + + private function afterHead($token) { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token with the tag name "body" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') { + /* Insert a body element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in body". */ + $this->mode = self::IN_BODY; + + /* A start tag token with the tag name "frameset" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') { + /* Insert a frameset element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in frameset". */ + $this->mode = self::IN_FRAME; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title" */ + } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('base', 'link', 'meta', 'script', 'style', 'title'))) { + /* Parse error. Switch the insertion mode back to "in head" and + reprocess the token. */ + $this->mode = self::IN_HEAD; + return $this->inHead($token); + + /* Anything else */ + } else { + /* Act as if a start tag token with the tag name "body" and no + attributes had been seen, and then reprocess the current token. */ + $this->afterHead(array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + return $this->inBody($token); + } + } + + private function inBody($token) { + /* Handle the token as follows: */ + + switch($token['type']) { + /* A character token */ + case HTML5::CHARACTR: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + break; + + /* A comment token */ + case HTML5::COMMENT: + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + break; + + case HTML5::STARTTAG: + switch($token['name']) { + /* A start tag token whose tag name is one of: "script", + "style" */ + case 'script': case 'style': + /* Process the token as if the insertion mode had been "in + head". */ + return $this->inHead($token); + break; + + /* A start tag token whose tag name is one of: "base", "link", + "meta", "title" */ + case 'base': case 'link': case 'meta': case 'title': + /* Parse error. Process the token as if the insertion mode + had been "in head". */ + return $this->inHead($token); + break; + + /* A start tag token with the tag name "body" */ + case 'body': + /* Parse error. If the second element on the stack of open + elements is not a body element, or, if the stack of open + elements has only one node on it, then ignore the token. + (innerHTML case) */ + if(count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') { + // Ignore + + /* Otherwise, for each attribute on the token, check to see + if the attribute is already present on the body element (the + second element) on the stack of open elements. If it is not, + add the attribute and its corresponding value to that + element. */ + } else { + foreach($token['attr'] as $attr) { + if(!$this->stack[1]->hasAttribute($attr['name'])) { + $this->stack[1]->setAttribute($attr['name'], $attr['value']); + } + } + } + break; + + /* A start tag whose tag name is one of: "address", + "blockquote", "center", "dir", "div", "dl", "fieldset", + "listing", "menu", "ol", "p", "ul" */ + case 'address': case 'blockquote': case 'center': case 'dir': + case 'div': case 'dl': case 'fieldset': case 'listing': + case 'menu': case 'ol': case 'p': case 'ul': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is "form" */ + case 'form': + /* If the form element pointer is not null, ignore the + token with a parse error. */ + if($this->form_pointer !== null) { + // Ignore. + + /* Otherwise: */ + } else { + /* If the stack of open elements has a p element in + scope, then act as if an end tag with the tag name p + had been seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token, and set the + form element pointer to point to the element created. */ + $element = $this->insertElement($token); + $this->form_pointer = $element; + } + break; + + /* A start tag whose tag name is "li", "dd" or "dt" */ + case 'li': case 'dd': case 'dt': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + $stack_length = count($this->stack) - 1; + + for($n = $stack_length; 0 <= $n; $n--) { + /* 1. Initialise node to be the current node (the + bottommost node of the stack). */ + $stop = false; + $node = $this->stack[$n]; + $cat = $this->getElementCategory($node->tagName); + + /* 2. If node is an li, dd or dt element, then pop all + the nodes from the current node up to node, including + node, then stop this algorithm. */ + if($token['name'] === $node->tagName || ($token['name'] !== 'li' + && ($node->tagName === 'dd' || $node->tagName === 'dt'))) { + for($x = $stack_length; $x >= $n ; $x--) { + array_pop($this->stack); + } + + break; + } + + /* 3. If node is not in the formatting category, and is + not in the phrasing category, and is not an address or + div element, then stop this algorithm. */ + if($cat !== self::FORMATTING && $cat !== self::PHRASING && + $node->tagName !== 'address' && $node->tagName !== 'div') { + break; + } + } + + /* Finally, insert an HTML element with the same tag + name as the token's. */ + $this->insertElement($token); + break; + + /* A start tag token whose tag name is "plaintext" */ + case 'plaintext': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + return HTML5::PLAINTEXT; + break; + + /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + this is a parse error; pop elements from the stack until an + element with one of those tag names has been popped from the + stack. */ + while($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { + array_pop($this->stack); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is "a" */ + case 'a': + /* If the list of active formatting elements contains + an element whose tag name is "a" between the end of the + list and the last marker on the list (or the start of + the list if there is no marker on the list), then this + is a parse error; act as if an end tag with the tag name + "a" had been seen, then remove that element from the list + of active formatting elements and the stack of open + elements if the end tag didn't already remove it (it + might not have if the element is not in table scope). */ + $leng = count($this->a_formatting); + + for($n = $leng - 1; $n >= 0; $n--) { + if($this->a_formatting[$n] === self::MARKER) { + break; + + } elseif($this->a_formatting[$n]->nodeName === 'a') { + $this->emitToken(array( + 'name' => 'a', + 'type' => HTML5::ENDTAG + )); + break; + } + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + /* A start tag whose tag name is one of: "b", "big", "em", "font", + "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'b': case 'big': case 'em': case 'font': case 'i': + case 'nobr': case 's': case 'small': case 'strike': + case 'strong': case 'tt': case 'u': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + /* A start tag token whose tag name is "button" */ + case 'button': + /* If the stack of open elements has a button element in scope, + then this is a parse error; act as if an end tag with the tag + name "button" had been seen, then reprocess the token. (We don't + do that. Unnecessary.) */ + if($this->elementInScope('button')) { + $this->inBody(array( + 'name' => 'button', + 'type' => HTML5::ENDTAG + )); + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; + + /* A start tag token whose tag name is one of: "marquee", "object" */ + case 'marquee': case 'object': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; + + /* A start tag token whose tag name is "xmp" */ + case 'xmp': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Switch the content model flag to the CDATA state. */ + return HTML5::CDATA; + break; + + /* A start tag whose tag name is "table" */ + case 'table': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + break; + + /* A start tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ + case 'area': case 'basefont': case 'bgsound': case 'br': + case 'embed': case 'img': case 'param': case 'spacer': + case 'wbr': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "hr" */ + case 'hr': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if($this->elementInScope('p')) { + $this->emitToken(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "image" */ + case 'image': + /* Parse error. Change the token's tag name to "img" and + reprocess it. (Don't ask.) */ + $token['name'] = 'img'; + return $this->inBody($token); + break; + + /* A start tag whose tag name is "input" */ + case 'input': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an input element for the token. */ + $element = $this->insertElement($token, false); + + /* If the form element pointer is not null, then associate the + input element with the form element pointed to by the form + element pointer. */ + $this->form_pointer !== null + ? $this->form_pointer->appendChild($element) + : end($this->stack)->appendChild($element); + + /* Pop that input element off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "isindex" */ + case 'isindex': + /* Parse error. */ + // w/e + + /* If the form element pointer is not null, + then ignore the token. */ + if($this->form_pointer === null) { + /* Act as if a start tag token with the tag name "form" had + been seen. */ + $this->inBody(array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody(array( + 'name' => 'hr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + /* Act as if a start tag token with the tag name "p" had + been seen. */ + $this->inBody(array( + 'name' => 'p', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + /* Act as if a start tag token with the tag name "label" + had been seen. */ + $this->inBody(array( + 'name' => 'label', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + /* Act as if a stream of character tokens had been seen. */ + $this->insertText('This is a searchable index. '. + 'Insert your search keywords here: '); + + /* Act as if a start tag token with the tag name "input" + had been seen, with all the attributes from the "isindex" + token, except with the "name" attribute set to the value + "isindex" (ignoring any explicit "name" attribute). */ + $attr = $token['attr']; + $attr[] = array('name' => 'name', 'value' => 'isindex'); + + $this->inBody(array( + 'name' => 'input', + 'type' => HTML5::STARTTAG, + 'attr' => $attr + )); + + /* Act as if a stream of character tokens had been seen + (see below for what they should say). */ + $this->insertText('This is a searchable index. '. + 'Insert your search keywords here: '); + + /* Act as if an end tag token with the tag name "label" + had been seen. */ + $this->inBody(array( + 'name' => 'label', + 'type' => HTML5::ENDTAG + )); + + /* Act as if an end tag token with the tag name "p" had + been seen. */ + $this->inBody(array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + )); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody(array( + 'name' => 'hr', + 'type' => HTML5::ENDTAG + )); + + /* Act as if an end tag token with the tag name "form" had + been seen. */ + $this->inBody(array( + 'name' => 'form', + 'type' => HTML5::ENDTAG + )); + } + break; + + /* A start tag whose tag name is "textarea" */ + case 'textarea': + $this->insertElement($token); + + /* Switch the tokeniser's content model flag to the + RCDATA state. */ + return HTML5::RCDATA; + break; + + /* A start tag whose tag name is one of: "iframe", "noembed", + "noframes" */ + case 'iframe': case 'noembed': case 'noframes': + $this->insertElement($token); + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + break; + + /* A start tag whose tag name is "select" */ + case 'select': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in select". */ + $this->mode = self::IN_SELECT; + break; + + /* A start or end tag whose tag name is one of: "caption", "col", + "colgroup", "frame", "frameset", "head", "option", "optgroup", + "tbody", "td", "tfoot", "th", "thead", "tr". */ + case 'caption': case 'col': case 'colgroup': case 'frame': + case 'frameset': case 'head': case 'option': case 'optgroup': + case 'tbody': case 'td': case 'tfoot': case 'th': case 'thead': + case 'tr': + // Parse error. Ignore the token. + break; + + /* A start or end tag whose tag name is one of: "event-source", + "section", "nav", "article", "aside", "header", "footer", + "datagrid", "command" */ + case 'event-source': case 'section': case 'nav': case 'article': + case 'aside': case 'header': case 'footer': case 'datagrid': + case 'command': + // Work in progress! + break; + + /* A start tag token not covered by the previous entries */ + default: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + $this->insertElement($token, true, true); + break; + } + break; + + case HTML5::ENDTAG: + switch($token['name']) { + /* An end tag with the tag name "body" */ + case 'body': + /* If the second element in the stack of open elements is + not a body element, this is a parse error. Ignore the token. + (innerHTML case) */ + if(count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') { + // Ignore. + + /* If the current node is not the body element, then this + is a parse error. */ + } elseif(end($this->stack)->nodeName !== 'body') { + // Parse error. + } + + /* Change the insertion mode to "after body". */ + $this->mode = self::AFTER_BODY; + break; + + /* An end tag with the tag name "html" */ + case 'html': + /* Act as if an end tag with tag name "body" had been seen, + then, if that token wasn't ignored, reprocess the current + token. */ + $this->inBody(array( + 'name' => 'body', + 'type' => HTML5::ENDTAG + )); + + return $this->afterBody($token); + break; + + /* An end tag whose tag name is one of: "address", "blockquote", + "center", "dir", "div", "dl", "fieldset", "listing", "menu", + "ol", "pre", "ul" */ + case 'address': case 'blockquote': case 'center': case 'dir': + case 'div': case 'dl': case 'fieldset': case 'listing': + case 'menu': case 'ol': case 'pre': case 'ul': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with + the same tag name as that of the token, then this + is a parse error. */ + // w/e + + /* If the stack of open elements has an element in + scope with the same tag name as that of the token, + then pop elements from this stack until an element + with that tag name has been popped from the stack. */ + for($n = count($this->stack) - 1; $n >= 0; $n--) { + if($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is "form" */ + case 'form': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + } + + if(end($this->stack)->nodeName !== $token['name']) { + /* Now, if the current node is not an element with the + same tag name as that of the token, then this is a parse + error. */ + // w/e + + } else { + /* Otherwise, if the current node is an element with + the same tag name as that of the token pop that element + from the stack. */ + array_pop($this->stack); + } + + /* In any case, set the form element pointer to null. */ + $this->form_pointer = null; + break; + + /* An end tag whose tag name is "p" */ + case 'p': + /* If the stack of open elements has a p element in scope, + then generate implied end tags, except for p elements. */ + if($this->elementInScope('p')) { + $this->generateImpliedEndTags(array('p')); + + /* If the current node is not a p element, then this is + a parse error. */ + // k + + /* If the stack of open elements has a p element in + scope, then pop elements from this stack until the stack + no longer has a p element in scope. */ + for($n = count($this->stack) - 1; $n >= 0; $n--) { + if($this->elementInScope('p')) { + array_pop($this->stack); + + } else { + break; + } + } + } + break; + + /* An end tag whose tag name is "dd", "dt", or "li" */ + case 'dd': case 'dt': case 'li': + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + generate implied end tags, except for elements with the + same tag name as the token. */ + if($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(array($token['name'])); + + /* If the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + pop elements from this stack until an element with that + tag name has been popped from the stack. */ + for($n = count($this->stack) - 1; $n >= 0; $n--) { + if($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': + $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + generate implied end tags. */ + if($this->elementInScope($elements)) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with the same + tag name as that of the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has in scope an element + whose tag name is one of "h1", "h2", "h3", "h4", "h5", or + "h6", then pop elements from the stack until an element + with one of those tag names has been popped from the stack. */ + while($this->elementInScope($elements)) { + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is one of: "a", "b", "big", "em", + "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'a': case 'b': case 'big': case 'em': case 'font': + case 'i': case 'nobr': case 's': case 'small': case 'strike': + case 'strong': case 'tt': case 'u': + /* 1. Let the formatting element be the last element in + the list of active formatting elements that: + * is between the end of the list and the last scope + marker in the list, if any, or the start of the list + otherwise, and + * has the same tag name as the token. + */ + while(true) { + for($a = count($this->a_formatting) - 1; $a >= 0; $a--) { + if($this->a_formatting[$a] === self::MARKER) { + break; + + } elseif($this->a_formatting[$a]->tagName === $token['name']) { + $formatting_element = $this->a_formatting[$a]; + $in_stack = in_array($formatting_element, $this->stack, true); + $fe_af_pos = $a; + break; + } + } + + /* If there is no such node, or, if that node is + also in the stack of open elements but the element + is not in scope, then this is a parse error. Abort + these steps. The token is ignored. */ + if(!isset($formatting_element) || ($in_stack && + !$this->elementInScope($token['name']))) { + break; + + /* Otherwise, if there is such a node, but that node + is not in the stack of open elements, then this is a + parse error; remove the element from the list, and + abort these steps. */ + } elseif(isset($formatting_element) && !$in_stack) { + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } + + /* 2. Let the furthest block be the topmost node in the + stack of open elements that is lower in the stack + than the formatting element, and is not an element in + the phrasing or formatting categories. There might + not be one. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $length = count($this->stack); + + for($s = $fe_s_pos + 1; $s < $length; $s++) { + $category = $this->getElementCategory($this->stack[$s]->nodeName); + + if($category !== self::PHRASING && $category !== self::FORMATTING) { + $furthest_block = $this->stack[$s]; + } + } + + /* 3. If there is no furthest block, then the UA must + skip the subsequent steps and instead just pop all + the nodes from the bottom of the stack of open + elements, from the current node up to the formatting + element, and remove the formatting element from the + list of active formatting elements. */ + if(!isset($furthest_block)) { + for($n = $length - 1; $n >= $fe_s_pos; $n--) { + array_pop($this->stack); + } + + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } + + /* 4. Let the common ancestor be the element + immediately above the formatting element in the stack + of open elements. */ + $common_ancestor = $this->stack[$fe_s_pos - 1]; + + /* 5. If the furthest block has a parent node, then + remove the furthest block from its parent node. */ + if($furthest_block->parentNode !== null) { + $furthest_block->parentNode->removeChild($furthest_block); + } + + /* 6. Let a bookmark note the position of the + formatting element in the list of active formatting + elements relative to the elements on either side + of it in the list. */ + $bookmark = $fe_af_pos; + + /* 7. Let node and last node be the furthest block. + Follow these steps: */ + $node = $furthest_block; + $last_node = $furthest_block; + + while(true) { + for($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) { + /* 7.1 Let node be the element immediately + prior to node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 7.2 If node is not in the list of active + formatting elements, then remove node from + the stack of open elements and then go back + to step 1. */ + if(!in_array($node, $this->a_formatting, true)) { + unset($this->stack[$n]); + $this->stack = array_merge($this->stack); + + } else { + break; + } + } + + /* 7.3 Otherwise, if node is the formatting + element, then go to the next step in the overall + algorithm. */ + if($node === $formatting_element) { + break; + + /* 7.4 Otherwise, if last node is the furthest + block, then move the aforementioned bookmark to + be immediately after the node in the list of + active formatting elements. */ + } elseif($last_node === $furthest_block) { + $bookmark = array_search($node, $this->a_formatting, true) + 1; + } + + /* 7.5 If node has any children, perform a + shallow clone of node, replace the entry for + node in the list of active formatting elements + with an entry for the clone, replace the entry + for node in the stack of open elements with an + entry for the clone, and let node be the clone. */ + if($node->hasChildNodes()) { + $clone = $node->cloneNode(); + $s_pos = array_search($node, $this->stack, true); + $a_pos = array_search($node, $this->a_formatting, true); + + $this->stack[$s_pos] = $clone; + $this->a_formatting[$a_pos] = $clone; + $node = $clone; + } + + /* 7.6 Insert last node into node, first removing + it from its previous parent node if any. */ + if($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $node->appendChild($last_node); + + /* 7.7 Let last node be node. */ + $last_node = $node; + } + + /* 8. Insert whatever last node ended up being in + the previous step into the common ancestor node, + first removing it from its previous parent node if + any. */ + if($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $common_ancestor->appendChild($last_node); + + /* 9. Perform a shallow clone of the formatting + element. */ + $clone = $formatting_element->cloneNode(); + + /* 10. Take all of the child nodes of the furthest + block and append them to the clone created in the + last step. */ + while($furthest_block->hasChildNodes()) { + $child = $furthest_block->firstChild; + $furthest_block->removeChild($child); + $clone->appendChild($child); + } + + /* 11. Append that clone to the furthest block. */ + $furthest_block->appendChild($clone); + + /* 12. Remove the formatting element from the list + of active formatting elements, and insert the clone + into the list of active formatting elements at the + position of the aforementioned bookmark. */ + $fe_af_pos = array_search($formatting_element, $this->a_formatting, true); + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + + $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1); + $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting)); + $this->a_formatting = array_merge($af_part1, array($clone), $af_part2); + + /* 13. Remove the formatting element from the stack + of open elements, and insert the clone into the stack + of open elements immediately after (i.e. in a more + deeply nested position than) the position of the + furthest block in that stack. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $fb_s_pos = array_search($furthest_block, $this->stack, true); + unset($this->stack[$fe_s_pos]); + + $s_part1 = array_slice($this->stack, 0, $fb_s_pos); + $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack)); + $this->stack = array_merge($s_part1, array($clone), $s_part2); + + /* 14. Jump back to step 1 in this series of steps. */ + unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block); + } + break; + + /* An end tag token whose tag name is one of: "button", + "marquee", "object" */ + case 'button': case 'marquee': case 'object': + /* If the stack of open elements has an element in scope whose + tag name matches the tag name of the token, then generate implied + tags. */ + if($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // k + + /* Now, if the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then pop + elements from the stack until that element has been popped from + the stack, and clear the list of active formatting elements up + to the last marker. */ + for($n = count($this->stack) - 1; $n >= 0; $n--) { + if($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + + $marker = end(array_keys($this->a_formatting, self::MARKER, true)); + + for($n = count($this->a_formatting) - 1; $n > $marker; $n--) { + array_pop($this->a_formatting); + } + } + break; + + /* Or an end tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "hr", "iframe", "image", "img", + "input", "isindex", "noembed", "noframes", "param", "select", + "spacer", "table", "textarea", "wbr" */ + case 'area': case 'basefont': case 'bgsound': case 'br': + case 'embed': case 'hr': case 'iframe': case 'image': + case 'img': case 'input': case 'isindex': case 'noembed': + case 'noframes': case 'param': case 'select': case 'spacer': + case 'table': case 'textarea': case 'wbr': + // Parse error. Ignore the token. + break; + + /* An end tag token not covered by the previous entries */ + default: + for($n = count($this->stack) - 1; $n >= 0; $n--) { + /* Initialise node to be the current node (the bottommost + node of the stack). */ + $node = end($this->stack); + + /* If node has the same tag name as the end tag token, + then: */ + if($token['name'] === $node->nodeName) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* If the tag name of the end tag token does not + match the tag name of the current node, this is a + parse error. */ + // k + + /* Pop all the nodes from the current node up to + node, including node, then stop this algorithm. */ + for($x = count($this->stack) - $n; $x >= $n; $x--) { + array_pop($this->stack); + } + + } else { + $category = $this->getElementCategory($node); + + if($category !== self::SPECIAL && $category !== self::SCOPING) { + /* Otherwise, if node is in neither the formatting + category nor the phrasing category, then this is a + parse error. Stop this algorithm. The end tag token + is ignored. */ + return false; + } + } + } + break; + } + break; + } + } + + private function inTable($token) { + $clear = array('html', 'table'); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append the character to the current node. */ + $text = $this->dom->createTextNode($token['data']); + end($this->stack)->appendChild($text); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + end($this->stack)->appendChild($comment); + + /* A start tag whose tag name is "caption" */ + } elseif($token['type'] === HTML5::STARTTAG && + $token['name'] === 'caption') { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + + /* Insert an HTML element for the token, then switch the + insertion mode to "in caption". */ + $this->insertElement($token); + $this->mode = self::IN_CAPTION; + + /* A start tag whose tag name is "colgroup" */ + } elseif($token['type'] === HTML5::STARTTAG && + $token['name'] === 'colgroup') { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the + insertion mode to "in column group". */ + $this->insertElement($token); + $this->mode = self::IN_CGROUP; + + /* A start tag whose tag name is "col" */ + } elseif($token['type'] === HTML5::STARTTAG && + $token['name'] === 'col') { + $this->inTable(array( + 'name' => 'colgroup', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + $this->inColumnGroup($token); + + /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('tbody', 'tfoot', 'thead'))) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the insertion + mode to "in table body". */ + $this->insertElement($token); + $this->mode = self::IN_TBODY; + + /* A start tag whose tag name is one of: "td", "th", "tr" */ + } elseif($token['type'] === HTML5::STARTTAG && + in_array($token['name'], array('td', 'th', 'tr'))) { + /* Act as if a start tag token with the tag name "tbody" had been + seen, then reprocess the current token. */ + $this->inTable(array( + 'name' => 'tbody', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + return $this->inTableBody($token); + + /* A start tag whose tag name is "table" */ + } elseif($token['type'] === HTML5::STARTTAG && + $token['name'] === 'table') { + /* Parse error. Act as if an end tag token with the tag name "table" + had been seen, then, if that token wasn't ignored, reprocess the + current token. */ + $this->inTable(array( + 'name' => 'table', + 'type' => HTML5::ENDTAG + )); + + return $this->mainPhase($token); + + /* An end tag whose tag name is "table" */ + } elseif($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if(!$this->elementInScope($token['name'], true)) { + return false; + + /* Otherwise: */ + } else { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Now, if the current node is not a table element, then this + is a parse error. */ + // w/e + + /* Pop elements from this stack until a table element has been + popped from the stack. */ + while(true) { + $current = end($this->stack)->nodeName; + array_pop($this->stack); + + if($current === 'table') { + break; + } + } + + /* Reset the insertion mode appropriately. */ + $this->resetInsertionMode(); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td', + 'tfoot', 'th', 'thead', 'tr'))) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* Parse error. Process the token as if the insertion mode was "in + body", with the following exception: */ + + /* If the current node is a table, tbody, tfoot, thead, or tr + element, then, whenever a node would be inserted into the current + node, it must instead be inserted into the foster parent element. */ + if(in_array(end($this->stack)->nodeName, + array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { + /* The foster parent element is the parent element of the last + table element in the stack of open elements, if there is a + table element and it has such a parent element. If there is no + table element in the stack of open elements (innerHTML case), + then the foster parent element is the first element in the + stack of open elements (the html element). Otherwise, if there + is a table element in the stack of open elements, but the last + table element in the stack of open elements has no parent, or + its parent node is not an element, then the foster parent + element is the element before the last table element in the + stack of open elements. */ + for($n = count($this->stack) - 1; $n >= 0; $n--) { + if($this->stack[$n]->nodeName === 'table') { + $table = $this->stack[$n]; + break; + } + } + + if(isset($table) && $table->parentNode !== null) { + $this->foster_parent = $table->parentNode; + + } elseif(!isset($table)) { + $this->foster_parent = $this->stack[0]; + + } elseif(isset($table) && ($table->parentNode === null || + $table->parentNode->nodeType !== XML_ELEMENT_NODE)) { + $this->foster_parent = $this->stack[$n - 1]; + } + } + + $this->inBody($token); + } + } + + private function inCaption($token) { + /* An end tag whose tag name is "caption" */ + if($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if(!$this->elementInScope($token['name'], true)) { + // Ignore + + /* Otherwise: */ + } else { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Now, if the current node is not a caption element, then this + is a parse error. */ + // w/e + + /* Pop elements from this stack until a caption element has + been popped from the stack. */ + while(true) { + $node = end($this->stack)->nodeName; + array_pop($this->stack); + + if($node === 'caption') { + break; + } + } + + /* Clear the list of active formatting elements up to the last + marker. */ + $this->clearTheActiveFormattingElementsUpToTheLastMarker(); + + /* Switch the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag + name is "table" */ + } elseif(($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', + 'thead', 'tr'))) || ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table')) { + /* Parse error. Act as if an end tag with the tag name "caption" + had been seen, then, if that token wasn't ignored, reprocess the + current token. */ + $this->inCaption(array( + 'name' => 'caption', + 'type' => HTML5::ENDTAG + )); + + return $this->inTable($token); + + /* An end tag whose tag name is one of: "body", "col", "colgroup", + "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], + array('body', 'col', 'colgroup', 'html', 'tbody', 'tfoot', 'th', + 'thead', 'tr'))) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in body". */ + $this->inBody($token); + } + } + + private function inColumnGroup($token) { + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append the character to the current node. */ + $text = $this->dom->createTextNode($token['data']); + end($this->stack)->appendChild($text); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + end($this->stack)->appendChild($comment); + + /* A start tag whose tag name is "col" */ + } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') { + /* Insert a col element for the token. Immediately pop the current + node off the stack of open elements. */ + $this->insertElement($token); + array_pop($this->stack); + + /* An end tag whose tag name is "colgroup" */ + } elseif($token['type'] === HTML5::ENDTAG && + $token['name'] === 'colgroup') { + /* If the current node is the root html element, then this is a + parse error, ignore the token. (innerHTML case) */ + if(end($this->stack)->nodeName === 'html') { + // Ignore + + /* Otherwise, pop the current node (which will be a colgroup + element) from the stack of open elements. Switch the insertion + mode to "in table". */ + } else { + array_pop($this->stack); + $this->mode = self::IN_TABLE; + } + + /* An end tag whose tag name is "col" */ + } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Act as if an end tag with the tag name "colgroup" had been seen, + and then, if that token wasn't ignored, reprocess the current token. */ + $this->inColumnGroup(array( + 'name' => 'colgroup', + 'type' => HTML5::ENDTAG + )); + + return $this->inTable($token); + } + } + + private function inTableBody($token) { + $clear = array('tbody', 'tfoot', 'thead', 'html'); + + /* A start tag whose tag name is "tr" */ + if($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Insert a tr element for the token, then switch the insertion + mode to "in row". */ + $this->insertElement($token); + $this->mode = self::IN_ROW; + + /* A start tag whose tag name is one of: "th", "td" */ + } elseif($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td')) { + /* Parse error. Act as if a start tag with the tag name "tr" had + been seen, then reprocess the current token. */ + $this->inTableBody(array( + 'name' => 'tr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + )); + + return $this->inRow($token); + + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead'))) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. */ + if(!$this->elementInScope($token['name'], true)) { + // Ignore + + /* Otherwise: */ + } else { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Pop the current node from the stack of open elements. Switch + the insertion mode to "in table". */ + array_pop($this->stack); + $this->mode = self::IN_TABLE; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */ + } elseif(($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead'))) || + ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table')) { + /* If the stack of open elements does not have a tbody, thead, or + tfoot element in table scope, this is a parse error. Ignore the + token. (innerHTML case) */ + if(!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Act as if an end tag with the same tag name as the current + node ("tbody", "tfoot", or "thead") had been seen, then + reprocess the current token. */ + $this->inTableBody(array( + 'name' => end($this->stack)->nodeName, + 'type' => HTML5::ENDTAG + )); + + return $this->mainPhase($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th", "tr" */ + } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in table". */ + $this->inTable($token); + } + } + + private function inRow($token) { + $clear = array('tr', 'html'); + + /* A start tag whose tag name is one of: "th", "td" */ + if($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td')) { + /* Clear the stack back to a table row context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the insertion + mode to "in cell". */ + $this->insertElement($token); + $this->mode = self::IN_CELL; + + /* Insert a marker at the end of the list of active formatting + elements. */ + $this->a_formatting[] = self::MARKER; + + /* An end tag whose tag name is "tr" */ + } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if(!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Clear the stack back to a table row context. */ + $this->clearStackToTableContext($clear); + + /* Pop the current node (which will be a tr element) from the + stack of open elements. Switch the insertion mode to "in table + body". */ + array_pop($this->stack); + $this->mode = self::IN_TBODY; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */ + } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr'))) { + /* Act as if an end tag with the tag name "tr" had been seen, then, + if that token wasn't ignored, reprocess the current token. */ + $this->inRow(array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + )); + + return $this->inCell($token); + + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead'))) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. */ + if(!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Otherwise, act as if an end tag with the tag name "tr" had + been seen, then reprocess the current token. */ + $this->inRow(array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + )); + + return $this->inCell($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th" */ + } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in table". */ + $this->inTable($token); + } + } + + private function inCell($token) { + /* An end tag whose tag name is one of: "td", "th" */ + if($token['type'] === HTML5::ENDTAG && + ($token['name'] === 'td' || $token['name'] === 'th')) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as that of the token, then this is a + parse error and the token must be ignored. */ + if(!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Generate implied end tags, except for elements with the same + tag name as the token. */ + $this->generateImpliedEndTags(array($token['name'])); + + /* Now, if the current node is not an element with the same tag + name as the token, then this is a parse error. */ + // k + + /* Pop elements from this stack until an element with the same + tag name as the token has been popped from the stack. */ + while(true) { + $node = end($this->stack)->nodeName; + array_pop($this->stack); + + if($node === $token['name']) { + break; + } + } + + /* Clear the list of active formatting elements up to the last + marker. */ + $this->clearTheActiveFormattingElementsUpToTheLastMarker(); + + /* Switch the insertion mode to "in row". (The current node + will be a tr element at this point.) */ + $this->mode = self::IN_ROW; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', + 'thead', 'tr'))) { + /* If the stack of open elements does not have a td or th element + in table scope, then this is a parse error; ignore the token. + (innerHTML case) */ + if(!$this->elementInScope(array('td', 'th'), true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', + 'thead', 'tr'))) { + /* If the stack of open elements does not have a td or th element + in table scope, then this is a parse error; ignore the token. + (innerHTML case) */ + if(!$this->elementInScope(array('td', 'th'), true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html" */ + } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], + array('body', 'caption', 'col', 'colgroup', 'html'))) { + /* Parse error. Ignore the token. */ + + /* An end tag whose tag name is one of: "table", "tbody", "tfoot", + "thead", "tr" */ + } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], + array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as that of the token (which can only + happen for "tbody", "tfoot" and "thead", or, in the innerHTML case), + then this is a parse error and the token must be ignored. */ + if(!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in body". */ + $this->inBody($token); + } + } + + private function inSelect($token) { + /* Handle the token as follows: */ + + /* A character token */ + if($token['type'] === HTML5::CHARACTR) { + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token whose tag name is "option" */ + } elseif($token['type'] === HTML5::STARTTAG && + $token['name'] === 'option') { + /* If the current node is an option element, act as if an end tag + with the tag name "option" had been seen. */ + if(end($this->stack)->nodeName === 'option') { + $this->inSelect(array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* A start tag token whose tag name is "optgroup" */ + } elseif($token['type'] === HTML5::STARTTAG && + $token['name'] === 'optgroup') { + /* If the current node is an option element, act as if an end tag + with the tag name "option" had been seen. */ + if(end($this->stack)->nodeName === 'option') { + $this->inSelect(array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + )); + } + + /* If the current node is an optgroup element, act as if an end tag + with the tag name "optgroup" had been seen. */ + if(end($this->stack)->nodeName === 'optgroup') { + $this->inSelect(array( + 'name' => 'optgroup', + 'type' => HTML5::ENDTAG + )); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* An end tag token whose tag name is "optgroup" */ + } elseif($token['type'] === HTML5::ENDTAG && + $token['name'] === 'optgroup') { + /* First, if the current node is an option element, and the node + immediately before it in the stack of open elements is an optgroup + element, then act as if an end tag with the tag name "option" had + been seen. */ + $elements_in_stack = count($this->stack); + + if($this->stack[$elements_in_stack - 1]->nodeName === 'option' && + $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup') { + $this->inSelect(array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + )); + } + + /* If the current node is an optgroup element, then pop that node + from the stack of open elements. Otherwise, this is a parse error, + ignore the token. */ + if($this->stack[$elements_in_stack - 1] === 'optgroup') { + array_pop($this->stack); + } + + /* An end tag token whose tag name is "option" */ + } elseif($token['type'] === HTML5::ENDTAG && + $token['name'] === 'option') { + /* If the current node is an option element, then pop that node + from the stack of open elements. Otherwise, this is a parse error, + ignore the token. */ + if(end($this->stack)->nodeName === 'option') { + array_pop($this->stack); + } + + /* An end tag whose tag name is "select" */ + } elseif($token['type'] === HTML5::ENDTAG && + $token['name'] === 'select') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if(!$this->elementInScope($token['name'], true)) { + // w/e + + /* Otherwise: */ + } else { + /* Pop elements from the stack of open elements until a select + element has been popped from the stack. */ + while(true) { + $current = end($this->stack)->nodeName; + array_pop($this->stack); + + if($current === 'select') { + break; + } + } + + /* Reset the insertion mode appropriately. */ + $this->resetInsertionMode(); + } + + /* A start tag whose tag name is "select" */ + } elseif($token['name'] === 'select' && + $token['type'] === HTML5::STARTTAG) { + /* Parse error. Act as if the token had been an end tag with the + tag name "select" instead. */ + $this->inSelect(array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + )); + + /* An end tag whose tag name is one of: "caption", "table", "tbody", + "tfoot", "thead", "tr", "td", "th" */ + } elseif(in_array($token['name'], array('caption', 'table', 'tbody', + 'tfoot', 'thead', 'tr', 'td', 'th')) && $token['type'] === HTML5::ENDTAG) { + /* Parse error. */ + // w/e + + /* If the stack of open elements has an element in table scope with + the same tag name as that of the token, then act as if an end tag + with the tag name "select" had been seen, and reprocess the token. + Otherwise, ignore the token. */ + if($this->elementInScope($token['name'], true)) { + $this->inSelect(array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + )); + + $this->mainPhase($token); + } + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function afterBody($token) { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Process the token as it would be processed if the insertion mode + was "in body". */ + $this->inBody($token); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the first element in the stack of open + elements (the html element), with the data attribute set to the + data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->stack[0]->appendChild($comment); + + /* An end tag with the tag name "html" */ + } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') { + /* If the parser was originally created in order to handle the + setting of an element's innerHTML attribute, this is a parse error; + ignore the token. (The element will be an html element in this + case.) (innerHTML case) */ + + /* Otherwise, switch to the trailing end phase. */ + $this->phase = self::END_PHASE; + + /* Anything else */ + } else { + /* Parse error. Set the insertion mode to "in body" and reprocess + the token. */ + $this->mode = self::IN_BODY; + return $this->inBody($token); + } + } + + private function inFrameset($token) { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag with the tag name "frameset" */ + } elseif($token['name'] === 'frameset' && + $token['type'] === HTML5::STARTTAG) { + $this->insertElement($token); + + /* An end tag with the tag name "frameset" */ + } elseif($token['name'] === 'frameset' && + $token['type'] === HTML5::ENDTAG) { + /* If the current node is the root html element, then this is a + parse error; ignore the token. (innerHTML case) */ + if(end($this->stack)->nodeName === 'html') { + // Ignore + + } else { + /* Otherwise, pop the current node from the stack of open + elements. */ + array_pop($this->stack); + + /* If the parser was not originally created in order to handle + the setting of an element's innerHTML attribute (innerHTML case), + and the current node is no longer a frameset element, then change + the insertion mode to "after frameset". */ + $this->mode = self::AFTR_FRAME; + } + + /* A start tag with the tag name "frame" */ + } elseif($token['name'] === 'frame' && + $token['type'] === HTML5::STARTTAG) { + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + + /* A start tag with the tag name "noframes" */ + } elseif($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG) { + /* Process the token as if the insertion mode had been "in body". */ + $this->inBody($token); + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function afterFrameset($token) { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ + if($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* An end tag with the tag name "html" */ + } elseif($token['name'] === 'html' && + $token['type'] === HTML5::ENDTAG) { + /* Switch to the trailing end phase. */ + $this->phase = self::END_PHASE; + + /* A start tag with the tag name "noframes" */ + } elseif($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG) { + /* Process the token as if the insertion mode had been "in body". */ + $this->inBody($token); + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function trailingEndPhase($token) { + /* After the main phase, as each token is emitted from the tokenisation + stage, it must be processed as described in this section. */ + + /* A DOCTYPE token */ + if($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A comment token */ + } elseif($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* Process the token as it would be processed in the main phase. */ + $this->mainPhase($token); + + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or a start tag token. Or an end tag token. */ + } elseif(($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG) { + /* Parse error. Switch back to the main phase and reprocess the + token. */ + $this->phase = self::MAIN_PHASE; + return $this->mainPhase($token); + + /* An end-of-file token */ + } elseif($token['type'] === HTML5::EOF) { + /* OMG DONE!! */ + } + } + + private function insertElement($token, $append = true, $check = false) { + // Proprietary workaround for libxml2's limitations with tag names + if ($check) { + // Slightly modified HTML5 tag-name modification, + // removing anything that's not an ASCII letter, digit, or hyphen + $token['name'] = preg_replace('/[^a-z0-9-]/i', '', $token['name']); + // Remove leading hyphens and numbers + $token['name'] = ltrim($token['name'], '-0..9'); + // In theory, this should ever be needed, but just in case + if ($token['name'] === '') $token['name'] = 'span'; // arbitrary generic choice + } + + $el = $this->dom->createElement($token['name']); + + foreach($token['attr'] as $attr) { + if(!$el->hasAttribute($attr['name'])) { + $el->setAttribute($attr['name'], $attr['value']); + } + } + + $this->appendToRealParent($el); + $this->stack[] = $el; + + return $el; + } + + private function insertText($data) { + $text = $this->dom->createTextNode($data); + $this->appendToRealParent($text); + } + + private function insertComment($data) { + $comment = $this->dom->createComment($data); + $this->appendToRealParent($comment); + } + + private function appendToRealParent($node) { + if($this->foster_parent === null) { + end($this->stack)->appendChild($node); + + } elseif($this->foster_parent !== null) { + /* If the foster parent element is the parent element of the + last table element in the stack of open elements, then the new + node must be inserted immediately before the last table element + in the stack of open elements in the foster parent element; + otherwise, the new node must be appended to the foster parent + element. */ + for($n = count($this->stack) - 1; $n >= 0; $n--) { + if($this->stack[$n]->nodeName === 'table' && + $this->stack[$n]->parentNode !== null) { + $table = $this->stack[$n]; + break; + } + } + + if(isset($table) && $this->foster_parent->isSameNode($table->parentNode)) + $this->foster_parent->insertBefore($node, $table); + else + $this->foster_parent->appendChild($node); + + $this->foster_parent = null; + } + } + + private function elementInScope($el, $table = false) { + if(is_array($el)) { + foreach($el as $element) { + if($this->elementInScope($element, $table)) { + return true; + } + } + + return false; + } + + $leng = count($this->stack); + + for($n = 0; $n < $leng; $n++) { + /* 1. Initialise node to be the current node (the bottommost node of + the stack). */ + $node = $this->stack[$leng - 1 - $n]; + + if($node->tagName === $el) { + /* 2. If node is the target node, terminate in a match state. */ + return true; + + } elseif($node->tagName === 'table') { + /* 3. Otherwise, if node is a table element, terminate in a failure + state. */ + return false; + + } elseif($table === true && in_array($node->tagName, array('caption', 'td', + 'th', 'button', 'marquee', 'object'))) { + /* 4. Otherwise, if the algorithm is the "has an element in scope" + variant (rather than the "has an element in table scope" variant), + and node is one of the following, terminate in a failure state. */ + return false; + + } elseif($node === $node->ownerDocument->documentElement) { + /* 5. Otherwise, if node is an html element (root element), terminate + in a failure state. (This can only happen if the node is the topmost + node of the stack of open elements, and prevents the next step from + being invoked if there are no more elements in the stack.) */ + return false; + } + + /* Otherwise, set node to the previous entry in the stack of open + elements and return to step 2. (This will never fail, since the loop + will always terminate in the previous step if the top of the stack + is reached.) */ + } + } + + private function reconstructActiveFormattingElements() { + /* 1. If there are no entries in the list of active formatting elements, + then there is nothing to reconstruct; stop this algorithm. */ + $formatting_elements = count($this->a_formatting); + + if($formatting_elements === 0) { + return false; + } + + /* 3. Let entry be the last (most recently added) element in the list + of active formatting elements. */ + $entry = end($this->a_formatting); + + /* 2. If the last (most recently added) entry in the list of active + formatting elements is a marker, or if it is an element that is in the + stack of open elements, then there is nothing to reconstruct; stop this + algorithm. */ + if($entry === self::MARKER || in_array($entry, $this->stack, true)) { + return false; + } + + for($a = $formatting_elements - 1; $a >= 0; true) { + /* 4. If there are no entries before entry in the list of active + formatting elements, then jump to step 8. */ + if($a === 0) { + $step_seven = false; + break; + } + + /* 5. Let entry be the entry one earlier than entry in the list of + active formatting elements. */ + $a--; + $entry = $this->a_formatting[$a]; + + /* 6. If entry is neither a marker nor an element that is also in + thetack of open elements, go to step 4. */ + if($entry === self::MARKER || in_array($entry, $this->stack, true)) { + break; + } + } + + while(true) { + /* 7. Let entry be the element one later than entry in the list of + active formatting elements. */ + if(isset($step_seven) && $step_seven === true) { + $a++; + $entry = $this->a_formatting[$a]; + } + + /* 8. Perform a shallow clone of the element entry to obtain clone. */ + $clone = $entry->cloneNode(); + + /* 9. Append clone to the current node and push it onto the stack + of open elements so that it is the new current node. */ + end($this->stack)->appendChild($clone); + $this->stack[] = $clone; + + /* 10. Replace the entry for entry in the list with an entry for + clone. */ + $this->a_formatting[$a] = $clone; + + /* 11. If the entry for clone in the list of active formatting + elements is not the last entry in the list, return to step 7. */ + if(end($this->a_formatting) !== $clone) { + $step_seven = true; + } else { + break; + } + } + } + + private function clearTheActiveFormattingElementsUpToTheLastMarker() { + /* When the steps below require the UA to clear the list of active + formatting elements up to the last marker, the UA must perform the + following steps: */ + + while(true) { + /* 1. Let entry be the last (most recently added) entry in the list + of active formatting elements. */ + $entry = end($this->a_formatting); + + /* 2. Remove entry from the list of active formatting elements. */ + array_pop($this->a_formatting); + + /* 3. If entry was a marker, then stop the algorithm at this point. + The list has been cleared up to the last marker. */ + if($entry === self::MARKER) { + break; + } + } + } + + private function generateImpliedEndTags($exclude = array()) { + /* When the steps below require the UA to generate implied end tags, + then, if the current node is a dd element, a dt element, an li element, + a p element, a td element, a th element, or a tr element, the UA must + act as if an end tag with the respective tag name had been seen and + then generate implied end tags again. */ + $node = end($this->stack); + $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude); + + while(in_array(end($this->stack)->nodeName, $elements)) { + array_pop($this->stack); + } + } + + private function getElementCategory($node) { + $name = $node->tagName; + if(in_array($name, $this->special)) + return self::SPECIAL; + + elseif(in_array($name, $this->scoping)) + return self::SCOPING; + + elseif(in_array($name, $this->formatting)) + return self::FORMATTING; + + else + return self::PHRASING; + } + + private function clearStackToTableContext($elements) { + /* When the steps above require the UA to clear the stack back to a + table context, it means that the UA must, while the current node is not + a table element or an html element, pop elements from the stack of open + elements. If this causes any elements to be popped from the stack, then + this is a parse error. */ + while(true) { + $node = end($this->stack)->nodeName; + + if(in_array($node, $elements)) { + break; + } else { + array_pop($this->stack); + } + } + } + + private function resetInsertionMode() { + /* 1. Let last be false. */ + $last = false; + $leng = count($this->stack); + + for($n = $leng - 1; $n >= 0; $n--) { + /* 2. Let node be the last node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 3. If node is the first node in the stack of open elements, then + set last to true. If the element whose innerHTML attribute is being + set is neither a td element nor a th element, then set node to the + element whose innerHTML attribute is being set. (innerHTML case) */ + if($this->stack[0]->isSameNode($node)) { + $last = true; + } + + /* 4. If node is a select element, then switch the insertion mode to + "in select" and abort these steps. (innerHTML case) */ + if($node->nodeName === 'select') { + $this->mode = self::IN_SELECT; + break; + + /* 5. If node is a td or th element, then switch the insertion mode + to "in cell" and abort these steps. */ + } elseif($node->nodeName === 'td' || $node->nodeName === 'th') { + $this->mode = self::IN_CELL; + break; + + /* 6. If node is a tr element, then switch the insertion mode to + "in row" and abort these steps. */ + } elseif($node->nodeName === 'tr') { + $this->mode = self::IN_ROW; + break; + + /* 7. If node is a tbody, thead, or tfoot element, then switch the + insertion mode to "in table body" and abort these steps. */ + } elseif(in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) { + $this->mode = self::IN_TBODY; + break; + + /* 8. If node is a caption element, then switch the insertion mode + to "in caption" and abort these steps. */ + } elseif($node->nodeName === 'caption') { + $this->mode = self::IN_CAPTION; + break; + + /* 9. If node is a colgroup element, then switch the insertion mode + to "in column group" and abort these steps. (innerHTML case) */ + } elseif($node->nodeName === 'colgroup') { + $this->mode = self::IN_CGROUP; + break; + + /* 10. If node is a table element, then switch the insertion mode + to "in table" and abort these steps. */ + } elseif($node->nodeName === 'table') { + $this->mode = self::IN_TABLE; + break; + + /* 11. If node is a head element, then switch the insertion mode + to "in body" ("in body"! not "in head"!) and abort these steps. + (innerHTML case) */ + } elseif($node->nodeName === 'head') { + $this->mode = self::IN_BODY; + break; + + /* 12. If node is a body element, then switch the insertion mode to + "in body" and abort these steps. */ + } elseif($node->nodeName === 'body') { + $this->mode = self::IN_BODY; + break; + + /* 13. If node is a frameset element, then switch the insertion + mode to "in frameset" and abort these steps. (innerHTML case) */ + } elseif($node->nodeName === 'frameset') { + $this->mode = self::IN_FRAME; + break; + + /* 14. If node is an html element, then: if the head element + pointer is null, switch the insertion mode to "before head", + otherwise, switch the insertion mode to "after head". In either + case, abort these steps. (innerHTML case) */ + } elseif($node->nodeName === 'html') { + $this->mode = ($this->head_pointer === null) + ? self::BEFOR_HEAD + : self::AFTER_HEAD; + + break; + + /* 15. If last is true, then set the insertion mode to "in body" + and abort these steps. (innerHTML case) */ + } elseif($last) { + $this->mode = self::IN_BODY; + break; + } + } + } + + private function closeCell() { + /* If the stack of open elements has a td or th element in table scope, + then act as if an end tag token with that tag name had been seen. */ + foreach(array('td', 'th') as $cell) { + if($this->elementInScope($cell, true)) { + $this->inCell(array( + 'name' => $cell, + 'type' => HTML5::ENDTAG + )); + + break; + } + } + } + + public function save() { + return $this->dom; + } +} +?> diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer.php new file mode 100644 index 00000000..e7eb82e8 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer.php @@ -0,0 +1,176 @@ +getAll(); + $context = new HTMLPurifier_Context(); + $this->generator = new HTMLPurifier_Generator($config, $context); + } + + /** + * Main function that renders object or aspect of that object + * @note Parameters vary depending on printer + */ + // function render() {} + + /** + * Returns a start tag + * @param $tag Tag name + * @param $attr Attribute array + */ + protected function start($tag, $attr = array()) { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Start($tag, $attr ? $attr : array()) + ); + } + + /** + * Returns an end teg + * @param $tag Tag name + */ + protected function end($tag) { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_End($tag) + ); + } + + /** + * Prints a complete element with content inside + * @param $tag Tag name + * @param $contents Element contents + * @param $attr Tag attributes + * @param $escape Bool whether or not to escape contents + */ + protected function element($tag, $contents, $attr = array(), $escape = true) { + return $this->start($tag, $attr) . + ($escape ? $this->escape($contents) : $contents) . + $this->end($tag); + } + + protected function elementEmpty($tag, $attr = array()) { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Empty($tag, $attr) + ); + } + + protected function text($text) { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Text($text) + ); + } + + /** + * Prints a simple key/value row in a table. + * @param $name Key + * @param $value Value + */ + protected function row($name, $value) { + if (is_bool($value)) $value = $value ? 'On' : 'Off'; + return + $this->start('tr') . "\n" . + $this->element('th', $name) . "\n" . + $this->element('td', $value) . "\n" . + $this->end('tr') + ; + } + + /** + * Escapes a string for HTML output. + * @param $string String to escape + */ + protected function escape($string) { + $string = HTMLPurifier_Encoder::cleanUTF8($string); + $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8'); + return $string; + } + + /** + * Takes a list of strings and turns them into a single list + * @param $array List of strings + * @param $polite Bool whether or not to add an end before the last + */ + protected function listify($array, $polite = false) { + if (empty($array)) return 'None'; + $ret = ''; + $i = count($array); + foreach ($array as $value) { + $i--; + $ret .= $value; + if ($i > 0 && !($polite && $i == 1)) $ret .= ', '; + if ($polite && $i == 1) $ret .= 'and '; + } + return $ret; + } + + /** + * Retrieves the class of an object without prefixes, as well as metadata + * @param $obj Object to determine class of + * @param $prefix Further prefix to remove + */ + protected function getClass($obj, $sec_prefix = '') { + static $five = null; + if ($five === null) $five = version_compare(PHP_VERSION, '5', '>='); + $prefix = 'HTMLPurifier_' . $sec_prefix; + if (!$five) $prefix = strtolower($prefix); + $class = str_replace($prefix, '', get_class($obj)); + $lclass = strtolower($class); + $class .= '('; + switch ($lclass) { + case 'enum': + $values = array(); + foreach ($obj->valid_values as $value => $bool) { + $values[] = $value; + } + $class .= implode(', ', $values); + break; + case 'css_composite': + $values = array(); + foreach ($obj->defs as $def) { + $values[] = $this->getClass($def, $sec_prefix); + } + $class .= implode(', ', $values); + break; + case 'css_multiple': + $class .= $this->getClass($obj->single, $sec_prefix) . ', '; + $class .= $obj->max; + break; + case 'css_denyelementdecorator': + $class .= $this->getClass($obj->def, $sec_prefix) . ', '; + $class .= $obj->element; + break; + case 'css_importantdecorator': + $class .= $this->getClass($obj->def, $sec_prefix); + if ($obj->allow) $class .= ', !important'; + break; + } + $class .= ')'; + return $class; + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/CSSDefinition.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/CSSDefinition.php new file mode 100644 index 00000000..81f98659 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/CSSDefinition.php @@ -0,0 +1,38 @@ +def = $config->getCSSDefinition(); + $ret = ''; + + $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer')); + $ret .= $this->start('table'); + + $ret .= $this->element('caption', 'Properties ($info)'); + + $ret .= $this->start('thead'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Property', array('class' => 'heavy')); + $ret .= $this->element('th', 'Definition', array('class' => 'heavy', 'style' => 'width:auto;')); + $ret .= $this->end('tr'); + $ret .= $this->end('thead'); + + ksort($this->def->info); + foreach ($this->def->info as $property => $obj) { + $name = $this->getClass($obj, 'AttrDef_'); + $ret .= $this->row($property, $name); + } + + $ret .= $this->end('table'); + $ret .= $this->end('div'); + + return $ret; + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.css b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.css new file mode 100644 index 00000000..3ff1a88a --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.css @@ -0,0 +1,10 @@ + +.hp-config {} + +.hp-config tbody th {text-align:right; padding-right:0.5em;} +.hp-config thead, .hp-config .namespace {background:#3C578C; color:#FFF;} +.hp-config .namespace th {text-align:center;} +.hp-config .verbose {display:none;} +.hp-config .controls {text-align:center;} + +/* vim: et sw=4 sts=4 */ diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.js b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.js new file mode 100644 index 00000000..cba00c9b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.js @@ -0,0 +1,5 @@ +function toggleWriteability(id_of_patient, checked) { + document.getElementById(id_of_patient).disabled = checked; +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.php new file mode 100644 index 00000000..02aa6568 --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/ConfigForm.php @@ -0,0 +1,368 @@ +docURL = $doc_url; + $this->name = $name; + $this->compress = $compress; + // initialize sub-printers + $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default(); + $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool(); + } + + /** + * Sets default column and row size for textareas in sub-printers + * @param $cols Integer columns of textarea, null to use default + * @param $rows Integer rows of textarea, null to use default + */ + public function setTextareaDimensions($cols = null, $rows = null) { + if ($cols) $this->fields['default']->cols = $cols; + if ($rows) $this->fields['default']->rows = $rows; + } + + /** + * Retrieves styling, in case it is not accessible by webserver + */ + public static function getCSS() { + return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css'); + } + + /** + * Retrieves JavaScript, in case it is not accessible by webserver + */ + public static function getJavaScript() { + return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js'); + } + + /** + * Returns HTML output for a configuration form + * @param $config Configuration object of current form state, or an array + * where [0] has an HTML namespace and [1] is being rendered. + * @param $allowed Optional namespace(s) and directives to restrict form to. + */ + public function render($config, $allowed = true, $render_controls = true) { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + + $this->config = $config; + $this->genConfig = $gen_config; + $this->prepareGenerator($gen_config); + + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $config->def); + $all = array(); + foreach ($allowed as $key) { + list($ns, $directive) = $key; + $all[$ns][$directive] = $config->get($ns .'.'. $directive); + } + + $ret = ''; + $ret .= $this->start('table', array('class' => 'hp-config')); + $ret .= $this->start('thead'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive')); + $ret .= $this->element('th', 'Value', array('class' => 'hp-value')); + $ret .= $this->end('tr'); + $ret .= $this->end('thead'); + foreach ($all as $ns => $directives) { + $ret .= $this->renderNamespace($ns, $directives); + } + if ($render_controls) { + $ret .= $this->start('tbody'); + $ret .= $this->start('tr'); + $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls')); + $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit')); + $ret .= '[Reset]'; + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders a single namespace + * @param $ns String namespace name + * @param $directive Associative array of directives to values + */ + protected function renderNamespace($ns, $directives) { + $ret = ''; + $ret .= $this->start('tbody', array('class' => 'namespace')); + $ret .= $this->start('tr'); + $ret .= $this->element('th', $ns, array('colspan' => 2)); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); + $ret .= $this->start('tbody'); + foreach ($directives as $directive => $value) { + $ret .= $this->start('tr'); + $ret .= $this->start('th'); + if ($this->docURL) { + $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL); + $ret .= $this->start('a', array('href' => $url)); + } + $attr = array('for' => "{$this->name}:$ns.$directive"); + + // crop directive name if it's too long + if (!$this->compress || (strlen($directive) < $this->compress)) { + $directive_disp = $directive; + } else { + $directive_disp = substr($directive, 0, $this->compress - 2) . '...'; + $attr['title'] = $directive; + } + + $ret .= $this->element( + 'label', + $directive_disp, + // component printers must create an element with this id + $attr + ); + if ($this->docURL) $ret .= $this->end('a'); + $ret .= $this->end('th'); + + $ret .= $this->start('td'); + $def = $this->config->def->info["$ns.$directive"]; + if (is_int($def)) { + $allow_null = $def < 0; + $type = abs($def); + } else { + $type = $def->type; + $allow_null = isset($def->allow_null); + } + if (!isset($this->fields[$type])) $type = 0; // default + $type_obj = $this->fields[$type]; + if ($allow_null) { + $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj); + } + $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config)); + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + } + $ret .= $this->end('tbody'); + return $ret; + } + +} + +/** + * Printer decorator for directives that accept null + */ +class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer { + /** + * Printer being decorated + */ + protected $obj; + /** + * @param $obj Printer to decorate + */ + public function __construct($obj) { + parent::__construct(); + $this->obj = $obj; + } + public function render($ns, $directive, $value, $name, $config) { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + + $ret = ''; + $ret .= $this->start('label', array('for' => "$name:Null_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' Null/Disabled'); + $ret .= $this->end('label'); + $attr = array( + 'type' => 'checkbox', + 'value' => '1', + 'class' => 'null-toggle', + 'name' => "$name"."[Null_$ns.$directive]", + 'id' => "$name:Null_$ns.$directive", + 'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!! + ); + if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) { + // modify inline javascript slightly + $attr['onclick'] = "toggleWriteability('$name:Yes_$ns.$directive',checked);toggleWriteability('$name:No_$ns.$directive',checked)"; + } + if ($value === null) $attr['checked'] = 'checked'; + $ret .= $this->elementEmpty('input', $attr); + $ret .= $this->text(' or '); + $ret .= $this->elementEmpty('br'); + $ret .= $this->obj->render($ns, $directive, $value, $name, array($gen_config, $config)); + return $ret; + } +} + +/** + * Swiss-army knife configuration form field printer + */ +class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer { + public $cols = 18; + public $rows = 5; + public function render($ns, $directive, $value, $name, $config) { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + // this should probably be split up a little + $ret = ''; + $def = $config->def->info["$ns.$directive"]; + if (is_int($def)) { + $type = abs($def); + } else { + $type = $def->type; + } + if (is_array($value)) { + switch ($type) { + case HTMLPurifier_VarParser::LOOKUP: + $array = $value; + $value = array(); + foreach ($array as $val => $b) { + $value[] = $val; + } + case HTMLPurifier_VarParser::ALIST: + $value = implode(PHP_EOL, $value); + break; + case HTMLPurifier_VarParser::HASH: + $nvalue = ''; + foreach ($value as $i => $v) { + $nvalue .= "$i:$v" . PHP_EOL; + } + $value = $nvalue; + break; + default: + $value = ''; + } + } + if ($type === HTMLPurifier_VarParser::MIXED) { + return 'Not supported'; + $value = serialize($value); + } + $attr = array( + 'name' => "$name"."[$ns.$directive]", + 'id' => "$name:$ns.$directive" + ); + if ($value === null) $attr['disabled'] = 'disabled'; + if (isset($def->allowed)) { + $ret .= $this->start('select', $attr); + foreach ($def->allowed as $val => $b) { + $attr = array(); + if ($value == $val) $attr['selected'] = 'selected'; + $ret .= $this->element('option', $val, $attr); + } + $ret .= $this->end('select'); + } elseif ( + $type === HTMLPurifier_VarParser::TEXT || + $type === HTMLPurifier_VarParser::ITEXT || + $type === HTMLPurifier_VarParser::ALIST || + $type === HTMLPurifier_VarParser::HASH || + $type === HTMLPurifier_VarParser::LOOKUP + ) { + $attr['cols'] = $this->cols; + $attr['rows'] = $this->rows; + $ret .= $this->start('textarea', $attr); + $ret .= $this->text($value); + $ret .= $this->end('textarea'); + } else { + $attr['value'] = $value; + $attr['type'] = 'text'; + $ret .= $this->elementEmpty('input', $attr); + } + return $ret; + } +} + +/** + * Bool form field printer + */ +class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer { + public function render($ns, $directive, $value, $name, $config) { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + $ret = ''; + $ret .= $this->start('div', array('id' => "$name:$ns.$directive")); + + $ret .= $this->start('label', array('for' => "$name:Yes_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' Yes'); + $ret .= $this->end('label'); + + $attr = array( + 'type' => 'radio', + 'name' => "$name"."[$ns.$directive]", + 'id' => "$name:Yes_$ns.$directive", + 'value' => '1' + ); + if ($value === true) $attr['checked'] = 'checked'; + if ($value === null) $attr['disabled'] = 'disabled'; + $ret .= $this->elementEmpty('input', $attr); + + $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' No'); + $ret .= $this->end('label'); + + $attr = array( + 'type' => 'radio', + 'name' => "$name"."[$ns.$directive]", + 'id' => "$name:No_$ns.$directive", + 'value' => '0' + ); + if ($value === false) $attr['checked'] = 'checked'; + if ($value === null) $attr['disabled'] = 'disabled'; + $ret .= $this->elementEmpty('input', $attr); + + $ret .= $this->end('div'); + + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/HTMLDefinition.php b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/HTMLDefinition.php new file mode 100644 index 00000000..8a8f126b --- /dev/null +++ b/libraries/external/htmlpurifier-4.1.1-standalone/standalone/HTMLPurifier/Printer/HTMLDefinition.php @@ -0,0 +1,272 @@ +config =& $config; + + $this->def = $config->getHTMLDefinition(); + + $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer')); + + $ret .= $this->renderDoctype(); + $ret .= $this->renderEnvironment(); + $ret .= $this->renderContentSets(); + $ret .= $this->renderInfo(); + + $ret .= $this->end('div'); + + return $ret; + } + + /** + * Renders the Doctype table + */ + protected function renderDoctype() { + $doctype = $this->def->doctype; + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Doctype'); + $ret .= $this->row('Name', $doctype->name); + $ret .= $this->row('XML', $doctype->xml ? 'Yes' : 'No'); + $ret .= $this->row('Default Modules', implode($doctype->modules, ', ')); + $ret .= $this->row('Default Tidy Modules', implode($doctype->tidyModules, ', ')); + $ret .= $this->end('table'); + return $ret; + } + + + /** + * Renders environment table, which is miscellaneous info + */ + protected function renderEnvironment() { + $def = $this->def; + + $ret = ''; + + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Environment'); + + $ret .= $this->row('Parent of fragment', $def->info_parent); + $ret .= $this->renderChildren($def->info_parent_def->child); + $ret .= $this->row('Block wrap name', $def->info_block_wrapper); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Global attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr),0,0); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Tag transforms'); + $list = array(); + foreach ($def->info_tag_transform as $old => $new) { + $new = $this->getClass($new, 'TagTransform_'); + $list[] = "<$old> with $new"; + } + $ret .= $this->element('td', $this->listify($list)); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre)); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post)); + $ret .= $this->end('tr'); + + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders the Content Sets table + */ + protected function renderContentSets() { + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Content Sets'); + foreach ($this->def->info_content_sets as $name => $lookup) { + $ret .= $this->heavyHeader($name); + $ret .= $this->start('tr'); + $ret .= $this->element('td', $this->listifyTagLookup($lookup)); + $ret .= $this->end('tr'); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders the Elements ($info) table + */ + protected function renderInfo() { + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Elements ($info)'); + ksort($this->def->info); + $ret .= $this->heavyHeader('Allowed tags', 2); + $ret .= $this->start('tr'); + $ret .= $this->element('td', $this->listifyTagLookup($this->def->info), array('colspan' => 2)); + $ret .= $this->end('tr'); + foreach ($this->def->info as $name => $def) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', "<$name>", array('class'=>'heavy', 'colspan' => 2)); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Inline content'); + $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); + $ret .= $this->end('tr'); + if (!empty($def->excludes)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Excludes'); + $ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); + $ret .= $this->end('tr'); + } + if (!empty($def->attr_transform_pre)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); + $ret .= $this->end('tr'); + } + if (!empty($def->attr_transform_post)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); + $ret .= $this->end('tr'); + } + if (!empty($def->auto_close)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Auto closed by'); + $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); + $ret .= $this->end('tr'); + } + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Allowed attributes'); + $ret .= $this->element('td',$this->listifyAttr($def->attr), array(), 0); + $ret .= $this->end('tr'); + + if (!empty($def->required_attr)) { + $ret .= $this->row('Required attributes', $this->listify($def->required_attr)); + } + + $ret .= $this->renderChildren($def->child); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders a row describing the allowed children of an element + * @param $def HTMLPurifier_ChildDef of pertinent element + */ + protected function renderChildren($def) { + $context = new HTMLPurifier_Context(); + $ret = ''; + $ret .= $this->start('tr'); + $elements = array(); + $attr = array(); + if (isset($def->elements)) { + if ($def->type == 'strictblockquote') { + $def->validateChildren(array(), $this->config, $context); + } + $elements = $def->elements; + } + if ($def->type == 'chameleon') { + $attr['rowspan'] = 2; + } elseif ($def->type == 'empty') { + $elements = array(); + } elseif ($def->type == 'table') { + $elements = array_flip(array('col', 'caption', 'colgroup', 'thead', + 'tfoot', 'tbody', 'tr')); + } + $ret .= $this->element('th', 'Allowed children', $attr); + + if ($def->type == 'chameleon') { + + $ret .= $this->element('td', + 'Block: ' . + $this->escape($this->listifyTagLookup($def->block->elements)),0,0); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element('td', + 'Inline: ' . + $this->escape($this->listifyTagLookup($def->inline->elements)),0,0); + + } elseif ($def->type == 'custom') { + + $ret .= $this->element('td', ''.ucfirst($def->type).': ' . + $def->dtd_regex); + + } else { + $ret .= $this->element('td', + ''.ucfirst($def->type).': ' . + $this->escape($this->listifyTagLookup($elements)),0,0); + } + $ret .= $this->end('tr'); + return $ret; + } + + /** + * Listifies a tag lookup table. + * @param $array Tag lookup array in form of array('tagname' => true) + */ + protected function listifyTagLookup($array) { + ksort($array); + $list = array(); + foreach ($array as $name => $discard) { + if ($name !== '#PCDATA' && !isset($this->def->info[$name])) continue; + $list[] = $name; + } + return $this->listify($list); + } + + /** + * Listifies a list of objects by retrieving class names and internal state + * @param $array List of objects + * @todo Also add information about internal state + */ + protected function listifyObjectList($array) { + ksort($array); + $list = array(); + foreach ($array as $discard => $obj) { + $list[] = $this->getClass($obj, 'AttrTransform_'); + } + return $this->listify($list); + } + + /** + * Listifies a hash of attributes to AttrDef classes + * @param $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) + */ + protected function listifyAttr($array) { + ksort($array); + $list = array(); + foreach ($array as $name => $obj) { + if ($obj === false) continue; + $list[] = "$name = " . $this->getClass($obj, 'AttrDef_') . ''; + } + return $this->listify($list); + } + + /** + * Creates a heavy header row + */ + protected function heavyHeader($text, $num = 1) { + $ret = ''; + $ret .= $this->start('tr'); + $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy')); + $ret .= $this->end('tr'); + return $ret; + } + +} + +// vim: et sw=4 sts=4 diff --git a/libraries/external/jquery-1.4.2/jquery-1.4.2.min.js b/libraries/external/jquery-1.4.2/jquery-1.4.2.min.js new file mode 100644 index 00000000..7c243080 --- /dev/null +++ b/libraries/external/jquery-1.4.2/jquery-1.4.2.min.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
    a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

    ";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
    ";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
    ","
    "];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
    ").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
    "; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/system/appleseed.php b/system/appleseed.php new file mode 100644 index 00000000..677e0d5e --- /dev/null +++ b/system/appleseed.php @@ -0,0 +1,30 @@ +Initialize (); + +$zApple->Route (); + diff --git a/system/application.php b/system/application.php new file mode 100644 index 00000000..1110bb3d --- /dev/null +++ b/system/application.php @@ -0,0 +1,31 @@ +