mailgun-php/phpunit.phar
2013-07-17 22:48:12 -07:00

69889 lines
2.6 MiB
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env php
<?php
define('__PHPUNIT_PHAR__', realpath($GLOBALS['_SERVER']['SCRIPT_NAME']));
spl_autoload_register(
function ($class)
{
static $classes = NULL;
if ($classes === NULL) {
$classes = array(
'bankaccount' => '/DbUnit-1.2.3/Samples/BankAccountDB/BankAccount.php',
'bankaccountdbtest' => '/DbUnit-1.2.3/Samples/BankAccountDB/BankAccountDBTest.php',
'bankaccountdbtestmysql' => '/DbUnit-1.2.3/Samples/BankAccountDB/BankAccountDBTestMySQL.php',
'bankaccountexception' => '/DbUnit-1.2.3/Samples/BankAccountDB/BankAccount.php',
'file_iterator' => '/File_Iterator-1.3.3/File/Iterator.php',
'file_iterator_facade' => '/File_Iterator-1.3.3/File/Iterator/Facade.php',
'file_iterator_factory' => '/File_Iterator-1.3.3/File/Iterator/Factory.php',
'php_codecoverage' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage.php',
'php_codecoverage_driver' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Driver.php',
'php_codecoverage_driver_xdebug' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Driver/Xdebug.php',
'php_codecoverage_exception' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Exception.php',
'php_codecoverage_filter' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Filter.php',
'php_codecoverage_report_clover' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Clover.php',
'php_codecoverage_report_factory' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Factory.php',
'php_codecoverage_report_html' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML.php',
'php_codecoverage_report_html_renderer' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer.php',
'php_codecoverage_report_html_renderer_dashboard' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Dashboard.php',
'php_codecoverage_report_html_renderer_directory' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Directory.php',
'php_codecoverage_report_html_renderer_file' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/File.php',
'php_codecoverage_report_node' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node.php',
'php_codecoverage_report_node_directory' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node/Directory.php',
'php_codecoverage_report_node_file' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node/File.php',
'php_codecoverage_report_node_iterator' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node/Iterator.php',
'php_codecoverage_report_php' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/PHP.php',
'php_codecoverage_report_text' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Text.php',
'php_codecoverage_util' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Util.php',
'php_codecoverage_util_invalidargumenthelper' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Util/InvalidArgumentHelper.php',
'php_codecoverage_version' => '/PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Version.php',
'php_invoker' => '/PHP_Invoker-1.1.2/PHP/Invoker.php',
'php_invoker_timeoutexception' => '/PHP_Invoker-1.1.2/PHP/Invoker/TimeoutException.php',
'php_timer' => '/PHP_Timer-1.0.4/PHP/Timer.php',
'php_token' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_abstract' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_ampersand' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_and_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_array' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_array_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_as' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_at' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_backtick' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_bad_character' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_bool_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_boolean_and' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_boolean_or' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_break' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_callable' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_caret' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_case' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_catch' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_character' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_class' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_class_c' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_clone' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_close_bracket' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_close_curly' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_close_square' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_close_tag' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_colon' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_comma' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_comment' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_concat_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_const' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_constant_encapsed_string' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_continue' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_curly_open' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_dec' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_declare' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_default' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_dir' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_div' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_div_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_dnumber' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_do' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_doc_comment' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_dollar' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_dollar_open_curly_braces' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_dot' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_double_arrow' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_double_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_double_colon' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_double_quotes' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_echo' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_else' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_elseif' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_empty' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_encapsed_and_whitespace' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_end_heredoc' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_enddeclare' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_endfor' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_endforeach' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_endif' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_endswitch' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_endwhile' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_eval' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_exclamation_mark' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_exit' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_extends' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_file' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_final' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_for' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_foreach' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_func_c' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_function' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_global' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_goto' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_gt' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_halt_compiler' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_if' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_implements' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_inc' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_include' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_include_once' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_includes' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_inline_html' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_instanceof' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_insteadof' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_int_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_interface' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_is_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_is_greater_or_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_is_identical' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_is_not_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_is_not_identical' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_is_smaller_or_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_isset' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_line' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_list' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_lnumber' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_logical_and' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_logical_or' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_logical_xor' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_lt' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_method_c' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_minus' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_minus_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_mod_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_mul_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_mult' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_namespace' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_new' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_ns_c' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_ns_separator' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_num_string' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_object_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_object_operator' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_open_bracket' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_open_curly' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_open_square' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_open_tag' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_open_tag_with_echo' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_or_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_paamayim_nekudotayim' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_percent' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_pipe' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_plus' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_plus_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_print' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_private' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_protected' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_public' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_question_mark' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_require' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_require_once' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_return' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_semicolon' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_sl' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_sl_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_sr' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_sr_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_start_heredoc' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_static' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_stream' => '/PHP_TokenStream-1.1.5/PHP/Token/Stream.php',
'php_token_stream_cachingfactory' => '/PHP_TokenStream-1.1.5/PHP/Token/Stream/CachingFactory.php',
'php_token_string' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_string_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_string_varname' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_switch' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_throw' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_tilde' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_trait' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_trait_c' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_try' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_unset' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_unset_cast' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_use' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_var' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_variable' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_while' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_whitespace' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_token_xor_equal' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_tokenwithscope' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'php_tokenwithscopeandvisibility' => '/PHP_TokenStream-1.1.5/PHP/Token.php',
'phpunit_extensions_database_abstracttester' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/AbstractTester.php',
'phpunit_extensions_database_constraint_datasetisequal' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Constraint/DataSetIsEqual.php',
'phpunit_extensions_database_constraint_tableisequal' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Constraint/TableIsEqual.php',
'phpunit_extensions_database_constraint_tablerowcount' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Constraint/TableRowCount.php',
'phpunit_extensions_database_dataset_abstractdataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php',
'phpunit_extensions_database_dataset_abstracttable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractTable.php',
'phpunit_extensions_database_dataset_abstracttablemetadata' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php',
'phpunit_extensions_database_dataset_abstractxmldataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php',
'phpunit_extensions_database_dataset_compositedataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/CompositeDataSet.php',
'phpunit_extensions_database_dataset_csvdataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/CsvDataSet.php',
'phpunit_extensions_database_dataset_datasetfilter' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DataSetFilter.php',
'phpunit_extensions_database_dataset_defaultdataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultDataSet.php',
'phpunit_extensions_database_dataset_defaulttable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultTable.php',
'phpunit_extensions_database_dataset_defaulttableiterator' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php',
'phpunit_extensions_database_dataset_defaulttablemetadata' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php',
'phpunit_extensions_database_dataset_flatxmldataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.php',
'phpunit_extensions_database_dataset_idataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/IDataSet.php',
'phpunit_extensions_database_dataset_ipersistable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/IPersistable.php',
'phpunit_extensions_database_dataset_ispec' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ISpec.php',
'phpunit_extensions_database_dataset_itable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ITable.php',
'phpunit_extensions_database_dataset_itableiterator' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ITableIterator.php',
'phpunit_extensions_database_dataset_itablemetadata' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ITableMetaData.php',
'phpunit_extensions_database_dataset_mysqlxmldataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/MysqlXmlDataSet.php',
'phpunit_extensions_database_dataset_persistors_abstract' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php',
'phpunit_extensions_database_dataset_persistors_factory' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Factory.php',
'phpunit_extensions_database_dataset_persistors_flatxml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php',
'phpunit_extensions_database_dataset_persistors_mysqlxml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/MysqlXml.php',
'phpunit_extensions_database_dataset_persistors_xml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php',
'phpunit_extensions_database_dataset_persistors_yaml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php',
'phpunit_extensions_database_dataset_querydataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/QueryDataSet.php',
'phpunit_extensions_database_dataset_querytable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/QueryTable.php',
'phpunit_extensions_database_dataset_replacementdataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ReplacementDataSet.php',
'phpunit_extensions_database_dataset_replacementtable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ReplacementTable.php',
'phpunit_extensions_database_dataset_replacementtableiterator' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ReplacementTableIterator.php',
'phpunit_extensions_database_dataset_specs_csv' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Csv.php',
'phpunit_extensions_database_dataset_specs_dbquery' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/DbQuery.php',
'phpunit_extensions_database_dataset_specs_dbtable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/DbTable.php',
'phpunit_extensions_database_dataset_specs_factory' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Factory.php',
'phpunit_extensions_database_dataset_specs_flatxml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/FlatXml.php',
'phpunit_extensions_database_dataset_specs_ifactory' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/IFactory.php',
'phpunit_extensions_database_dataset_specs_xml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Xml.php',
'phpunit_extensions_database_dataset_specs_yaml' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Yaml.php',
'phpunit_extensions_database_dataset_tablefilter' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/TableFilter.php',
'phpunit_extensions_database_dataset_tablemetadatafilter' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/TableMetaDataFilter.php',
'phpunit_extensions_database_dataset_xmldataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/XmlDataSet.php',
'phpunit_extensions_database_dataset_yamldataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/YamlDataSet.php',
'phpunit_extensions_database_db_dataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/DataSet.php',
'phpunit_extensions_database_db_defaultdatabaseconnection' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php',
'phpunit_extensions_database_db_filtereddataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/FilteredDataSet.php',
'phpunit_extensions_database_db_idatabaseconnection' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/IDatabaseConnection.php',
'phpunit_extensions_database_db_imetadata' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/IMetaData.php',
'phpunit_extensions_database_db_metadata' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData.php',
'phpunit_extensions_database_db_metadata_informationschema' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php',
'phpunit_extensions_database_db_metadata_mysql' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/MySQL.php',
'phpunit_extensions_database_db_metadata_oci' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/Oci.php',
'phpunit_extensions_database_db_metadata_pgsql' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/PgSQL.php',
'phpunit_extensions_database_db_metadata_sqlite' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/Sqlite.php',
'phpunit_extensions_database_db_metadata_sqlsrv' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/SqlSrv.php',
'phpunit_extensions_database_db_resultsettable' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/ResultSetTable.php',
'phpunit_extensions_database_db_table' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/Table.php',
'phpunit_extensions_database_db_tableiterator' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/TableIterator.php',
'phpunit_extensions_database_db_tablemetadata' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/TableMetaData.php',
'phpunit_extensions_database_defaulttester' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/DefaultTester.php',
'phpunit_extensions_database_exception' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Exception.php',
'phpunit_extensions_database_idatabaselistconsumer' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/IDatabaseListConsumer.php',
'phpunit_extensions_database_itester' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/ITester.php',
'phpunit_extensions_database_operation_composite' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Composite.php',
'phpunit_extensions_database_operation_delete' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Delete.php',
'phpunit_extensions_database_operation_deleteall' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/DeleteAll.php',
'phpunit_extensions_database_operation_exception' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Exception.php',
'phpunit_extensions_database_operation_factory' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Factory.php',
'phpunit_extensions_database_operation_idatabaseoperation' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php',
'phpunit_extensions_database_operation_insert' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Insert.php',
'phpunit_extensions_database_operation_null' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Null.php',
'phpunit_extensions_database_operation_replace' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Replace.php',
'phpunit_extensions_database_operation_rowbased' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/RowBased.php',
'phpunit_extensions_database_operation_truncate' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Truncate.php',
'phpunit_extensions_database_operation_update' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Update.php',
'phpunit_extensions_database_testcase' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/TestCase.php',
'phpunit_extensions_database_ui_command' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Command.php',
'phpunit_extensions_database_ui_context' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Context.php',
'phpunit_extensions_database_ui_imedium' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IMedium.php',
'phpunit_extensions_database_ui_imediumprinter' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IMediumPrinter.php',
'phpunit_extensions_database_ui_imode' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IMode.php',
'phpunit_extensions_database_ui_imodefactory' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IModeFactory.php',
'phpunit_extensions_database_ui_invalidmodeexception' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/InvalidModeException.php',
'phpunit_extensions_database_ui_mediums_text' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Mediums/Text.php',
'phpunit_extensions_database_ui_modefactory' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/ModeFactory.php',
'phpunit_extensions_database_ui_modes_exportdataset' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet.php',
'phpunit_extensions_database_ui_modes_exportdataset_arguments' => '/DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php',
'phpunit_extensions_grouptestsuite' => '/PHPUnit/Extensions/GroupTestSuite.php',
'phpunit_extensions_phpttestcase' => '/PHPUnit/Extensions/PhptTestCase.php',
'phpunit_extensions_phpttestcase_logger' => '/PHPUnit/Extensions/PhptTestCase/Logger.php',
'phpunit_extensions_phpttestsuite' => '/PHPUnit/Extensions/PhptTestSuite.php',
'phpunit_extensions_repeatedtest' => '/PHPUnit/Extensions/RepeatedTest.php',
'phpunit_extensions_selenium2testcase' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase.php',
'phpunit_extensions_selenium2testcase_command' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Command.php',
'phpunit_extensions_selenium2testcase_commandsholder' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/CommandsHolder.php',
'phpunit_extensions_selenium2testcase_driver' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Driver.php',
'phpunit_extensions_selenium2testcase_element' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Element.php',
'phpunit_extensions_selenium2testcase_element_accessor' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Element/Accessor.php',
'phpunit_extensions_selenium2testcase_element_select' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Element/Select.php',
'phpunit_extensions_selenium2testcase_elementcommand_attribute' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Attribute.php',
'phpunit_extensions_selenium2testcase_elementcommand_click' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Click.php',
'phpunit_extensions_selenium2testcase_elementcommand_css' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Css.php',
'phpunit_extensions_selenium2testcase_elementcommand_equals' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Equals.php',
'phpunit_extensions_selenium2testcase_elementcommand_genericaccessor' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.php',
'phpunit_extensions_selenium2testcase_elementcommand_genericpost' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/GenericPost.php',
'phpunit_extensions_selenium2testcase_elementcommand_value' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Value.php',
'phpunit_extensions_selenium2testcase_elementcriteria' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCriteria.php',
'phpunit_extensions_selenium2testcase_exception' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Exception.php',
'phpunit_extensions_selenium2testcase_keys' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Keys.php',
'phpunit_extensions_selenium2testcase_keysholder' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/KeysHolder.php',
'phpunit_extensions_selenium2testcase_noseleniumexception' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/NoSeleniumException.php',
'phpunit_extensions_selenium2testcase_response' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Response.php',
'phpunit_extensions_selenium2testcase_screenshotlistener' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ScreenshotListener.php',
'phpunit_extensions_selenium2testcase_session' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session.php',
'phpunit_extensions_selenium2testcase_session_cookie' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Cookie.php',
'phpunit_extensions_selenium2testcase_session_cookie_builder' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Cookie/Builder.php',
'phpunit_extensions_selenium2testcase_session_storage' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Storage.php',
'phpunit_extensions_selenium2testcase_session_timeouts' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Timeouts.php',
'phpunit_extensions_selenium2testcase_sessioncommand_acceptalert' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php',
'phpunit_extensions_selenium2testcase_sessioncommand_alerttext' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/AlertText.php',
'phpunit_extensions_selenium2testcase_sessioncommand_click' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Click.php',
'phpunit_extensions_selenium2testcase_sessioncommand_dismissalert' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php',
'phpunit_extensions_selenium2testcase_sessioncommand_frame' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Frame.php',
'phpunit_extensions_selenium2testcase_sessioncommand_genericaccessor' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.php',
'phpunit_extensions_selenium2testcase_sessioncommand_genericattribute' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php',
'phpunit_extensions_selenium2testcase_sessioncommand_keys' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Keys.php',
'phpunit_extensions_selenium2testcase_sessioncommand_location' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Location.php',
'phpunit_extensions_selenium2testcase_sessioncommand_moveto' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php',
'phpunit_extensions_selenium2testcase_sessioncommand_orientation' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Orientation.php',
'phpunit_extensions_selenium2testcase_sessioncommand_url' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Url.php',
'phpunit_extensions_selenium2testcase_sessioncommand_window' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Window.php',
'phpunit_extensions_selenium2testcase_sessionstrategy' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionStrategy.php',
'phpunit_extensions_selenium2testcase_sessionstrategy_isolated' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php',
'phpunit_extensions_selenium2testcase_sessionstrategy_shared' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionStrategy/Shared.php',
'phpunit_extensions_selenium2testcase_statecommand' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/StateCommand.php',
'phpunit_extensions_selenium2testcase_url' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/URL.php',
'phpunit_extensions_selenium2testcase_waituntil' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/WaitUntil.php',
'phpunit_extensions_selenium2testcase_webdriverexception' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/WebDriverException.php',
'phpunit_extensions_selenium2testcase_window' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Window.php',
'phpunit_extensions_seleniumbrowsersuite' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumBrowserSuite.php',
'phpunit_extensions_seleniumcommon_remotecoverage' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumCommon/RemoteCoverage.php',
'phpunit_extensions_seleniumtestcase' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumTestCase.php',
'phpunit_extensions_seleniumtestcase_driver' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumTestCase/Driver.php',
'phpunit_extensions_seleniumtestsuite' => '/PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumTestSuite.php',
'phpunit_extensions_testdecorator' => '/PHPUnit/Extensions/TestDecorator.php',
'phpunit_extensions_ticketlistener' => '/PHPUnit/Extensions/TicketListener.php',
'phpunit_framework_assert' => '/PHPUnit/Framework/Assert.php',
'phpunit_framework_assertionfailederror' => '/PHPUnit/Framework/AssertionFailedError.php',
'phpunit_framework_comparator' => '/PHPUnit/Framework/Comparator.php',
'phpunit_framework_comparator_array' => '/PHPUnit/Framework/Comparator/Array.php',
'phpunit_framework_comparator_domdocument' => '/PHPUnit/Framework/Comparator/DOMDocument.php',
'phpunit_framework_comparator_double' => '/PHPUnit/Framework/Comparator/Double.php',
'phpunit_framework_comparator_exception' => '/PHPUnit/Framework/Comparator/Exception.php',
'phpunit_framework_comparator_mockobject' => '/PHPUnit/Framework/Comparator/MockObject.php',
'phpunit_framework_comparator_numeric' => '/PHPUnit/Framework/Comparator/Numeric.php',
'phpunit_framework_comparator_object' => '/PHPUnit/Framework/Comparator/Object.php',
'phpunit_framework_comparator_resource' => '/PHPUnit/Framework/Comparator/Resource.php',
'phpunit_framework_comparator_scalar' => '/PHPUnit/Framework/Comparator/Scalar.php',
'phpunit_framework_comparator_splobjectstorage' => '/PHPUnit/Framework/Comparator/SplObjectStorage.php',
'phpunit_framework_comparator_type' => '/PHPUnit/Framework/Comparator/Type.php',
'phpunit_framework_comparatorfactory' => '/PHPUnit/Framework/ComparatorFactory.php',
'phpunit_framework_comparisonfailure' => '/PHPUnit/Framework/ComparisonFailure.php',
'phpunit_framework_constraint' => '/PHPUnit/Framework/Constraint.php',
'phpunit_framework_constraint_and' => '/PHPUnit/Framework/Constraint/And.php',
'phpunit_framework_constraint_arrayhaskey' => '/PHPUnit/Framework/Constraint/ArrayHasKey.php',
'phpunit_framework_constraint_attribute' => '/PHPUnit/Framework/Constraint/Attribute.php',
'phpunit_framework_constraint_callback' => '/PHPUnit/Framework/Constraint/Callback.php',
'phpunit_framework_constraint_classhasattribute' => '/PHPUnit/Framework/Constraint/ClassHasAttribute.php',
'phpunit_framework_constraint_classhasstaticattribute' => '/PHPUnit/Framework/Constraint/ClassHasStaticAttribute.php',
'phpunit_framework_constraint_composite' => '/PHPUnit/Framework/Constraint/Composite.php',
'phpunit_framework_constraint_count' => '/PHPUnit/Framework/Constraint/Count.php',
'phpunit_framework_constraint_exception' => '/PHPUnit/Framework/Constraint/Exception.php',
'phpunit_framework_constraint_exceptioncode' => '/PHPUnit/Framework/Constraint/ExceptionCode.php',
'phpunit_framework_constraint_exceptionmessage' => '/PHPUnit/Framework/Constraint/ExceptionMessage.php',
'phpunit_framework_constraint_fileexists' => '/PHPUnit/Framework/Constraint/FileExists.php',
'phpunit_framework_constraint_greaterthan' => '/PHPUnit/Framework/Constraint/GreaterThan.php',
'phpunit_framework_constraint_isanything' => '/PHPUnit/Framework/Constraint/IsAnything.php',
'phpunit_framework_constraint_isempty' => '/PHPUnit/Framework/Constraint/IsEmpty.php',
'phpunit_framework_constraint_isequal' => '/PHPUnit/Framework/Constraint/IsEqual.php',
'phpunit_framework_constraint_isfalse' => '/PHPUnit/Framework/Constraint/IsFalse.php',
'phpunit_framework_constraint_isidentical' => '/PHPUnit/Framework/Constraint/IsIdentical.php',
'phpunit_framework_constraint_isinstanceof' => '/PHPUnit/Framework/Constraint/IsInstanceOf.php',
'phpunit_framework_constraint_isjson' => '/PHPUnit/Framework/Constraint/IsJson.php',
'phpunit_framework_constraint_isnull' => '/PHPUnit/Framework/Constraint/IsNull.php',
'phpunit_framework_constraint_istrue' => '/PHPUnit/Framework/Constraint/IsTrue.php',
'phpunit_framework_constraint_istype' => '/PHPUnit/Framework/Constraint/IsType.php',
'phpunit_framework_constraint_jsonmatches' => '/PHPUnit/Framework/Constraint/JsonMatches.php',
'phpunit_framework_constraint_jsonmatches_errormessageprovider' => '/PHPUnit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php',
'phpunit_framework_constraint_lessthan' => '/PHPUnit/Framework/Constraint/LessThan.php',
'phpunit_framework_constraint_not' => '/PHPUnit/Framework/Constraint/Not.php',
'phpunit_framework_constraint_objecthasattribute' => '/PHPUnit/Framework/Constraint/ObjectHasAttribute.php',
'phpunit_framework_constraint_or' => '/PHPUnit/Framework/Constraint/Or.php',
'phpunit_framework_constraint_pcrematch' => '/PHPUnit/Framework/Constraint/PCREMatch.php',
'phpunit_framework_constraint_samesize' => '/PHPUnit/Framework/Constraint/SameSize.php',
'phpunit_framework_constraint_stringcontains' => '/PHPUnit/Framework/Constraint/StringContains.php',
'phpunit_framework_constraint_stringendswith' => '/PHPUnit/Framework/Constraint/StringEndsWith.php',
'phpunit_framework_constraint_stringmatches' => '/PHPUnit/Framework/Constraint/StringMatches.php',
'phpunit_framework_constraint_stringstartswith' => '/PHPUnit/Framework/Constraint/StringStartsWith.php',
'phpunit_framework_constraint_traversablecontains' => '/PHPUnit/Framework/Constraint/TraversableContains.php',
'phpunit_framework_constraint_traversablecontainsonly' => '/PHPUnit/Framework/Constraint/TraversableContainsOnly.php',
'phpunit_framework_constraint_xor' => '/PHPUnit/Framework/Constraint/Xor.php',
'phpunit_framework_error' => '/PHPUnit/Framework/Error.php',
'phpunit_framework_error_deprecated' => '/PHPUnit/Framework/Error/Deprecated.php',
'phpunit_framework_error_notice' => '/PHPUnit/Framework/Error/Notice.php',
'phpunit_framework_error_warning' => '/PHPUnit/Framework/Error/Warning.php',
'phpunit_framework_exception' => '/PHPUnit/Framework/Exception.php',
'phpunit_framework_expectationfailedexception' => '/PHPUnit/Framework/ExpectationFailedException.php',
'phpunit_framework_incompletetest' => '/PHPUnit/Framework/IncompleteTest.php',
'phpunit_framework_incompletetesterror' => '/PHPUnit/Framework/IncompleteTestError.php',
'phpunit_framework_mockobject_builder_identity' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Identity.php',
'phpunit_framework_mockobject_builder_invocationmocker' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php',
'phpunit_framework_mockobject_builder_match' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Match.php',
'phpunit_framework_mockobject_builder_methodnamematch' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php',
'phpunit_framework_mockobject_builder_namespace' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Namespace.php',
'phpunit_framework_mockobject_builder_parametersmatch' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/ParametersMatch.php',
'phpunit_framework_mockobject_builder_stub' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Stub.php',
'phpunit_framework_mockobject_generator' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator.php',
'phpunit_framework_mockobject_invocation' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invocation.php',
'phpunit_framework_mockobject_invocation_object' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invocation/Object.php',
'phpunit_framework_mockobject_invocation_static' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invocation/Static.php',
'phpunit_framework_mockobject_invocationmocker' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/InvocationMocker.php',
'phpunit_framework_mockobject_invokable' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invokable.php',
'phpunit_framework_mockobject_matcher' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher.php',
'phpunit_framework_mockobject_matcher_anyinvokedcount' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php',
'phpunit_framework_mockobject_matcher_anyparameters' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php',
'phpunit_framework_mockobject_matcher_invocation' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/Invocation.php',
'phpunit_framework_mockobject_matcher_invokedatindex' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php',
'phpunit_framework_mockobject_matcher_invokedatleastonce' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
'phpunit_framework_mockobject_matcher_invokedcount' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedCount.php',
'phpunit_framework_mockobject_matcher_invokedrecorder' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php',
'phpunit_framework_mockobject_matcher_methodname' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/MethodName.php',
'phpunit_framework_mockobject_matcher_parameters' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/Parameters.php',
'phpunit_framework_mockobject_matcher_statelessinvocation' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php',
'phpunit_framework_mockobject_mockbuilder' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/MockBuilder.php',
'phpunit_framework_mockobject_mockobject' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/MockObject.php',
'phpunit_framework_mockobject_stub' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub.php',
'phpunit_framework_mockobject_stub_consecutivecalls' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php',
'phpunit_framework_mockobject_stub_exception' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/Exception.php',
'phpunit_framework_mockobject_stub_matchercollection' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/MatcherCollection.php',
'phpunit_framework_mockobject_stub_return' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/Return.php',
'phpunit_framework_mockobject_stub_returnargument' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnArgument.php',
'phpunit_framework_mockobject_stub_returncallback' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php',
'phpunit_framework_mockobject_stub_returnself' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnSelf.php',
'phpunit_framework_mockobject_stub_returnvaluemap' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnValueMap.php',
'phpunit_framework_mockobject_verifiable' => '/PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Verifiable.php',
'phpunit_framework_outputerror' => '/PHPUnit/Framework/OutputError.php',
'phpunit_framework_selfdescribing' => '/PHPUnit/Framework/SelfDescribing.php',
'phpunit_framework_skippedtest' => '/PHPUnit/Framework/SkippedTest.php',
'phpunit_framework_skippedtesterror' => '/PHPUnit/Framework/SkippedTestError.php',
'phpunit_framework_skippedtestsuiteerror' => '/PHPUnit/Framework/SkippedTestSuiteError.php',
'phpunit_framework_syntheticerror' => '/PHPUnit/Framework/SyntheticError.php',
'phpunit_framework_test' => '/PHPUnit/Framework/Test.php',
'phpunit_framework_testcase' => '/PHPUnit/Framework/TestCase.php',
'phpunit_framework_testfailure' => '/PHPUnit/Framework/TestFailure.php',
'phpunit_framework_testlistener' => '/PHPUnit/Framework/TestListener.php',
'phpunit_framework_testresult' => '/PHPUnit/Framework/TestResult.php',
'phpunit_framework_testsuite' => '/PHPUnit/Framework/TestSuite.php',
'phpunit_framework_testsuite_dataprovider' => '/PHPUnit/Framework/TestSuite/DataProvider.php',
'phpunit_framework_warning' => '/PHPUnit/Framework/Warning.php',
'phpunit_runner_basetestrunner' => '/PHPUnit/Runner/BaseTestRunner.php',
'phpunit_runner_standardtestsuiteloader' => '/PHPUnit/Runner/StandardTestSuiteLoader.php',
'phpunit_runner_testsuiteloader' => '/PHPUnit/Runner/TestSuiteLoader.php',
'phpunit_runner_version' => '/PHPUnit/Runner/Version.php',
'phpunit_textui_command' => '/PHPUnit/TextUI/Command.php',
'phpunit_textui_resultprinter' => '/PHPUnit/TextUI/ResultPrinter.php',
'phpunit_textui_testrunner' => '/PHPUnit/TextUI/TestRunner.php',
'phpunit_util_class' => '/PHPUnit/Util/Class.php',
'phpunit_util_configuration' => '/PHPUnit/Util/Configuration.php',
'phpunit_util_deprecatedfeature' => '/PHPUnit/Util/DeprecatedFeature.php',
'phpunit_util_deprecatedfeature_logger' => '/PHPUnit/Util/DeprecatedFeature/Logger.php',
'phpunit_util_diff' => '/PHPUnit/Util/Diff.php',
'phpunit_util_errorhandler' => '/PHPUnit/Util/ErrorHandler.php',
'phpunit_util_fileloader' => '/PHPUnit/Util/Fileloader.php',
'phpunit_util_filesystem' => '/PHPUnit/Util/Filesystem.php',
'phpunit_util_filter' => '/PHPUnit/Util/Filter.php',
'phpunit_util_getopt' => '/PHPUnit/Util/Getopt.php',
'phpunit_util_globalstate' => '/PHPUnit/Util/GlobalState.php',
'phpunit_util_invalidargumenthelper' => '/PHPUnit/Util/InvalidArgumentHelper.php',
'phpunit_util_log_json' => '/PHPUnit/Util/Log/JSON.php',
'phpunit_util_log_junit' => '/PHPUnit/Util/Log/JUnit.php',
'phpunit_util_log_tap' => '/PHPUnit/Util/Log/TAP.php',
'phpunit_util_php' => '/PHPUnit/Util/PHP.php',
'phpunit_util_php_default' => '/PHPUnit/Util/PHP/Default.php',
'phpunit_util_php_windows' => '/PHPUnit/Util/PHP/Windows.php',
'phpunit_util_printer' => '/PHPUnit/Util/Printer.php',
'phpunit_util_string' => '/PHPUnit/Util/String.php',
'phpunit_util_test' => '/PHPUnit/Util/Test.php',
'phpunit_util_testdox_nameprettifier' => '/PHPUnit/Util/TestDox/NamePrettifier.php',
'phpunit_util_testdox_resultprinter' => '/PHPUnit/Util/TestDox/ResultPrinter.php',
'phpunit_util_testdox_resultprinter_html' => '/PHPUnit/Util/TestDox/ResultPrinter/HTML.php',
'phpunit_util_testdox_resultprinter_text' => '/PHPUnit/Util/TestDox/ResultPrinter/Text.php',
'phpunit_util_testsuiteiterator' => '/PHPUnit/Util/TestSuiteIterator.php',
'phpunit_util_type' => '/PHPUnit/Util/Type.php',
'phpunit_util_xml' => '/PHPUnit/Util/XML.php',
'symfony\\component\\yaml\\dumper' => '/Yaml-2.2.0/Symfony/Component/Yaml/Dumper.php',
'symfony\\component\\yaml\\escaper' => '/Yaml-2.2.0/Symfony/Component/Yaml/Escaper.php',
'symfony\\component\\yaml\\exception\\dumpexception' => '/Yaml-2.2.0/Symfony/Component/Yaml/Exception/DumpException.php',
'symfony\\component\\yaml\\exception\\exceptioninterface' => '/Yaml-2.2.0/Symfony/Component/Yaml/Exception/ExceptionInterface.php',
'symfony\\component\\yaml\\exception\\parseexception' => '/Yaml-2.2.0/Symfony/Component/Yaml/Exception/ParseException.php',
'symfony\\component\\yaml\\exception\\runtimeexception' => '/Yaml-2.2.0/Symfony/Component/Yaml/Exception/RuntimeException.php',
'symfony\\component\\yaml\\inline' => '/Yaml-2.2.0/Symfony/Component/Yaml/Inline.php',
'symfony\\component\\yaml\\parser' => '/Yaml-2.2.0/Symfony/Component/Yaml/Parser.php',
'symfony\\component\\yaml\\tests\\a' => '/Yaml-2.2.0/Symfony/Component/Yaml/Tests/DumperTest.php',
'symfony\\component\\yaml\\tests\\b' => '/Yaml-2.2.0/Symfony/Component/Yaml/Tests/ParserTest.php',
'symfony\\component\\yaml\\tests\\dumpertest' => '/Yaml-2.2.0/Symfony/Component/Yaml/Tests/DumperTest.php',
'symfony\\component\\yaml\\tests\\inlinetest' => '/Yaml-2.2.0/Symfony/Component/Yaml/Tests/InlineTest.php',
'symfony\\component\\yaml\\tests\\parsertest' => '/Yaml-2.2.0/Symfony/Component/Yaml/Tests/ParserTest.php',
'symfony\\component\\yaml\\tests\\yamltest' => '/Yaml-2.2.0/Symfony/Component/Yaml/Tests/YamlTest.php',
'symfony\\component\\yaml\\unescaper' => '/Yaml-2.2.0/Symfony/Component/Yaml/Unescaper.php',
'symfony\\component\\yaml\\yaml' => '/Yaml-2.2.0/Symfony/Component/Yaml/Yaml.php',
'text_template' => '/Text_Template-1.1.4/Text/Template.php'
);
}
$class = strtolower($class);
if (isset($classes[$class])) {
require 'phar://phpunit-3.7.22.phar' . $classes[$class];
}
}
);
Phar::mapPhar('phpunit-3.7.22.phar');
PHPUnit_TextUI_Command::main();
__HALT_COMPILER(); ?>
ݏ<00>phpunit-3.7.22.pharFile_Iterator-1.3.3/LICENSE <><7F>Q  <20><><FE>&File_Iterator-1.3.3/ChangeLog.markdownT<><7F>QTǎ<>X<CC>#File_Iterator-1.3.3/README.markdownF<><7F>QF<00>_h'<27>%File_Iterator-1.3.3/File/Iterator.phpk<><7F>Qk<00>M<C29D>,File_Iterator-1.3.3/File/Iterator/Facade.php<68><><7F>Q<D7><00>-File_Iterator-1.3.3/File/Iterator/Factory.phpC<><7F>QC<00>=<3D><><97> PHPUnit_MockObject-1.2.3/LICENSE<><7F>QBҶCPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invokable.php= <><7F>Q= <00><15><><8B>SPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/wsdl_class.tpl.dist<73><><7F>Q<D7><00><><8E><08>WPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/unmocked_clone.tpl.dist<73><><7F>Q<D7>8W}ض]PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/mocked_object_method.tpl.dist<73><><7F>Q<D7><00>bV<62><56>TPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/wsdl_method.tpl.dist<<><7F>Q<<00><>i<D0><69>]PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/mocked_static_method.tpl.dist<73><><7F>Q<D7><00>><3E>K<A6>UPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/mocked_class.tpl.dist<73><><7F>Q<D7><00>b)<29>UPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/mocked_clone.tpl.dist<73><><7F>Q<D7><00>aT<61>TPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator/trait_class.tpl.dist-<><7F>Q-<00>1<98>,<2C>CPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Generator.php%i<><7F>Q%ip<>p)<29>LPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/MethodName.phpJ<><7F>QJ<08>k<D4><6B>TPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php7 <><7F>Q7 <00><><87>Q<DF>QPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php<68><><7F>Q<D7><00>?<3F>d<EF>OPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php<68> <><7F>Q<D7> g<><67><82><8C>NPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedCount.phpz<><7F>Qz<00>_F<>QPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.phpI <><7F>QI <00><>DH<44>LPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/Parameters.php<68><><7F>Q<D7><00><><1E>LPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/Invocation.php<68><><7F>Q<D7><00>an<61>UPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php<><7F>Qt<><74><1F>PPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php}<><7F>Q}<00><>EPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/MockBuilder.php<68><><7F>Q<D7><00>q<10>APHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Matcher.php<68>&<><7F>Q<D7>&$<24>q<16>JPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/InvocationMocker.php<><7F>Qf<7F><66><FB>KPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invocation/Static.phpF<><7F>QF (<28><><FC>KPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invocation/Object.php
<><7F>Q
<00>ҥ<AD><D2A5>EPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/Return.php<68> <><7F>Q<D7> #<23><>ʶPPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/MatcherCollection.phpj <><7F>Qj <00><><CD>_<D9>MPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnArgument.phpm <><7F>Qm #D j<>IPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnSelf.php<68> <><7F>Q<D7> p<>HPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/Exception.phpb <><7F>Qb +<2B>`<60>OPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php <><7F>Q <00><>G<AE><47>MPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php<68> <><7F>Q<D7> <00>+<2B><><9D>MPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub/ReturnValueMap.php<68> <><7F>Q<D7> `<60>Y<CB><59>DPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Verifiable.php <><7F>Q |<7C><>DPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Invocation.php<68> <><7F>Q<D7> <00>7<B2><37><F9>>PHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Stub.php] <><7F>Q] <00><><B9>ǶQPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/ParametersMatch.phpi<><7F>Qi<04>9<92>GPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Match.phpx <><7F>Qx h<><68><8D><93>RPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php<68><><7F>Q<D7><00>*<2A>b<AC>KPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Namespace.php<68> <><7F>Q<D7> <00>G<><47>QPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php <><7F>Q <00>6<17><>JPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Identity.php<68> <><7F>Q<D7> <00><>h_<68>FPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/Builder/Stub.php<68> <><7F>Q<D7> 0<><30><17>DPHPUnit_MockObject-1.2.3/PHPUnit/Framework/MockObject/MockObject.php<68><><7F>Q<D7>ǧ<>4<FC>+PHPUnit_MockObject-1.2.3/ChangeLog.markdown<77><><7F>Q<D7>U<>z<>PHPUnit_Selenium-1.3.1/LICENSE<><7F>Qv<> ޶?PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumTestSuite.phpD<><7F>QDrF<><46>?PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase.php<68>A<><7F>Q<D7>A<00>LT϶EPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumTestCase/Driver.phpR<70><><7F>QR<51><00>r<C5><1D>BPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumBrowserSuite.php<68><><7F>Q<D7><00><>3<C8><33>>PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumTestCase.php<68><70><><7F>Q<D7><51>B <09><><C3>RPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Css.php] <><7F>Q] _<>4@<40>^PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.php]
<><7F>Q]
<00>d<C9><64><8E>UPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Equals.phpT <><7F>QT <00>g<B3><67><97>ZPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/GenericPost.phpK
<><7F>QK
<00><><B2><FB><AC>TPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Value.php<68>
<><7F>Q<D7>
<00><><00><>XPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Attribute.phph <><7F>Qh (<28><>$<24>TPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCommand/Click.php
<><7F>Q
<11><>&<26>JPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/KeysHolder.php<><7F>Q)˪p<CBAA>PPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Element/Accessor.php<68><><7F>Q<D7><00>!.<2E><>NPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Element/Select.php0<><7F>Q0<00>O<FE><4F><AE>GPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Command.php@ <><7F>Q@ [<5B><>L<DE>IPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Exception.php<68> <><7F>Q<D7> 2
<B4>c<B6>FPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Driver.php"<><7F>Q":0<>x<DC>LPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/StateCommand.phpk
<><7F>Qk
<1F>O<9B><4F>HPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Response.phpF <><7F>QF <00><>SPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/NoSeleniumException.php<68> <><7F>Q<D7>
d}L<>RPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/WebDriverException.phpZ <><7F>QZ
<C0>d<B0><B6>GPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session.php2,<><7F>Q2,<00><>I<>XPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php<68> <><7F>Q<D7> 6<><36><99><A5>VPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionStrategy/Shared.php<<><7F>Q<N<7F>R<D5>FPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Window.phpC <><7F>QC <00><14>+<2B>CPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/URL.php<68><><7F>Q<D7>Rr<00><>DPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Keys.php=<><7F>Q=<01><13><>OPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Storage.php, <><7F>Q, <00><><E9><13>NPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Cookie.php<68><><7F>Q<D7><9.D<>VPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Cookie/Builder.php<><7F>QY<>n<A6><6E>PPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Session/Timeouts.phpM<><7F>QM<17>`<60><>OPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionStrategy.php<68> <><7F>Q<D7> R$<24>r<B3>OPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ElementCriteria.phpB <><7F>QB x<>A\<5C>WPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Location.php<68> <><7F>Q<D7> <00><>><3E><>[PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php*
<><7F>Q*
漩/<2F>TPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Frame.php<68> <><7F>Q<D7> <1E><>۶^PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.phpH
<><7F>QH
2<> <09><>RPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Url.php <><7F>Q ;<3B>XPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/AlertText.php7 <><7F>Q7 H<>xs<78>UPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Window.php<68>
<><7F>Q<D7>
Ka<03><>SPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Keys.php<><7F>Q<00><10>F<DF>UPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php<68> <><7F>Q<D7> z<>]<01>_PHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php<68>
<><7F>Q<D7>
<00><><9D><EC><94>ZPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php%
<><7F>Q%
<00>O<8D><4F><CE>ZPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Orientation.php<68> <><7F>Q<D7> `<60><1B><>TPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/SessionCommand/Click.php<68> <><7F>Q<D7> <00>ɿ߶RPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/ScreenshotListener.php{<><7F>Q{6;<3B>E<C1>GPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/Element.php<68><><7F>Q<D7>fF<66>:<3A>NPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/CommandsHolder.php<68><><7F>Q<D7><00>IPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/Selenium2TestCase/WaitUntil.phpx<><7F>Qx <0C>|<7C><>DPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumCommon/prepend.php<68>
<><7F>Q<D7>
<00><>KPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumCommon/RemoteCoverage.php><><7F>Q>*dBʶMPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumCommon/phpunit_coverage.php<68> <><7F>Q<D7> ow<6F><77><8D>CPHPUnit_Selenium-1.3.1/PHPUnit/Extensions/SeleniumCommon/append.php <><7F>Q <00><><9B><B7><FA>)PHPUnit_Selenium-1.3.1/ChangeLog.markdown<><7F>Q<00>*<2A>n<C5>DbUnit-1.2.3/dbunit.batn<><7F>Qnq{O<><4F>DbUnit-1.2.3/LICENSE<><7F>Q<00> <09> <0B>IDbUnit-1.2.3/PHPUnit/Extensions/Database/DB/DefaultDatabaseConnection.php<68><><7F>Q<D7>0<><0F>5DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/Table.php<68> <><7F>Q<D7> (ZjK<6A>9DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/IMetaData.php*<><7F>Q*<00>X<06><>=DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/TableIterator.php~<><7F>Q~H<>"<22><>CDbUnit-1.2.3/PHPUnit/Extensions/Database/DB/IDatabaseConnection.php<68><><7F>Q<D7>^p<><70>7DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/DataSet.php<68><><7F>Q<D7>?><3E><><96>?DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/FilteredDataSet.phpA <><7F>QA ʂ<>:<3A>JDbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/InformationSchema.php<68><><7F>Q<D7>dGT6<54><DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/Oci.phpJ<><7F>QJ<00><>>DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/PgSQL.phpv<><7F>Qvyr<79>-<2D>?DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/Sqlite.php<><7F>Q<00>ۆ&<26>>DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/MySQL.php<68><><7F>Q<D7><00><><F7>ƶ?DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData/SqlSrv.php<68><><7F>Q<D7><00>b<87>2<93>=DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/TableMetaData.php <><7F>Q <00>Y<DE>%<25>>DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/ResultSetTable.php<68> <><7F>Q<D7> <00><><9E>
<B6>8DbUnit-1.2.3/PHPUnit/Extensions/Database/DB/MetaData.php<68><><7F>Q<D7><00><><B3>ʶ5DbUnit-1.2.3/PHPUnit/Extensions/Database/TestCase.php%<><7F>Q%<00><><EB>=<3D>7DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Command.phpF <><7F>QF <00><><CB>W<CC>7DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IMedium.phpM <><7F>QM b<><62>ŶMDbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php<><7F>Q#_<><5F><D1>CDbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Modes/ExportDataSet.php<68><><7F>Q<D7>|<7C><> <0A>;DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/ModeFactory.php<><7F>Q?<3F>_"<22><DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Mediums/Text.php<68><><7F>Q<D7>|<7C>J<AA><4A>7DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/Context.php <><7F>Q ѫ<04><>DDbUnit-1.2.3/PHPUnit/Extensions/Database/UI/InvalidModeException.php<68> <><7F>Q<D7> LFi<46><69>5DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IMode.php<68>
<><7F>Q<D7>
<00>W<BF>;<3B>>DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IMediumPrinter.php<68>
<><7F>Q<D7>
{4J˶<DbUnit-1.2.3/PHPUnit/Extensions/Database/UI/IModeFactory.php<68>
<><7F>Q<D7>
cg]9<>@DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Exception.php<68><><7F>Q<D7><00><><9D>h<BE>=DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Delete.php<68> <><7F>Q<D7> <00><><85>~<7E>=DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Insert.php<68><><7F>Q<D7><00>~<7E><><CC>?DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/RowBased.php6<><7F>Q6~
JN<B6>@DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/DeleteAll.php<68> <><7F>Q<D7> <07>n{<7B>=DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Update.php<68><><7F>Q<D7><00>3f<33><66>;DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Null.php<68>
<><7F>Q<D7>
՘MX<4D>IDbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/IDatabaseOperation.php<68> <><7F>Q<D7> >k<><6B>@DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Composite.php<68><><7F>Q<D7><1F>J<03>?DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Truncate.php<68> <><7F>Q<D7> <00>kJ<6B><4A>>DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Replace.phpQ<><7F>QQ<00><>È<E7>>DbUnit-1.2.3/PHPUnit/Extensions/Database/Operation/Factory.php<68><><7F>Q<D7><00><><9A><0F>6DbUnit-1.2.3/PHPUnit/Extensions/Database/Exception.php<68> <><7F>Q<D7> <00>Y?<3F><>DDbUnit-1.2.3/PHPUnit/Extensions/Database/Constraint/TableIsEqual.phpX<><7F>QX}<7D><1C>FDbUnit-1.2.3/PHPUnit/Extensions/Database/Constraint/DataSetIsEqual.phpf<><7F>Qf<00><>Tu<54>EDbUnit-1.2.3/PHPUnit/Extensions/Database/Constraint/TableRowCount.phpW <><7F>QW <00>wV<77><56>BDbUnit-1.2.3/PHPUnit/Extensions/Database/IDatabaseListConsumer.php5
<><7F>Q5
ꗧc<EA97A7>ADbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/QueryDataSet.phpc<><7F>Qc{<7B>.G<>DDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/MysqlXmlDataSet.php#<><7F>Q#<00>^N<><4E>?DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/QueryTable.php<68><><7F>Q<D7><00><><BE>G<D1>:DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ISpec.php}
<><7F>Q}
<00><><9A><ED><ED>HDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/TableMetaDataFilter.php<><7F>Q<00>kOͶGDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractXmlDataSet.php<68><><7F>Q<D7>]<5D>;DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ITable.php <><7F>Q }<1D>"<22>ADbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultTable.phpx<><7F>QxU<>9<97><39>MDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ReplacementTableIterator.php<68><><7F>Q<D7>V(ߠ<>GDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ReplacementDataSet.phpT<><7F>QT<00><><BB>ʶ=DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/IDataSet.php<68> <><7F>Q<D7> V<>?<3F>CDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultDataSet.php<68> <><7F>Q<D7> <19><><10>EDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ReplacementTable.php<><7F>Q%<25>BDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractTable.php<68><><7F>Q<D7>4R<34>O<E7>CDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ITableIterator.php<68>
<><7F>Q<D7>
<10><><15>?DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/CsvDataSet.php<68><><7F>Q<D7>c4]<5D>IDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultTableMetaData.php<68> <><7F>Q<D7> <00><>8`<60>?DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Yaml.php<68> <><7F>Q<D7> <00>"<22><><8A>>DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Xml.php<68> <><7F>Q<D7> H%z}<7D>CDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/IFactory.phpE
<><7F>QE
P<06><><BA>>DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Csv.phpU<><7F>QUh<>B<E7><42>BDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/DbTable.phpx<><7F>Qx><3E><>жBDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/DbQuery.php<68><><7F>Q<D7>4<1F>BDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/FlatXml.php<68> <><7F>Q<D7> h<00>*<2A>BDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Specs/Factory.php<68> <><7F>Q<D7> P<>ٻ<FA>IDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DefaultTableIterator.php<68><><7F>Q<D7><00>< <0A>BDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/DataSetFilter.php
<><7F>Q
<00><><95>7<B8>CDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/ITableMetaData.php, <><7F>Q, <00>n<CE><6E><F9>DDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractDataSet.php<68><><7F>Q<D7><00><17>K<D9>?DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/XmlDataSet.php<68><><7F>Q<D7><00>l <20><>DDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Yaml.php<68><><7F>Q<D7>r񤹶CDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Xml.php
<><7F>Q
_<06><><F0>HDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/MysqlXml.php<68><><7F>Q<D7>V<>?I<>HDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Abstract.php<68><><7F>Q<D7>;ӎ@<40>GDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/FlatXml.php^<><7F>Q^m <09><><D7>GDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/Persistors/Factory.php<68> <><7F>Q<D7> k<>V@<40>ADbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/IPersistable.php<68>
<><7F>Q<D7>
R<><52>ζCDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/FlatXmlDataSet.phpJ<><7F>QJ<00><> ζEDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/CompositeDataSet.php;<><7F>Q;|Q<><51><F1>@DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/YamlDataSet.php<68><><7F>Q<D7><00>c<FA><02>JDbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/AbstractTableMetaData.php<68><><7F>Q<D7><00>'nn<6E>@DbUnit-1.2.3/PHPUnit/Extensions/Database/DataSet/TableFilter.php<68><><7F>Q<D7>P<04>'<27>;DbUnit-1.2.3/PHPUnit/Extensions/Database/AbstractTester.php<><7F>Q U<><55><DF>:DbUnit-1.2.3/PHPUnit/Extensions/Database/DefaultTester.php<68> <><7F>Q<D7> <00>B<><42>4DbUnit-1.2.3/PHPUnit/Extensions/Database/ITester.php<68><><7F>Q<D7>ݿ$<24><>DbUnit-1.2.3/ChangeLog.markdown <><7F>Q /<2F>]W<>DbUnit-1.2.3/dbunit.phpu<><7F>Qudizt<7A>=DbUnit-1.2.3/Samples/BankAccountDB/BankAccountDBTestMySQL.php<68><><7F>Q<D7>s<>LDbUnit-1.2.3/Samples/BankAccountDB/_files/bank-account-after-new-account.xmlQ<><7F>QQ<00><>)<29><>IDbUnit-1.2.3/Samples/BankAccountDB/_files/bank-account-after-deposits.xml<><7F>QCP$ƶLDbUnit-1.2.3/Samples/BankAccountDB/_files/bank-account-after-withdrawals.xml
<><7F>Q
':ݶ?DbUnit-1.2.3/Samples/BankAccountDB/_files/bank-account-seed.xml <><7F>Q <00><VG<56>2DbUnit-1.2.3/Samples/BankAccountDB/BankAccount.phpu<><7F>Qu<1C><><E8><C4>8DbUnit-1.2.3/Samples/BankAccountDB/BankAccountDBTest.php<68><><7F>Q<D7><00><10>3<8F>PHP_Timer-1.0.4/PHP/Timer.php<68><><7F>Q<D7><00>%<25>ζPHP_Timer-1.0.4/LICENSE<><7F>Q`A<>*<2A>"PHP_Timer-1.0.4/ChangeLog.markdown<77><><7F>Q<D7>&<26>}<16>PHP_Timer-1.0.4/README.markdown!<><7F>Q!px i<>*Yaml-2.2.0/Symfony/Component/Yaml/Yaml.php<68><><7F>Q<D7>ͷ6<1F>6Yaml-2.2.0/Symfony/Component/Yaml/Tests/DumperTest.php<68><><7F>Q<D7><00>uE/<2F>6Yaml-2.2.0/Symfony/Component/Yaml/Tests/InlineTest.phpr%<><7F>Qr%<00><>L9<4C>6Yaml-2.2.0/Symfony/Component/Yaml/Tests/ParserTest.php<68>#<><7F>Q<D7>#D<><44><97>4Yaml-2.2.0/Symfony/Component/Yaml/Tests/YamlTest.phpX<><7F>QX<00>% <09>>Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml<><7F>Q<00><öGYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml<6D><><7F>Q<D7><00>>;<3B><><Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml<6D><><7F>Q<D7>U<11><1E>>Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.ymlU <><7F>QU <03><0F><>BYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.ymlq<><7F>Qqt<><74>r<FC>FYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml<6D><><7F>Q<D7><00>*<2A>MYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml0<6C><><7F>Q0<51>,x`k<>BYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml<6D><><7F>Q<D7><00><>X<F5><58>GYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.ymlX<><7F>QXZ{k<><6B>?Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/embededPhp.yml<><7F>QZ<>ܶ?Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml<><7F>Q@<40><><D6><DB>EYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml<6D><><7F>Q<D7><00>T
<AF><B6>DYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml<6D><><7F>Q<D7><08><><8C><BC>CYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml[<><7F>Q[<00>5<E1>R<D2>?Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.ymlJ<><7F>QJ;:<3A>Q<9A>IYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml<6D><><7F>Q<D7>%MC<4D>=Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml<6D><><7F>Q<D7><00>:Yaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/index.yml8<><7F>Q8<00><><A3><01>EYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.ymlz<><7F>Qzګغ<DAAB>JYaml-2.2.0/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml-<><7F>Q-Ç<>/Yaml-2.2.0/Symfony/Component/Yaml/composer.json<6F><><7F>Q<D7><00><><E6>F<DF>,Yaml-2.2.0/Symfony/Component/Yaml/.gitignore#<><7F>Q#܁0<DC81><30>)Yaml-2.2.0/Symfony/Component/Yaml/LICENSE)<><7F>Q)Nm<4E>Q<F2>,Yaml-2.2.0/Symfony/Component/Yaml/Dumper.php<68> <><7F>Q<D7> <00>8<8D>n<B9>0Yaml-2.2.0/Symfony/Component/Yaml/autoloader.php<68><><7F>Q<D7><00>U2<55><32>2Yaml-2.2.0/Symfony/Component/Yaml/phpunit.xml.dist3<><7F>Q3<00>>[<5B>>Yaml-2.2.0/Symfony/Component/Yaml/Exception/ParseException.php9 <><7F>Q9 ^<5E>[<5B><>BYaml-2.2.0/Symfony/Component/Yaml/Exception/ExceptionInterface.php<68><><7F>Q<D7><00>+<2B>l<AD>@Yaml-2.2.0/Symfony/Component/Yaml/Exception/RuntimeException.php<68><><7F>Q<D7><00>|<7C>-<2D>=Yaml-2.2.0/Symfony/Component/Yaml/Exception/DumpException.php<68><><7F>Q<D7>ؙ՚<D899>,Yaml-2.2.0/Symfony/Component/Yaml/Parser.php<68>X<><7F>Q<D7>X<00>H<DE>?<3F>/Yaml-2.2.0/Symfony/Component/Yaml/Unescaper.php<68><><7F>Q<D7><00><><8A>n<C2>+Yaml-2.2.0/Symfony/Component/Yaml/README.mda<><7F>Qa<00><>#X<>,Yaml-2.2.0/Symfony/Component/Yaml/Inline.php<68>><><7F>Q<D7>><00>h<DF><68><E0>-Yaml-2.2.0/Symfony/Component/Yaml/Escaper.phpi <><7F>Qi <00><0E><05>.Yaml-2.2.0/Symfony/Component/Yaml/CHANGELOG.md<6D><><7F>Q<D7>X<>l<>!PHPUnit/Framework/TestFailure.php<68><><7F>Q<D7>y<>'PHPUnit/Framework/ComparatorFactory.phpI<><7F>QI<00><>Z\<5C>+PHPUnit/Framework/SkippedTestSuiteError.php:
<><7F>Q:
<00><>c<>PHPUnit/Framework/Assert.phpJe<><7F>QJe$<24><>z<97>PHPUnit/Framework/TestCase.php<68><70><><7F>Q<D7><51><00><>&PHPUnit/Framework/Assert/Functions.php <20><><7F>Q <20>ƭ<>8<EC>)PHPUnit/Framework/Assert/Functions.php.in<69><><7F>Q<D7>dx<64><78><98>)PHPUnit/Framework/IncompleteTestError.php9
<><7F>Q9
<06>do<64>!PHPUnit/Framework/OutputError.php
<><7F>Q
<00>C<8A>g<D0>PHPUnit/Framework/Exception.php<68> <><7F>Q<D7> <00>/`?<3F>PHPUnit/Framework/Warning.php5<><7F>Q5e<1E><>'PHPUnit/Framework/ComparisonFailure.php<68><><7F>Q<D7><00><>M<13>&PHPUnit/Framework/SkippedTestError.php/
<><7F>Q/
a<>,*<2A>3PHPUnit/Framework/Constraint/ObjectHasAttribute.phpL <><7F>QL <00>;<3B>2<81>*PHPUnit/Framework/Constraint/PCREMatch.phpJ<><7F>QJe<>m<6D>.PHPUnit/Framework/Constraint/ExceptionCode.phpy<><7F>Qy)V<><56>-PHPUnit/Framework/Constraint/IsInstanceOf.php<68><><7F>Q<D7>c<><63><A7><A8>)PHPUnit/Framework/Constraint/SameSize.php <><7F>Q !n+<2B><>(PHPUnit/Framework/Constraint/IsEqual.php<68><><7F>Q<D7><00>'PHPUnit/Framework/Constraint/IsNull.php <><7F>Q 8<><38>$<24>'PHPUnit/Framework/Constraint/IsJson.php<68><><7F>Q<D7>xVZP<5A>'PHPUnit/Framework/Constraint/IsTrue.php <><7F>Q ,+<2B>Ͷ,PHPUnit/Framework/Constraint/ArrayHasKey.php<68><><7F>Q<D7>'<27>,PHPUnit/Framework/Constraint/IsIdentical.phpI<><7F>QIݢ<><DDA2>*PHPUnit/Framework/Constraint/Exception.phpD<><7F>QD-xDɶ$PHPUnit/Framework/Constraint/And.php<68><><7F>Q<D7>Q<>8PHPUnit/Framework/Constraint/TraversableContainsOnly.phpI<><7F>QI<00><>L<A0><4C>)PHPUnit/Framework/Constraint/Callback.php{<><7F>Q{<00>Q<82>c<99>$PHPUnit/Framework/Constraint/Not.phpc<><7F>Qc`<60><>:<3A>2PHPUnit/Framework/Constraint/ClassHasAttribute.phpC<><7F>QC<00><><AD><A4><F4>APHPUnit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php<68><><7F>Q<D7>nY<6E><59>,PHPUnit/Framework/Constraint/GreaterThan.phpY <><7F>QY c׆<>+PHPUnit/Framework/Constraint/IsAnything.php <><7F>Q Z<><5A>M<B5>/PHPUnit/Framework/Constraint/StringContains.php<68><><7F>Q<D7><00><>dj<64>4PHPUnit/Framework/Constraint/TraversableContains.php<><7F>Q<00><><15><>)PHPUnit/Framework/Constraint/LessThan.phpP <><7F>QP ><3E><><94><96>.PHPUnit/Framework/Constraint/StringMatches.php;<><7F>Q;$<24>n:<3A>*PHPUnit/Framework/Constraint/Composite.php<><7F>QG$a|<7C>1PHPUnit/Framework/Constraint/ExceptionMessage.php[<><7F>Q[h<>9<A2>+PHPUnit/Framework/Constraint/FileExists.phpY<><7F>QY<43><C594>*PHPUnit/Framework/Constraint/Attribute.php<><7F>Q<0E> <20>#PHPUnit/Framework/Constraint/Or.php<><7F>Q<00><><90>+<2B>/PHPUnit/Framework/Constraint/StringEndsWith.phpg <><7F>Qg qR <0A><>8PHPUnit/Framework/Constraint/ClassHasStaticAttribute.php)<><7F>Q)<00><>i<>(PHPUnit/Framework/Constraint/IsFalse.php$ <><7F>Q$ c{<7B>R<F0>1PHPUnit/Framework/Constraint/StringStartsWith.phpV <><7F>QV u/<<3C><>,PHPUnit/Framework/Constraint/JsonMatches.php<><7F>Q<00><>$<24><>(PHPUnit/Framework/Constraint/IsEmpty.phpj<><7F>QjطE<D8B7><45>&PHPUnit/Framework/Constraint/Count.php<68><><7F>Q<D7><00><><EF>)<29>$PHPUnit/Framework/Constraint/Xor.phpy<><7F>Qy%(<28><>'PHPUnit/Framework/Constraint/IsType.php<68><><7F>Q<D7><00>Z-<2D><> PHPUnit/Framework/Constraint.php<68><><7F>Q<D7><E<>$PHPUnit/Framework/SyntheticError.phpA<><7F>QAfS<66>j<E5>$PHPUnit/Framework/SelfDescribing.php<
<><7F>Q<
<00>E<BE>n<F0>1PHPUnit/Framework/Process/TestCaseMethod.tpl.dist+<><7F>Q+<00>~r<><72>,PHPUnit/Framework/TestSuite/DataProvider.php<68>
<><7F>Q<D7>
<00>:<3A>ö PHPUnit/Framework/Comparator.php<68><><7F>Q<D7>) <0B>:<3A>PHPUnit/Framework/TestSuite.php^o<><7F>Q^oۃS<DB83><53>&PHPUnit/Framework/Comparator/Array.phpx<><7F>Qx<00><00><1C>'PHPUnit/Framework/Comparator/Scalar.php<><7F>Qj<>_<AB><5F>*PHPUnit/Framework/Comparator/Exception.php <><7F>Q 7<><18><>(PHPUnit/Framework/Comparator/Numeric.php<><7F>Q<00><> <0C><>'PHPUnit/Framework/Comparator/Double.php
<><7F>Q
$X<>u<AB>%PHPUnit/Framework/Comparator/Type.phpr<><7F>Qr<00><>'PHPUnit/Framework/Comparator/Object.php<68><><7F>Q<D7>5<7F><35><84>)PHPUnit/Framework/Comparator/Resource.php<68><><7F>Q<D7><00><>@<40><>,PHPUnit/Framework/Comparator/DOMDocument.php<68><><7F>Q<D7> 7<07><>1PHPUnit/Framework/Comparator/SplObjectStorage.php<68><><7F>Q<D7><00><><10><>+PHPUnit/Framework/Comparator/MockObject.php <><7F>Q e"<22><>#PHPUnit/Framework/Error/Warning.phpe
<><7F>Qe
O <09>Ķ"PHPUnit/Framework/Error/Notice.phpb
<><7F>Qb
c9<63>&PHPUnit/Framework/Error/Deprecated.phpx
<><7F>Qx
f<><66>ܶPHPUnit/Framework/Error.phpB <><7F>QB <00><>x`<60> PHPUnit/Framework/TestResult.php,_<><7F>Q,_Z<1C><><AE>$PHPUnit/Framework/IncompleteTest.php
<><7F>Q
,<2C>9<89>"PHPUnit/Framework/TestListener.phpR<><7F>QR}<7D><><1B>0PHPUnit/Framework/ExpectationFailedException.php<68> <><7F>Q<D7> L<>u!<21>*PHPUnit/Framework/AssertionFailedError.php<68>
<><7F>Q<D7>
k<>!<15>!PHPUnit/Framework/SkippedTest.php<68> <><7F>Q<D7> a<>rr<72>PHPUnit/Framework/Test.php<68>
<><7F>Q<D7>
`<60>1<D7>*PHPUnit/Runner/StandardTestSuiteLoader.php<68><><7F>Q<D7>Ka|<17>"PHPUnit/Runner/TestSuiteLoader.php<68>
<><7F>Q<D7>
<09>ܳ<BD>PHPUnit/Runner/Version.phpK<><7F>QK<00>f<0E>!PHPUnit/Runner/BaseTestRunner.php<><7F>Q<00>B<><42>'PHPUnit/Util/TestDox/NamePrettifier.php"<><7F>Q"fyY<79>+PHPUnit/Util/TestDox/ResultPrinter/HTML.php<68><><7F>Q<D7><00><><F7><00>+PHPUnit/Util/TestDox/ResultPrinter/Text.php<68> <><7F>Q<D7> <00>&PHPUnit/Util/TestDox/ResultPrinter.phps&<><7F>Qs&<00><><91>ǶPHPUnit/Util/Printer.phpH<><7F>QH<1D><1D><>PHPUnit/Util/Diff.php5!<><7F>Q5!<00><><FA>ɶPHPUnit/Util/PHP/Windows.php<68> <><7F>Q<D7> <00><>d<07>PHPUnit/Util/PHP/Default.phpX
<><7F>QX
v"PHPUnit/Util/TestSuiteIterator.phpi<><7F>Qi<><C48D>PHPUnit/Util/GlobalState.php<68>7<><7F>Q<D7>7<00>o<93><6F><A0>PHPUnit/Util/Fileloader.php<68><><7F>Q<D7><00><>{<7B><>)PHPUnit/Util/DeprecatedFeature/Logger.phpT<><7F>QT<00><><A1>b<C1>PHPUnit/Util/Filter.php<68><><7F>Q<D7><00></<2F><>PHPUnit/Util/ErrorHandler.php <><7F>Q <00>D<14>PHPUnit/Util/PHP.php<68>,<><7F>Q<D7>,~8<>6<C1>PHPUnit/Util/String.php<68><><7F>Q<D7><00><>|&<26>PHPUnit/Util/Log/TAP.php<68><><7F>Q<D7><00><>12<31>PHPUnit/Util/Log/JUnit.php#<<><7F>Q#<<00>Z!<21><>PHPUnit/Util/Log/JSON.php<68><><7F>Q<D7>ĚP<C49A><50>PHPUnit/Util/XML.php<68>u<><7F>Q<D7>uM-<2D> <20>PHPUnit/Util/Getopt.php<68><><7F>Q<D7>-u!j<>PHPUnit/Util/Filesystem.php<68> <><7F>Q<D7> G<02><><BC>PHPUnit/Util/Type.php<68>&<><7F>Q<D7>&<00>C<F8>ٶ&PHPUnit/Util/InvalidArgumentHelper.php <><7F>Q K<><4B><90><C6>PHPUnit/Util/Class.php<68>*<><7F>Q<D7>*<00><>_<EB><5F>"PHPUnit/Util/DeprecatedFeature.php<68> <><7F>Q<D7>  <0B><18>PHPUnit/Util/Configuration.php<68><><7F>Q<D7>W<K<><4B>PHPUnit/Util/Test.php<68>M<><7F>Q<D7>M<1E>%PHPUnit/Extensions/GroupTestSuite.php<68><><7F>Q<D7>'e<><65><E0>%PHPUnit/Extensions/TicketListener.php<68><><7F>Q<D7>`k<><6B><FA>#PHPUnit/Extensions/RepeatedTest.php<68><><7F>Q<D7>#PHPUnit/Extensions/PhptTestCase.phpj"<><7F>Qj"rOfȶ*PHPUnit/Extensions/PhptTestCase/Logger.php<68> <><7F>Q<D7> b<><62>ն$PHPUnit/Extensions/TestDecorator.phpk<><7F>QkJ<>},<2C>$PHPUnit/Extensions/PhptTestSuite.php <><7F>Q 7<>q<DC><71>PHPUnit/TextUI/Command.phpq<><7F>Qq<00><>\M<> PHPUnit/TextUI/ResultPrinter.php<68>E<><7F>Q<D7>Ee<><65>x<E5>PHPUnit/TextUI/TestRunner.php)<29><><7F>Q)<29><1E><1B>2PHP_Invoker-1.1.2/PHP/Invoker/TimeoutException.php<68> <><7F>Q<D7> <00><>!PHP_Invoker-1.1.2/PHP/Invoker.php.<><7F>Q.L<>"<22>PHP_Invoker-1.1.2/LICENSE <><7F>Q N<><4E>ܶ$PHP_Invoker-1.1.2/ChangeLog.markdown:<><7F>Q:<00>7\<15>!PHP_Invoker-1.1.2/README.markdowni<><7F>Qi<00>0t(<28>,PHP_CodeCoverage-1.2.12/PHP/CodeCoverage.php*Y<><7F>Q*Y0:*U<>GPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Util/InvalidArgumentHelper.phpW <><7F>QW <00>Y<93>)<29>:PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Driver/Xdebug.php<68> <><7F>Q<D7> <00>ei<08>1PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Util.php<68>'<><7F>Q<D7>'j<><6A><FD><BC>6PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Exception.php<68> <><7F>Q<D7>
u:<3A>3PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Driver.php<68>
<><7F>Q<D7>
n <0C><04>3PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Filter.php<68>'<><7F>Q<D7>'[<5B><><91><B5>4PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Version.php< <><7F>Q< <00><>Y<>8PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node.php*%<><7F>Q*%<00>B<92><42><A9>=PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node/File.phpR<><7F>QR\-<2D>ǶAPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node/Iterator.php<><7F>Qu<><75>BPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Node/Directory.php#0<><7F>Q#0<>3<81><33>APHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer.php<68>#<><7F>Q<D7>#^Q<><51>FPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/File.phpQT<><7F>QQT<00><>]PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist<73><><7F>Q<D7><0F><><AD>cPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/img/glyphicons-halflings.png<6E>1<><7F>Q<D7>1<00>V(F<>iPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/img/glyphicons-halflings-white.pngI"<><7F>QI"<00><><A4>C<80>ZPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.dist;<><7F>Q;rS<72>ZPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/directory.html.dist<73><><7F>Q<D7><00>p<C0>W<AC>\PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css<73><73><><7F>Q<D7><51><00><>ak<61>gPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap-responsive.min.css<73>@<><7F>Q<D7>@<00><><A2>T<F7>TPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/css/style.cssq<><7F>Qq
<B9>*<2A><>_PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist <><7F>Q -<2D>,<2C><>\PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.distX<><7F>QX%<16>J<8E>UPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist<><7F>Q<00>`<60><><D6>ZPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.jsl{<><7F>Ql{<00><><04><>VPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.jsH <><7F>QH <00><><8F>߶WPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/js/highcharts.js<6A><73><><7F>Q<D7><51>~K&<26>WPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.js<6A>i<><7F>Q<D7>i<00><>v<B4><76>ZPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist <><7F>Q <00><>H<>KPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Directory.php<68><><7F>Q<D7>[ <0B>J<BB>KPHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML/Renderer/Dashboard.php<68><><7F>Q<D7>/MKU<4B>8PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/HTML.php<><7F>Q<00><>z<E1><7A>7PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/PHP.php{ <><7F>Q{ <17>=<3D><>8PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Text.php6+<><7F>Q6+ 8<>R<90>:PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Clover.php<68>2<><7F>Q<D7>2)<29><>ֶ;PHP_CodeCoverage-1.2.12/PHP/CodeCoverage/Report/Factory.php2<><7F>Q2<00><>[<5B><>PHP_CodeCoverage-1.2.12/LICENSE<><7F>Q<00><>w!<21>%Text_Template-1.1.4/Text/Template.php<68><><7F>Q<D7>W<><57>y<96>Text_Template-1.1.4/LICENSE<><7F>Q<00><>&Text_Template-1.1.4/ChangeLog.markdown<77><><7F>Q<D7><00><><9C><F8><87>#Text_Template-1.1.4/README.markdownF<><7F>QF<00>Q<0F>*PHP_TokenStream-1.1.5/PHP/Token/Stream.php<68>=<><7F>Q<D7>=<00>w<><77>9PHP_TokenStream-1.1.5/PHP/Token/Stream/CachingFactory.php <><7F>Q i<><69>{<7B>#PHP_TokenStream-1.1.5/PHP/Token.php<68>Y<><7F>Q<D7>YKx\a<>PHP_TokenStream-1.1.5/LICENSE<><7F>Q$īO<C4AB>(PHP_TokenStream-1.1.5/ChangeLog.markdown<77><><7F>Q<D7><00><35>%PHP_TokenStream-1.1.5/README.markdowne<><7F>QeX<>sF<73>File_Iterator
Copyright (c) 2009-2012, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
File_Iterator 1.3
=================
This is the list of changes for the File_Iterator 1.3 release series.
File_Iterator 1.3.3
-------------------
* No changes.
File_Iterator 1.3.2
-------------------
* No changes.
File_Iterator 1.3.1
-------------------
* Fixed infinite loop in `File_Iterator_Facade::getCommonPath()` for empty directories.
File_Iterator 1.3.0
-------------------
* Added `File_Iterator_Facade` for the most common use case.
* Moved `File_Iterator_Factory::getFilesAsArray()` to `File_Iterator_Facade::getFilesAsArray()`.
* `File_Iterator_Factory` is no longer static.
File_Iterator
=============
Installation
------------
File_Iterator should be installed using the [PEAR Installer](http://pear.php.net/). This installer is the backbone of PEAR, which provides a distribution system for PHP packages, and is shipped with every release of PHP since version 4.3.0.
The PEAR channel (`pear.phpunit.de`) that is used to distribute File_Iterator needs to be registered with the local PEAR environment:
sb@ubuntu ~ % pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded
This has to be done only once. Now the PEAR Installer can be used to install packages from the PHPUnit channel:
sb@vmware ~ % pear install phpunit/File_Iterator
downloading File_Iterator-1.1.1.tgz ...
Starting to download File_Iterator-1.1.1.tgz (3,173 bytes)
....done: 3,173 bytes
install ok: channel://pear.phpunit.de/File_Iterator-1.1.1
After the installation you can find the File_Iterator source files inside your local PEAR directory; the path is usually `/usr/lib/php/File`.
<?php
/**
* php-file-iterator
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package File
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @since File available since Release 1.0.0
*/
/**
* FilterIterator implementation that filters files based on prefix(es) and/or
* suffix(es). Hidden files and files from hidden directories are also filtered.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.3
* @link http://github.com/sebastianbergmann/php-file-iterator/tree
* @since Class available since Release 1.0.0
*/
class File_Iterator extends FilterIterator
{
const PREFIX = 0;
const SUFFIX = 1;
/**
* @var array
*/
protected $suffixes = array();
/**
* @var array
*/
protected $prefixes = array();
/**
* @var array
*/
protected $exclude = array();
/**
* @var string
*/
protected $basepath;
/**
* @param Iterator $iterator
* @param array $suffixes
* @param array $prefixes
* @param array $exclude
* @param string $basepath
*/
public function __construct(Iterator $iterator, array $suffixes = array(), array $prefixes = array(), array $exclude = array(), $basepath = NULL)
{
$exclude = array_filter(array_map('realpath', $exclude));
if ($basepath !== NULL) {
$basepath = realpath($basepath);
}
if ($basepath === FALSE) {
$basepath = NULL;
} else {
foreach ($exclude as &$_exclude) {
$_exclude = str_replace($basepath, '', $_exclude);
}
}
$this->prefixes = $prefixes;
$this->suffixes = $suffixes;
$this->exclude = $exclude;
$this->basepath = $basepath;
parent::__construct($iterator);
}
/**
* @return boolean
*/
public function accept()
{
$current = $this->getInnerIterator()->current();
$filename = $current->getFilename();
$realpath = $current->getRealPath();
if ($this->basepath !== NULL) {
$realpath = str_replace($this->basepath, '', $realpath);
}
// Filter files in hidden directories.
if (preg_match('=/\.[^/]*/=', $realpath)) {
return FALSE;
}
return $this->acceptPath($realpath) &&
$this->acceptPrefix($filename) &&
$this->acceptSuffix($filename);
}
/**
* @param string $path
* @return boolean
* @since Method available since Release 1.1.0
*/
protected function acceptPath($path)
{
foreach ($this->exclude as $exclude) {
if (strpos($path, $exclude) === 0) {
return FALSE;
}
}
return TRUE;
}
/**
* @param string $filename
* @return boolean
* @since Method available since Release 1.1.0
*/
protected function acceptPrefix($filename)
{
return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
}
/**
* @param string $filename
* @return boolean
* @since Method available since Release 1.1.0
*/
protected function acceptSuffix($filename)
{
return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
}
/**
* @param string $filename
* @param array $subString
* @param integer $type
* @return boolean
* @since Method available since Release 1.1.0
*/
protected function acceptSubString($filename, array $subStrings, $type)
{
if (empty($subStrings)) {
return TRUE;
}
$matched = FALSE;
foreach ($subStrings as $string) {
if (($type == self::PREFIX && strpos($filename, $string) === 0) ||
($type == self::SUFFIX &&
substr($filename, -1 * strlen($string)) == $string)) {
$matched = TRUE;
break;
}
}
return $matched;
}
}
<?php
/**
* php-file-iterator
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package File
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @since File available since Release 1.3.0
*/
/**
* Façade implementation that uses File_Iterator_Factory to create a
* File_Iterator that operates on an AppendIterator that contains an
* RecursiveDirectoryIterator for each given path. The list of unique
* files is returned as an array.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.3
* @link http://github.com/sebastianbergmann/php-file-iterator/tree
* @since Class available since Release 1.3.0
*/
class File_Iterator_Facade
{
/**
* @param array|string $paths
* @param array|string $suffixes
* @param array|string $prefixes
* @param array $exclude
* @param boolean $commonPath
* @return array
*/
public function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = array(), $commonPath = FALSE)
{
if (is_string($paths)) {
$paths = array($paths);
}
$factory = new File_Iterator_Factory;
$iterator = $factory->getFileIterator(
$paths, $suffixes, $prefixes, $exclude
);
$files = array();
foreach ($iterator as $file) {
$file = $file->getRealPath();
if ($file) {
$files[] = $file;
}
}
foreach ($paths as $path) {
if (is_file($path)) {
$files[] = realpath($path);
}
}
$files = array_unique($files);
sort($files);
if ($commonPath) {
return array(
'commonPath' => $this->getCommonPath($files),
'files' => $files
);
} else {
return $files;
}
}
/**
* Returns the common path of a set of files.
*
* @param array $files
* @return string
*/
protected function getCommonPath(array $files)
{
$count = count($files);
if ($count == 0) {
return '';
}
if ($count == 1) {
return dirname($files[0]) . DIRECTORY_SEPARATOR;
}
$_files = array();
foreach ($files as $file) {
$_files[] = $_fileParts = explode(DIRECTORY_SEPARATOR, $file);
if (empty($_fileParts[0])) {
$_fileParts[0] = DIRECTORY_SEPARATOR;
}
}
$common = '';
$done = FALSE;
$j = 0;
$count--;
while (!$done) {
for ($i = 0; $i < $count; $i++) {
if ($_files[$i][$j] != $_files[$i+1][$j]) {
$done = TRUE;
break;
}
}
if (!$done) {
$common .= $_files[0][$j];
if ($j > 0) {
$common .= DIRECTORY_SEPARATOR;
}
}
$j++;
}
return DIRECTORY_SEPARATOR . $common;
}
}
<?php
/**
* php-file-iterator
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package File
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @since File available since Release 1.1.0
*/
/**
* Factory Method implementation that creates a File_Iterator that operates on
* an AppendIterator that contains an RecursiveDirectoryIterator for each given
* path.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.3
* @link http://github.com/sebastianbergmann/php-file-iterator/tree
* @since Class available since Release 1.1.0
*/
class File_Iterator_Factory
{
/**
* @param array|string $paths
* @param array|string $suffixes
* @param array|string $prefixes
* @param array $exclude
* @return AppendIterator
*/
public function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = array())
{
if (is_string($paths)) {
$paths = array($paths);
}
$_paths = array();
foreach ($paths as $path) {
if ($locals = glob($path, GLOB_ONLYDIR)) {
$_paths = array_merge($_paths, $locals);
} else {
$_paths[] = $path;
}
}
$paths = $_paths;
unset($_paths);
if (is_string($prefixes)) {
if ($prefixes != '') {
$prefixes = array($prefixes);
} else {
$prefixes = array();
}
}
if (is_string($suffixes)) {
if ($suffixes != '') {
$suffixes = array($suffixes);
} else {
$suffixes = array();
}
}
$iterator = new AppendIterator;
foreach ($paths as $path) {
if (is_dir($path)) {
$iterator->append(
new File_Iterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path)
),
$suffixes,
$prefixes,
$exclude,
$path
)
);
}
}
return $iterator;
}
}
PHPUnit_MockObject
Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Interface for classes which can be invoked.
*
* The invocation will be taken from a mock object and passed to an object
* of this class.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
{namespace}
class {class_name} extends \SOAPClient
{
public function __construct($wsdl, array $options)
{
parent::__construct('{wsdl}', $options);
}
{methods}}
public function __clone()
{
$this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
parent::__clone();
}
{modifier} function {reference}{method_name}({arguments_decl})
{
$arguments = array({arguments_call});
$count = func_num_args();
if ($count > {arguments_count}) {
$_arguments = func_get_args();
for ($i = {arguments_count}; $i < $count; $i++) {
$arguments[] = $_arguments[$i];
}
}
$result = $this->__phpunit_getInvocationMocker()->invoke(
new PHPUnit_Framework_MockObject_Invocation_Object(
'{class_name}', '{method_name}', $arguments, $this, {clone_arguments}
)
);
return $result;
}
public function {method_name}({arguments})
{
}
{modifier} static function {reference}{method_name}({arguments_decl})
{
$arguments = array({arguments_call});
$count = func_num_args();
if ($count > {arguments_count}) {
$_arguments = func_get_args();
for ($i = {arguments_count}; $i < $count; $i++) {
$arguments[] = $_arguments[$i];
}
}
$result = self::__phpunit_getStaticInvocationMocker()->invoke(
new PHPUnit_Framework_MockObject_Invocation_Static(
'{class_name}', '{method_name}', $arguments, {clone_arguments}
)
);
return $result;
}
{prologue}{class_declaration}
{
private static $__phpunit_staticInvocationMocker;
private $__phpunit_invocationMocker;
{clone}{mocked_methods}
public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
{
return $this->__phpunit_getInvocationMocker()->expects($matcher);
}
public static function staticExpects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
{
return self::__phpunit_getStaticInvocationMocker()->expects($matcher);
}
public function __phpunit_getInvocationMocker()
{
if ($this->__phpunit_invocationMocker === NULL) {
$this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;
}
return $this->__phpunit_invocationMocker;
}
public static function __phpunit_getStaticInvocationMocker()
{
if (self::$__phpunit_staticInvocationMocker === NULL) {
self::$__phpunit_staticInvocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;
}
return self::$__phpunit_staticInvocationMocker;
}
public function __phpunit_hasMatchers()
{
return self::__phpunit_getStaticInvocationMocker()->hasMatchers() ||
$this->__phpunit_getInvocationMocker()->hasMatchers();
}
public function __phpunit_verify()
{
self::__phpunit_getStaticInvocationMocker()->verify();
$this->__phpunit_getInvocationMocker()->verify();
}
public function __phpunit_cleanup()
{
self::$__phpunit_staticInvocationMocker = NULL;
$this->__phpunit_invocationMocker = NULL;
}
}{epilogue}
public function __clone()
{
$this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
}
class {class_name}
{
use {trait_name};
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Mock Object Code Generator
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.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,
'die' => TRUE,
'do' => TRUE,
'echo' => TRUE,
'else' => TRUE,
'elseif' => TRUE,
'empty' => TRUE,
'enddeclare' => TRUE,
'endfor' => TRUE,
'endforeach' => TRUE,
'endif' => TRUE,
'endswitch' => TRUE,
'endwhile' => TRUE,
'eval' => TRUE,
'exit' => TRUE,
'expects' => TRUE,
'extends' => TRUE,
'final' => TRUE,
'for' => TRUE,
'foreach' => TRUE,
'function' => TRUE,
'global' => TRUE,
'goto' => TRUE,
'if' => TRUE,
'implements' => TRUE,
'include' => TRUE,
'include_once' => TRUE,
'instanceof' => TRUE,
'interface' => TRUE,
'isset' => TRUE,
'list' => TRUE,
'namespace' => TRUE,
'new' => TRUE,
'or' => TRUE,
'print' => TRUE,
'private' => TRUE,
'protected' => TRUE,
'public' => TRUE,
'require' => TRUE,
'require_once' => TRUE,
'return' => TRUE,
'static' => TRUE,
'staticExpects' => TRUE,
'switch' => TRUE,
'throw' => TRUE,
'try' => TRUE,
'unset' => TRUE,
'use' => TRUE,
'var' => TRUE,
'while' => TRUE,
'xor' => TRUE
);
/**
* @var boolean
*/
protected static $soapLoaded = NULL;
/**
* 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
* @param boolean $cloneArguments
* @return object
* @throws InvalidArgumentException
* @since Method available since Release 1.0.0
*/
public static function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = 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 (NULL !== $methods) {
foreach ($methods as $method) {
if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', $method)) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Cannot stub or mock method with invalid name "%s"',
$method
)
);
}
}
if ($methods != array_unique($methods)) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Cannot stub or mock using a method list that contains duplicates: "%s"',
implode(', ', $methods)
)
);
}
}
if ($mockClassName != '' && class_exists($mockClassName, FALSE)) {
$reflect = new ReflectionClass($mockClassName);
if (!$reflect->implementsInterface("PHPUnit_Framework_MockObject_MockObject")) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Class "%s" already exists.',
$mockClassName
)
);
}
}
$mock = self::generate(
$originalClassName,
$methods,
$mockClassName,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
return self::getObject(
$mock['code'],
$mock['mockClassName'],
$originalClassName,
$callOriginalConstructor,
$callAutoload,
$arguments
);
}
/**
* @param string $code
* @param string $className
* @param string $originalClassName
* @param string $callOriginalConstructor
* @param string $callAutoload
* @param array $arguments
* @return object
*/
protected static function getObject($code, $className, $originalClassName = '', $callOriginalConstructor = FALSE, $callAutoload = FALSE, array $arguments = array())
{
if (!class_exists($className, FALSE)) {
eval($code);
}
if ($callOriginalConstructor &&
!interface_exists($originalClassName, $callAutoload)) {
if (count($arguments) == 0) {
$object = new $className;
} else {
$class = new ReflectionClass($className);
$object = $class->newInstanceArgs($arguments);
}
} else {
// Use a trick to create a new object of a class
// without invoking its constructor.
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)
);
}
return $object;
}
/**
* Returns a mock object for the specified abstract class with all abstract
* methods of the class mocked. Concrete methods to mock can be specified with
* the last parameter
*
* @param string $originalClassName
* @param array $arguments
* @param string $mockClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param array $mockedMethods
* @param boolean $cloneArguments
* @return object
* @since Method available since Release 1.0.0
* @throws InvalidArgumentException
*/
public static function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $mockedMethods = array(), $cloneArguments = 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) ||
interface_exists($originalClassName, $callAutoload)) {
$methods = array();
$reflector = new ReflectionClass($originalClassName);
foreach ($reflector->getMethods() as $method) {
if ($method->isAbstract() || in_array($method->getName(), $mockedMethods)) {
$methods[] = $method->getName();
}
}
if (empty($methods)) {
$methods = NULL;
}
return self::getMock(
$originalClassName,
$methods,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
} else {
throw new PHPUnit_Framework_Exception(
sprintf(
'Class "%s" does not exist.',
$originalClassName
)
);
}
}
/**
* Returns an object for the specified trait.
*
* @param string $traitName
* @param array $arguments
* @param string $traitClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @return object
* @since Method available since Release 1.1.0
* @throws InvalidArgumentException
*/
public static function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE)
{
if (!is_string($traitName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
if (!is_string($traitClassName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
}
if (!trait_exists($traitName, $callAutoload)) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Trait "%s" does not exist.',
$traitName
)
);
}
$className = self::generateClassName(
$traitName, $traitClassName, 'Trait_'
);
$templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
DIRECTORY_SEPARATOR;
$classTemplate = new Text_Template(
$templateDir . 'trait_class.tpl'
);
$classTemplate->setVar(
array(
'class_name' => $className['className'],
'trait_name' => $traitName
)
);
return self::getObject(
$classTemplate->render(),
$className['className']
);
}
/**
* @param string $originalClassName
* @param array $methods
* @param string $mockClassName
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @return array
*/
public static function generate($originalClassName, array $methods = NULL, $mockClassName = '', $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = TRUE)
{
if ($mockClassName == '') {
$key = md5(
$originalClassName .
serialize($methods) .
serialize($callOriginalClone) .
serialize($cloneArguments)
);
if (isset(self::$cache[$key])) {
return self::$cache[$key];
}
}
$mock = self::generateMock(
$originalClassName,
$methods,
$mockClassName,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
if (isset($key)) {
self::$cache[$key] = $mock;
}
return $mock;
}
/**
* @param string $wsdlFile
* @param string $originalClassName
* @param array $methods
* @param array $options
* @return array
*/
public static function generateClassFromWsdl($wsdlFile, $originalClassName, array $methods = array(), array $options = array())
{
if (self::$soapLoaded === NULL) {
self::$soapLoaded = extension_loaded('soap');
}
if (self::$soapLoaded) {
$client = new SOAPClient($wsdlFile, $options);
$_methods = array_unique($client->__getFunctions());
unset($client);
$templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR .
'Generator' . DIRECTORY_SEPARATOR;
$methodTemplate = new Text_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();
}
}
$optionsBuffer = 'array(';
foreach ($options as $key => $value) {
$optionsBuffer .= $key . ' => ' . $value;
}
$optionsBuffer .= ')';
$classTemplate = new Text_Template(
$templateDir . 'wsdl_class.tpl'
);
$namespace = '';
if(strpos($originalClassName, '\\') !== FALSE) {
$parts = explode('\\', $originalClassName);
$originalClassName = array_pop($parts);
$namespace = 'namespace ' . join('\\', $parts) . ';';
}
$classTemplate->setVar(
array(
'namespace' => $namespace,
'class_name' => $originalClassName,
'wsdl' => $wsdlFile,
'options' => $optionsBuffer,
'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|null $methods
* @param string $mockClassName
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @return array
*/
protected static function generateMock($originalClassName, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments = TRUE)
{
$templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
DIRECTORY_SEPARATOR;
$classTemplate = new Text_Template(
$templateDir . 'mocked_class.tpl'
);
$cloneTemplate = '';
$isClass = FALSE;
$isInterface = FALSE;
$mockClassName = self::generateClassName(
$originalClassName, $mockClassName, 'Mock_'
);
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['originalClassName'] . "\n{\n}\n\n";
if (!empty($mockClassName['namespaceName'])) {
$prologue = 'namespace ' . $mockClassName['namespaceName'] .
" {\n\n" . $prologue . "}\n\n" .
"namespace {\n\n";
$epilogue = "\n\n}";
}
$cloneTemplate = new Text_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 && !$isInterface) {
$cloneTemplate = new Text_Template(
$templateDir . 'unmocked_clone.tpl'
);
} else {
$cloneTemplate = new Text_Template(
$templateDir . 'mocked_clone.tpl'
);
}
}
} else {
$cloneTemplate = new Text_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();
}
$mockedMethods = '';
if (isset($class)) {
foreach ($methods as $methodName) {
try {
$method = $class->getMethod($methodName);
if (self::canMockMethod($method)) {
$mockedMethods .= self::generateMockedMethodDefinitionFromExisting(
$templateDir, $method, $cloneArguments
);
}
}
catch (ReflectionException $e) {
$mockedMethods .= self::generateMockedMethodDefinition(
$templateDir, $mockClassName['fullClassName'], $methodName, $cloneArguments
);
}
}
} else {
foreach ($methods as $methodName) {
$mockedMethods .= self::generateMockedMethodDefinition(
$templateDir, $mockClassName['fullClassName'], $methodName, $cloneArguments
);
}
}
$classTemplate->setVar(
array(
'prologue' => isset($prologue) ? $prologue : '',
'epilogue' => isset($epilogue) ? $epilogue : '',
'class_declaration' => self::generateMockClassDeclaration(
$mockClassName, $isInterface
),
'clone' => $cloneTemplate,
'mock_class_name' => $mockClassName['className'],
'mocked_methods' => $mockedMethods
)
);
return array(
'code' => $classTemplate->render(),
'mockClassName' => $mockClassName['className']
);
}
/**
* @param string $originalClassName
* @param string $className
* @param string $prefix
* @return array
*/
protected static function generateClassName($originalClassName, $className, $prefix)
{
if ($originalClassName[0] == '\\') {
$originalClassName = substr($originalClassName, 1);
}
$classNameParts = explode('\\', $originalClassName);
if (count($classNameParts) > 1) {
$originalClassName = array_pop($classNameParts);
$namespaceName = join('\\', $classNameParts);
$fullClassName = $namespaceName . '\\' . $originalClassName;
} else {
$namespaceName = '';
$fullClassName = $originalClassName;
}
if ($className == '') {
do {
$className = $prefix . $originalClassName . '_' .
substr(md5(microtime()), 0, 8);
}
while (class_exists($className, FALSE));
}
return array(
'className' => $className,
'originalClassName' => $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['className'],
!empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
$mockClassName['originalClassName']
);
} else {
$buffer .= sprintf(
"%s extends %s%s implements PHPUnit_Framework_MockObject_MockObject",
$mockClassName['className'],
!empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
$mockClassName['originalClassName']
);
}
return $buffer;
}
/**
* @param string $templateDir
* @param ReflectionMethod $method
* @param boolean $cloneArguments
* @return string
*/
protected static function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method, $cloneArguments = TRUE)
{
if ($method->isPrivate()) {
$modifier = 'private';
}
else if ($method->isProtected()) {
$modifier = 'protected';
}
else {
$modifier = 'public';
}
if ($method->isStatic()) {
$static = TRUE;
} else {
$static = FALSE;
}
if ($method->returnsReference()) {
$reference = '&';
} else {
$reference = '';
}
return self::generateMockedMethodDefinition(
$templateDir,
$method->getDeclaringClass()->getName(),
$method->getName(),
$cloneArguments,
$modifier,
PHPUnit_Util_Class::getMethodParameters($method),
PHPUnit_Util_Class::getMethodParameters($method, TRUE),
$reference,
$static
);
}
/**
* @param string $templateDir
* @param string $className
* @param string $methodName
* @param boolean $cloneArguments
* @param string $modifier
* @param string $arguments_decl
* @param string $arguments_call
* @param string $reference
* @param boolean $static
* @return string
*/
protected static function generateMockedMethodDefinition($templateDir, $className, $methodName, $cloneArguments = TRUE, $modifier = 'public', $arguments_decl = '', $arguments_call = '', $reference = '', $static = FALSE)
{
if ($static) {
$template = new Text_Template(
$templateDir . 'mocked_static_method.tpl'
);
} else {
$template = new Text_Template(
$templateDir . 'mocked_object_method.tpl'
);
}
$template->setVar(
array(
'arguments_decl' => $arguments_decl,
'arguments_call' => $arguments_call,
'arguments_count' => !empty($arguments_call) ? count(explode(',', $arguments_call)) : 0,
'class_name' => $className,
'method_name' => $methodName,
'modifier' => $modifier,
'reference' => $reference,
'clone_arguments' => $cloneArguments ? 'TRUE' : 'FALSE'
)
);
return $template->render();
}
/**
* @param ReflectionMethod $method
* @return boolean
*/
protected static function canMockMethod(ReflectionMethod $method)
{
if ($method->isConstructor() || $method->isFinal() ||
isset(self::$blacklistedMethodNames[$method->getName()])) {
return FALSE;
}
return TRUE;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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().
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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, '', TRUE);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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.'
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Invocation matcher which allos any parameters to a method.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Invocation matcher which checks if a method has been invoked zero or more
* times. This matcher will always match.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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().
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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) {
$parameter->evaluate(
$this->invocation->parameters[$i],
sprintf(
'Parameter %s for invocation %s does not match expected ' .
'value.',
$i,
$this->invocation->toString()
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Interface for classes which matches an invocation based on its
* method name, argument, order or call count.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Implementation of the Builder pattern for Mock objects.
*
* @package PHPUnit_MockObject
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
class PHPUnit_Framework_MockObject_MockBuilder
{
/**
* @var PHPUnit_Framework_TestCase
*/
protected $testCase;
/**
* @var string
*/
protected $className;
/**
* @var array
*/
protected $methods = array();
/**
* @var string
*/
protected $mockClassName = '';
/**
* @var array
*/
protected $constructorArgs = array();
/**
* @var boolean
*/
protected $originalConstructor = TRUE;
/**
* @var boolean
*/
protected $originalClone = TRUE;
/**
* @var boolean
*/
protected $autoload = TRUE;
/**
* @var boolean
*/
protected $cloneArguments = FALSE;
/**
* @param PHPUnit_Framework_TestCase
* @param string
*/
public function __construct(PHPUnit_Framework_TestCase $testCase, $className)
{
$this->testCase = $testCase;
$this->className = $className;
}
/**
* Creates a mock object using a fluent interface.
*
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getMock()
{
return $this->testCase->getMock(
$this->className,
$this->methods,
$this->constructorArgs,
$this->mockClassName,
$this->originalConstructor,
$this->originalClone,
$this->autoload,
$this->cloneArguments
);
}
/**
* Creates a mock object for an abstract class using a fluent interface.
*
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getMockForAbstractClass()
{
return $this->testCase->getMockForAbstractClass(
$this->className,
$this->constructorArgs,
$this->mockClassName,
$this->originalConstructor,
$this->originalClone,
$this->autoload,
$this->methods,
$this->cloneArguments
);
}
/**
* Specifies the subset of methods to mock. Default is to mock all of them.
*
* @param array|null $methods
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function setMethods($methods)
{
$this->methods = $methods;
return $this;
}
/**
* Specifies the arguments for the constructor.
*
* @param array $args
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function setConstructorArgs(array $args)
{
$this->constructorArgs = $args;
return $this;
}
/**
* Specifies the name for the mock class.
*
* @param string $name
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function setMockClassName($name)
{
$this->mockClassName = $name;
return $this;
}
/**
* Disables the invocation of the original constructor.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function disableOriginalConstructor()
{
$this->originalConstructor = FALSE;
return $this;
}
/**
* Enables the invocation of the original constructor.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 1.2.0
*/
public function enableOriginalConstructor()
{
$this->originalConstructor = TRUE;
return $this;
}
/**
* Disables the invocation of the original clone constructor.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function disableOriginalClone()
{
$this->originalClone = FALSE;
return $this;
}
/**
* Enables the invocation of the original clone constructor.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 1.2.0
*/
public function enableOriginalClone()
{
$this->originalClone = TRUE;
return $this;
}
/**
* Disables the use of class autoloading while creating the mock object.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function disableAutoload()
{
$this->autoload = FALSE;
return $this;
}
/**
* Enables the use of class autoloading while creating the mock object.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 1.2.0
*/
public function enableAutoload()
{
$this->autoload = TRUE;
return $this;
}
/**
* Disables the cloning of arguments passed to mocked methods.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 1.2.0
*/
public function disableArgumentCloning()
{
$this->cloneArguments = FALSE;
return $this;
}
/**
* Enables the cloning of arguments passed to mocked methods.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 1.2.0
*/
public function enableArgumentCloning()
{
$this->cloneArguments = TRUE;
return $this;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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->getMessage()
),
$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->getMessage()
),
$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 = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
}
$invocationIsAny = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount';
if (!$invocationIsAny) {
$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->getMessage()
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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;
}
/**
* @since Method available since Release 1.1.0
*/
public function hasMatchers()
{
if (empty($this->matchers)) {
return FALSE;
}
foreach ($this->matchers as $matcher) {
if (!$matcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount) {
return TRUE;
}
}
return FALSE;
}
/**
* @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();
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Represents a static invocation.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.0
*/
class PHPUnit_Framework_MockObject_Invocation_Static implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing
{
/**
* @var array
*/
protected static $uncloneableExtensions = array(
'mysqli' => TRUE,
'SQLite' => TRUE,
'sqlite3' => TRUE,
'tidy' => TRUE,
'xmlwriter' => TRUE,
'xsl' => TRUE
);
/**
* @var array
*/
protected static $uncloneableClasses = array(
'Closure',
'COMPersistHelper',
'IteratorIterator',
'RecursiveIteratorIterator',
'SplFileObject',
'PDORow',
'ZipArchive'
);
/**
* @var string
*/
public $className;
/**
* @var string
*/
public $methodName;
/**
* @var array
*/
public $parameters;
/**
* @param string $className
* @param string $methodname
* @param array $parameters
* @param boolean $cloneObjects
*/
public function __construct($className, $methodName, array $parameters, $cloneObjects = FALSE)
{
$this->className = $className;
$this->methodName = $methodName;
$this->parameters = $parameters;
if (!$cloneObjects) {
return;
}
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)
{
$cloneable = NULL;
$object = new ReflectionObject($original);
// Check the blacklist before asking PHP reflection to work around
// https://bugs.php.net/bug.php?id=53967
if ($object->isInternal() &&
isset(self::$uncloneableExtensions[$object->getExtensionName()])) {
$cloneable = FALSE;
}
if ($cloneable === NULL) {
foreach (self::$uncloneableClasses as $class) {
if ($original instanceof $class) {
$cloneable = FALSE;
break;
}
}
}
if ($cloneable === NULL && method_exists($object, 'isCloneable')) {
$cloneable = $object->isCloneable();
}
if ($cloneable === NULL && $object->hasMethod('__clone')) {
$method = $object->getMethod('__clone');
$cloneable = $method->isPublic();
}
if ($cloneable === NULL) {
$cloneable = TRUE;
}
if ($cloneable) {
try {
return clone $original;
}
catch (Exception $e) {
return $original;
}
} else {
return $original;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Represents a non-static invocation.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.0
*/
class PHPUnit_Framework_MockObject_Invocation_Object extends PHPUnit_Framework_MockObject_Invocation_Static
{
/**
* @var object
*/
public $object;
/**
* @param string $className
* @param string $methodname
* @param array $parameters
* @param object $object
* @param object $cloneObjects
*/
public function __construct($className, $methodName, array $parameters, $object, $cloneObjects = FALSE)
{
parent::__construct($className, $methodName, $parameters, $cloneObjects);
$this->object = $object;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Stubs a method by returning a user-defined value.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Stubs a method by returning a user-defined value.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Stubs a method by returning an argument that was passed to the mocked method.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @copyright 2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.1.0
*/
/**
* Stubs a method by returning the current object.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.1.0
*/
class PHPUnit_Framework_MockObject_Stub_ReturnSelf implements PHPUnit_Framework_MockObject_Stub
{
public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
{
if (!$invocation instanceof PHPUnit_Framework_MockObject_Invocation_Object) {
throw new PHPUnit_Framework_Exception(
'The current object can only be returned when mocking an ' .
'object, not a static class.'
);
}
return $invocation->object;
}
public function toString()
{
return 'return the current object';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Oliver Schlicht <o.schlicht@bitExpert.de>
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Stubs a method by raising a user-defined exception.
*
* @package PHPUnit_MockObject
* @author Oliver Schlicht <o.schlicht@bitExpert.de>
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.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)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Patrick Müller <elias0@gmx.net>
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Stubs a method by returning a user-defined stack of values.
*
* @package PHPUnit_MockObject
* @author Patrick Müller <elias0@gmx.net>
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
*
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.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';
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.1.0
*/
/**
* Stubs a method by returning a value from a map.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.1.0
*/
class PHPUnit_Framework_MockObject_Stub_ReturnValueMap implements PHPUnit_Framework_MockObject_Stub
{
protected $valueMap;
public function __construct(array $valueMap)
{
$this->valueMap = $valueMap;
}
public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
{
$parameterCount = count($invocation->parameters);
foreach ($this->valueMap as $map) {
if (!is_array($map) || $parameterCount != count($map) - 1) {
continue;
}
$return = array_pop($map);
if ($invocation->parameters === $map) {
return $return;
}
}
return NULL;
}
public function toString()
{
return 'return value from a map';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Interface for classes which must verify a given expectation.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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();
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Interface for invocations.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.0.0
*/
interface PHPUnit_Framework_MockObject_Invocation
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Builder interface for parameter matchers.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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:
* <code>
* // 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));
* </code>
*
* @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
*/
public function with();
/**
* Sets a matcher which allows any kind of parameters.
*
* Some examples:
* <code>
* // match any number of parameters
* $b->withAnyParamers();
* </code>
*
* @return PHPUnit_Framework_MockObject_Matcher_AnyParameters
*/
public function withAnyParameters();
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Builder interface for invocation order matches.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Interface for builders which can register builders with a given identification.
*
* This interface relates to PHPUnit_Framework_MockObject_Builder_Identity.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Builder interface for matcher of method names.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* 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().
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Builder interface for stubs which are actions replacing an invocation.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since File available since Release 1.0.0
*/
/**
* Interface for all mock objects which are generated by
* PHPUnit_Framework_MockObject_Mock.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 1.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);
/**
* Registers a new static 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 static function staticExpects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
/**
* @return PHPUnit_Framework_MockObject_InvocationMocker
*/
public function __phpunit_getInvocationMocker();
/**
* @return PHPUnit_Framework_MockObject_InvocationMocker
*/
public static function __phpunit_getStaticInvocationMocker();
/**
* 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();
}
PHPUnit_MockObject 1.2
======================
This is the list of changes for the PHPUnit_MockObject 1.2 release series.
PHPUnit_MockObject 1.2.3
------------------------
* Fixed a bug where getting two mocks with different argument cloning options returned the same mock.
PHPUnit_MockObject 1.2.2
------------------------
* Fixed #100: Removed the unique mock object ID introduced in version 1.2.
PHPUnit_MockObject 1.2.1
------------------------
* No changes.
PHPUnit_MockObject 1.2.0
------------------------
* Implemented #47: Make cloning of arguments passed to mocked methods optional.
* Implemented #84: `getMockFromWsdl()` now works with namespaces.
* Fixed #90: Mocks with a fixed class name could only be created once.
PHPUnit_Selenium
Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.2
*/
/**
* TestSuite class for Selenium 1 tests
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_SeleniumTestSuite extends PHPUnit_Framework_TestSuite
{
/**
* Overriding the default: Selenium suites are always built from a TestCase class.
* @var boolean
*/
protected $testCase = TRUE;
/**
* Making the method public.
*/
public function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
{
return parent::addTestMethod($class, $method);
}
/**
* @param string $className extending PHPUnit_Extensions_SeleniumTestCase
* @return PHPUnit_Extensions_SeleniumTestSuite
*/
public static function fromTestCaseClass($className)
{
$suite = new self();
$suite->setName($className);
$class = new ReflectionClass($className);
$classGroups = PHPUnit_Util_Test::getGroups($className);
$staticProperties = $class->getStaticProperties();
//BC: renamed seleneseDirectory -> selenesePath
if (!isset($staticProperties['selenesePath']) && isset($staticProperties['seleneseDirectory'])) {
$staticProperties['selenesePath'] = $staticProperties['seleneseDirectory'];
}
// Create tests from Selenese/HTML files.
if (isset($staticProperties['selenesePath']) &&
(is_dir($staticProperties['selenesePath']) || is_file($staticProperties['selenesePath']))) {
if (is_dir($staticProperties['selenesePath'])) {
$files = array_merge(
self::getSeleneseFiles($staticProperties['selenesePath'], '.htm'),
self::getSeleneseFiles($staticProperties['selenesePath'], '.html')
);
} else {
$files[] = realpath($staticProperties['selenesePath']);
}
// Create tests from Selenese/HTML files for multiple browsers.
if (!empty($staticProperties['browsers'])) {
foreach ($staticProperties['browsers'] as $browser) {
$browserSuite = PHPUnit_Extensions_SeleniumBrowserSuite::fromClassAndBrowser($className, $browser);
foreach ($files as $file) {
self::addGeneratedTestTo($browserSuite,
new $className($file, array(), '', $browser),
$classGroups
);
}
$suite->addTest($browserSuite);
}
}
else {
// Create tests from Selenese/HTML files for single browser.
foreach ($files as $file) {
self::addGeneratedTestTo($suite,
new $className($file),
$classGroups);
}
}
}
// Create tests from test methods for multiple browsers.
if (!empty($staticProperties['browsers'])) {
foreach ($staticProperties['browsers'] as $browser) {
$browserSuite = PHPUnit_Extensions_SeleniumBrowserSuite::fromClassAndBrowser($className, $browser);
foreach ($class->getMethods() as $method) {
$browserSuite->addTestMethod($class, $method);
}
$browserSuite->setupSpecificBrowser($browser);
$suite->addTest($browserSuite);
}
}
else {
// Create tests from test methods for single browser.
foreach ($class->getMethods() as $method) {
$suite->addTestMethod($class, $method);
}
}
return $suite;
}
private static function addGeneratedTestTo(PHPUnit_Framework_TestSuite $suite, PHPUnit_Framework_TestCase $test, $classGroups)
{
list ($methodName, ) = explode(' ', $test->getName());
$test->setDependencies(
PHPUnit_Util_Test::getDependencies(get_class($test), $methodName)
);
$suite->addTest($test, $classGroups);
}
/**
* @param string $directory
* @param string $suffix
* @return array
*/
private static function getSeleneseFiles($directory, $suffix)
{
$facade = new File_Iterator_Facade;
return $facade->getFilesAsArray($directory, $suffix);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* TestCase class that uses Selenium 2
* (WebDriver API and JsonWire protocol) to provide
* the functionality required for web testing.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
* @method void acceptAlert() Press OK on an alert, or confirms a dialog
* @method mixed alertText() alertText($value = NULL) Gets the alert dialog text, or sets the text for a prompt dialog
* @method void back()
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byClassName() byClassName($value)
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byCssSelector() byCssSelector($value)
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byId() byId($value)
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byLinkText() byLinkText($value)
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byName() byName($value)
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byTag() byTag($value)
* @method \PHPUnit_Extensions_Selenium2TestCase_Element byXPath() byXPath($value)
* @method void click() click(int $button = 0) Click any mouse button (at the coordinates set by the last moveto command).
* @method void clickOnElement() clickOnElement($id)
* @method string currentScreenshot() BLOB of the image file
* @method void dismissAlert() Press Cancel on an alert, or does not confirm a dialog
* @method \PHPUnit_Extensions_Selenium2TestCase_Element element() element(\PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) Retrieves an element
* @method array elements() elements(\PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) Retrieves an array of Element instances
* @method string execute() execute($javaScriptCode) Injects arbitrary JavaScript in the page and returns the last
* @method string executeAsync() executeAsync($javaScriptCode) Injects arbitrary JavaScript and wait for the callback (last element of arguments) to be called
* @method void forward()
* @method void frame() frame(mixed $element) Changes the focus to a frame in the page (by frameCount of type int, htmlId of type string, htmlName of type string or element of type \PHPUnit_Extensions_Selenium2TestCase_Element)
* @method void moveto() moveto(\PHPUnit_Extensions_Selenium2TestCase_Element $element) Move the mouse by an offset of the specificed element.
* @method void refresh()
* @method \PHPUnit_Extensions_Selenium2TestCase_Element_Select select() select($element)
* @method string source() Returns the HTML source of the page
* @method \PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts timeouts()
* @method string title()
* @method void|string url() url($url = NULL)
* @method PHPUnit_Extensions_Selenium2TestCase_ElementCriteria using() using($strategy) Factory Method for Criteria objects
* @method void window() window($name) Changes the focus to another window
* @method string windowHandle() Retrieves the current window handle
* @method string windowHandles() Retrieves a list of all available window handles
* @method string keys() Send a sequence of key strokes to the active element.
* @method void closeWindow() Close the current window.
*/
abstract class PHPUnit_Extensions_Selenium2TestCase extends PHPUnit_Framework_TestCase
{
const VERSION = '1.3.1';
/**
* @var string override to provide code coverage data from the server
*/
protected $coverageScriptUrl;
/**
* @var PHPUnit_Extensions_Selenium2TestCase_Session
*/
private $session;
/**
* @var array
*/
private $parameters;
/**
* @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
*/
protected static $sessionStrategy;
/**
* @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
*/
protected static $browserSessionStrategy;
/**
* @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
*/
protected $localSessionStrategy;
/**
* @var array
*/
private static $lastBrowserParams;
/**
* @var string
*/
private $testId;
/**
* @var boolean
*/
private $collectCodeCoverageInformation;
/**
* @var PHPUnit_Extensions_Selenium2TestCase_KeysHolder
*/
private $keysHolder;
/**
* @param boolean
*/
public static function shareSession($shareSession)
{
if (!is_bool($shareSession)) {
throw new InvalidArgumentException("The shared session support can only be switched on or off.");
}
if (!$shareSession) {
self::$sessionStrategy = self::defaultSessionStrategy();
} else {
self::$sessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared(self::defaultSessionStrategy());
}
}
private static function sessionStrategy()
{
if (!self::$sessionStrategy) {
self::$sessionStrategy = self::defaultSessionStrategy();
}
return self::$sessionStrategy;
}
private static function defaultSessionStrategy()
{
return new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated;
}
public function __construct($name = NULL, array $data = array(), $dataName = '')
{
parent::__construct($name, $data, $dataName);
$this->parameters = array(
'host' => 'localhost',
'port' => 4444,
'browser' => NULL,
'browserName' => NULL,
'desiredCapabilities' => array(),
'seleniumServerRequestsTimeout' => 60
);
$this->keysHolder = new PHPUnit_Extensions_Selenium2TestCase_KeysHolder();
}
public function setupSpecificBrowser($params)
{
$this->setUpSessionStrategy($params);
$params = array_merge($this->parameters, $params);
$this->setHost($params['host']);
$this->setPort($params['port']);
$this->setBrowser($params['browserName']);
$this->parameters['browser'] = $params['browser'];
$this->setDesiredCapabilities($params['desiredCapabilities']);
$this->setSeleniumServerRequestsTimeout(
$params['seleniumServerRequestsTimeout']);
}
protected function setUpSessionStrategy($params)
{
// This logic enables us to have a session strategy reused for each
// item in self::$browsers. We don't want them both to share one
// and we don't want each test for a specific browser to have a
// new strategy
if ($params == self::$lastBrowserParams) {
// do nothing so we use the same session strategy for this
// browser
} elseif (isset($params['sessionStrategy'])) {
$strat = $params['sessionStrategy'];
if ($strat != "isolated" && $strat != "shared") {
throw new InvalidArgumentException("Session strategy must be either 'isolated' or 'shared'");
} elseif ($strat == "isolated") {
self::$browserSessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated;
} else {
self::$browserSessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared(self::defaultSessionStrategy());
}
} else {
self::$browserSessionStrategy = self::defaultSessionStrategy();
}
self::$lastBrowserParams = $params;
$this->localSessionStrategy = self::$browserSessionStrategy;
}
private function getStrategy()
{
if ($this->localSessionStrategy)
return $this->localSessionStrategy;
else
return self::sessionStrategy();
}
public function prepareSession()
{
try {
if (!$this->session) {
$this->session = $this->getStrategy()->session($this->parameters);
}
} catch (PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException $e) {
$this->markTestSkipped("The Selenium Server is not active on host {$this->parameters['host']} at port {$this->parameters['port']}.");
}
return $this->session;
}
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
$this->testId = get_class($this) . '__' . $this->getName();
if ($result === NULL) {
$result = $this->createResult();
}
$this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
parent::run($result);
if ($this->collectCodeCoverageInformation) {
$coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
$this->coverageScriptUrl,
$this->testId
);
$result->getCodeCoverage()->append(
$coverage->get(), $this
);
}
// do not call this before to give the time to the Listeners to run
$this->getStrategy()->endOfTest($this->session);
return $result;
}
/**
* @throws RuntimeException
*/
protected function runTest()
{
$this->prepareSession();
$thrownException = NULL;
if ($this->collectCodeCoverageInformation) {
$this->session->cookie()->remove('PHPUNIT_SELENIUM_TEST_ID');
$this->session->cookie()->add('PHPUNIT_SELENIUM_TEST_ID', $this->testId)->set();
}
try {
$this->setUpPage();
$result = parent::runTest();
if (!empty($this->verificationErrors)) {
$this->fail(implode("\n", $this->verificationErrors));
}
} catch (Exception $e) {
$thrownException = $e;
}
if (NULL !== $thrownException) {
throw $thrownException;
}
return $result;
}
public static function suite($className)
{
return PHPUnit_Extensions_SeleniumTestSuite::fromTestCaseClass($className);
}
public function onNotSuccessfulTest(Exception $e)
{
$this->getStrategy()->notSuccessfulTest();
parent::onNotSuccessfulTest($e);
}
/**
* Delegate method calls to the Session.
*
* @param string $command
* @param array $arguments
* @return mixed
*/
public function __call($command, $arguments)
{
if ($this->session === NULL) {
throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is currently no active session to execute the '$command' command. You're probably trying to set some option in setUp() with an incorrect setter name. You may consider using setUpPage() instead.");
}
$result = call_user_func_array(
array($this->session, $command), $arguments
);
return $result;
}
/**
* @param string $host
* @throws InvalidArgumentException
*/
public function setHost($host)
{
if (!is_string($host)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$this->parameters['host'] = $host;
}
public function getHost()
{
return $this->parameters['host'];
}
/**
* @param integer $port
* @throws InvalidArgumentException
*/
public function setPort($port)
{
if (!is_int($port)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
$this->parameters['port'] = $port;
}
public function getPort()
{
return $this->parameters['port'];
}
/**
* @param string $browser
* @throws InvalidArgumentException
*/
public function setBrowser($browserName)
{
if (!is_string($browserName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$this->parameters['browserName'] = $browserName;
}
public function getBrowser()
{
return $this->parameters['browserName'];
}
/**
* @param string $browserUrl
* @throws InvalidArgumentException
*/
public function setBrowserUrl($browserUrl)
{
if (!is_string($browserUrl)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$this->parameters['browserUrl'] = new PHPUnit_Extensions_Selenium2TestCase_URL($browserUrl);
}
public function getBrowserUrl()
{
if (isset($this->parameters['browserUrl'])) {
return $this->parameters['browserUrl'];
}
return '';
}
/**
* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
*/
public function setDesiredCapabilities(array $capabilities)
{
$this->parameters['desiredCapabilities'] = $capabilities;
}
public function getDesiredCapabilities()
{
return $this->parameters['desiredCapabilities'];
}
/**
* @param int $timeout seconds
*/
public function setSeleniumServerRequestsTimeout($timeout)
{
$this->parameters['seleniumServerRequestsTimeout'] = $timeout;
}
public function getSeleniumServerRequestsTimeout()
{
return $this->parameters['seleniumServerRequestsTimeout'];
}
/**
* Get test id (generated internally)
* @return string
*/
public function getTestId()
{
return $this->testId;
}
/**
* Get Selenium2 current session id
* @return string
*/
public function getSessionId()
{
if ($this->session)
return $this->session->id();
return FALSE;
}
/**
* Wait until callback isn't null or timeout occurs
*
* @param $callback
* @param null $timeout
* @return mixed
*/
public function waitUntil($callback, $timeout = null)
{
$waitUntil = new PHPUnit_Extensions_Selenium2TestCase_WaitUntil($this);
return $waitUntil->run($callback, $timeout);
}
/**
* Sends a special key
* Deprecated due to issues with IE webdriver. Use keys() method instead
* @deprecated
* @param string $name
* @throws PHPUnit_Extensions_Selenium2TestCase_Exception
* @see PHPUnit_Extensions_Selenium2TestCase_KeysHolder
*/
public function keysSpecial($name)
{
$names = explode(',', $name);
foreach ($names as $key) {
$this->keys($this->keysHolder->specialKey(trim($key)));
}
}
/**
* setUp method that is called after the session has been prepared.
* It is possible to use session-specific commands like url() here.
*/
public function setUpPage()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Implementation of the Selenium RC client/server protocol.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 string
*/
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 $userCommands A numerical array which holds custom user commands.
*/
protected $userCommands = array();
/**
* @var array
*/
protected $verificationErrors = array();
/**
* @var array
*/
private $webDriverCapabilities;
public function __construct()
{
if (empty(self::$autoGeneratedCommands)) {
self::autoGenerateCommands();
}
}
/**
* Only browserName is supported.
*/
public function setWebDriverCapabilities(array $capabilities)
{
$this->webDriverCapabilities = $capabilities;
}
/**
* @return string
*/
public function start()
{
if ($this->browserUrl == NULL) {
throw new PHPUnit_Framework_Exception(
'setBrowserUrl() needs to be called before start().'
);
}
if ($this->webDriverCapabilities !== NULL) {
$seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($this->host, $this->port);
$driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl);
$session = $driver->startSession($this->webDriverCapabilities, new PHPUnit_Extensions_Selenium2TestCase_URL($this->browserUrl));
$webDriverSessionId = $session->id();
$this->sessionId = $this->getString(
'getNewBrowserSession',
array($this->browser, $this->browserUrl, '',
"webdriver.remote.sessionid=$webDriverSessionId")
);
$this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
}
if (!isset($this->sessionId)) {
$this->sessionId = $this->getString(
'getNewBrowserSession',
array($this->browser, $this->browserUrl)
);
$this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
}
return $this->sessionId;
}
/**
* @return string
* @since Method available since Release 1.1.0
*/
public function getSessionId()
{
return $this->sessionId;
}
/**
* @param string
* @since Method available since Release 1.2.0
*/
public function setSessionId($sessionId)
{
$this->sessionId = $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;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $browser
* @throws InvalidArgumentException
*/
public function setBrowser($browser)
{
if (!is_string($browser)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$this->browser = $browser;
}
/**
* @return string
*/
public function getBrowser()
{
return $this->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;
}
/**
* @return string
* @since Method available since Release 1.1.0
*/
public function getHost()
{
return $this->host;
}
/**
* @param integer $port
* @throws InvalidArgumentException
*/
public function setPort($port)
{
if (!is_int($port)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
$this->port = $port;
}
/**
* @return integer
* @since Method available since Release 1.1.0
*/
public function getPort()
{
return $this->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;
}
/**
* Adds allowed user commands into {@link self::$userCommands}. See
* {@link self::__call()} (switch/case -> default) for usage.
*
* @param string $command A command.
*
* @return $this
* @see self::__call()
*/
public function addUserCommand($command)
{
if (!is_string($command)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$this->userCommands[] = $command;
return $this;
}
/**
* 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(string $attributeLocator)
* @method array getAttributeFromAllWindows(string $attributeName)
* @method string getBodyText()
* @method string getConfirmation()
* @method string getCookie()
* @method string getCookieByName(string $name)
* @method integer getCssCount(string $locator)
* @method integer getCursorPosition(string $locator)
* @method integer getElementHeight(string $locator)
* @method integer getElementIndex(string $locator)
* @method integer getElementPositionLeft(string $locator)
* @method integer getElementPositionTop(string $locator)
* @method integer getElementWidth(string $locator)
* @method string getEval(string $script)
* @method string getExpression(string $expression)
* @method string getHtmlSource()
* @method string getLocation()
* @method string getLogMessages()
* @method integer getMouseSpeed()
* @method string getPrompt()
* @method array getSelectOptions(string $selectLocator)
* @method string getSelectedId(string $selectLocator)
* @method array getSelectedIds(string $selectLocator)
* @method string getSelectedIndex(string $selectLocator)
* @method array getSelectedIndexes(string $selectLocator)
* @method string getSelectedLabel(string $selectLocator)
* @method array getSelectedLabels(string $selectLocator)
* @method string getSelectedValue(string $selectLocator)
* @method array getSelectedValues(string $selectLocator)
* @method unknown getSpeed()
* @method unknown getSpeedAndWait()
* @method string getTable(string $tableCellAddress)
* @method string getText(string $locator)
* @method string getTitle()
* @method string getValue(string $locator)
* @method boolean getWhetherThisFrameMatchFrameExpression(string $currentFrameString, string $target)
* @method boolean getWhetherThisWindowMatchWindowExpression(string $currentWindowString, string $target)
* @method integer getXpathCount(string $xpath)
* @method unknown goBack()
* @method unknown goBackAndWait()
* @method unknown highlight(string $locator)
* @method unknown highlightAndWait(string $locator)
* @method unknown ignoreAttributesWithoutValue(string $ignore)
* @method unknown ignoreAttributesWithoutValueAndWait(string $ignore)
* @method boolean isAlertPresent()
* @method boolean isChecked(locator)
* @method boolean isConfirmationPresent()
* @method boolean isCookiePresent(string $name)
* @method boolean isEditable(string $locator)
* @method boolean isElementPresent(string $locator)
* @method boolean isOrdered(string $locator1, string $locator2)
* @method boolean isPromptPresent()
* @method boolean isSomethingSelected(string $selectLocator)
* @method boolean isTextPresent(pattern)
* @method boolean isVisible(locator)
* @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 waitForElementPresent()
* @method unknown waitForElementNotPresent()
* @method unknown waitForPageToLoad()
* @method unknown waitForPopUp()
* @method unknown windowFocus()
* @method unknown windowMaximize()
*/
public function __call($command, $arguments)
{
$arguments = $this->preprocessParameters($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 'captureScreenshot':
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': {
// 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 'getCssCount':
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 'captureEntirePageScreenshotToString':
case 'captureScreenshotToString':
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 'waitForElementPresent':
case 'waitForElementNotPresent':
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: {
if (!in_array($command, $this->userCommands)) {
throw new BadMethodCallException(
"Method $command not defined."
);
}
$this->doCommand($command, $arguments);
}
}
}
/**
* Send a command to the Selenium RC server.
*
* @param string $command
* @param array $arguments
* @param array $namedArguments
* @return string
* @author Seth Casana <totallymeat@gmail.org>
*/
protected function doCommand($command, array $arguments = array(), array $namedArguments = array())
{
$url = sprintf(
'http://%s:%s/selenium-server/driver/',
$this->host,
$this->port
);
$numArguments = count($arguments);
$postData = sprintf('cmd=%s', urlencode($command));
for ($i = 0; $i < $numArguments; $i++) {
$argNum = strval($i + 1);
if ($arguments[$i] == ' ') {
$postData .= sprintf('&%s=%s', $argNum, urlencode($arguments[$i]));
} else {
$postData .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i])));
}
}
foreach ($namedArguments as $key => $value) {
$postData .= sprintf('&%s=%s', $key, urlencode($value));
}
if (isset($this->sessionId)) {
$postData .= sprintf('&%s=%s', 'sessionId', $this->sessionId);
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded; charset=utf-8'
));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
$response = curl_exec($curl);
$info = curl_getinfo($curl);
if (!$response) {
throw new RuntimeException("CURL error while accessing the Selenium Server at '$url': " . curl_error($curl));
}
curl_close($curl);
if (!preg_match('/^OK/', $response)) {
throw new RuntimeException("Invalid response while accessing the Selenium Server at '$url': " . $response);
}
if ($info['http_code'] != 200) {
throw new RuntimeException(
'The response from the Selenium RC server is invalid: ' .
$response
);
}
return $response;
}
protected function preprocessParameters($params)
{
foreach ($params as $key => $param ) {
if (is_string($param) && (strlen($param) > 0)) {
$params[$key] = $this->getString('getExpression', array($param));
}
}
return $params;
}
/**
* 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 <ganchiku@gmail.com>
* @author Bjoern Schotte <schotte@mayflower.de>
*/
protected function getBoolean($command, array $arguments)
{
$result = $this->getString($command, $arguments);
switch ($result) {
case 'true': return TRUE;
case 'false': return FALSE;
default: {
throw new PHPUnit_Framework_Exception(
'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::export($result)
);
}
}
}
/**
* 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 <ganchiku@gmail.com>
* @author Bjoern Schotte <schotte@mayflower.de>
*/
protected function getNumber($command, array $arguments)
{
$result = $this->getString($command, $arguments);
if (!is_numeric($result)) {
throw new PHPUnit_Framework_Exception(
'Result is not numeric: ' . PHPUnit_Util_Type::export($result)
);
}
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 <ganchiku@gmail.com>
* @author Bjoern Schotte <schotte@mayflower.de>
*/
protected function getString($command, array $arguments)
{
try {
$result = $this->doCommand($command, $arguments);
}
catch (RuntimeException $e) {
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 <ganchiku@gmail.com>
* @author Bjoern Schotte <schotte@mayflower.de>
*/
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'];
$requiresTarget = $info['requiresTarget'];
$result = $this->__call($method, $arguments);
$message = "Failed command: " . $command . "('"
. (array_key_exists(0, $arguments) ? $arguments[0] . "'" : '')
. (array_key_exists(1, $arguments) ? ", '" . $arguments[1] . "'" : '')
. ")";
if ($info['isBoolean']) {
if (!isset($info['negative']) || !$info['negative']) {
PHPUnit_Framework_Assert::assertTrue($result, $message);
} else {
PHPUnit_Framework_Assert::assertFalse($result, $message);
}
} else {
if ($requiresTarget === TRUE) {
$expected = $arguments[1];
} else {
$expected = $arguments[0];
}
if (strpos($expected, 'exact:') === 0) {
$expected = substr($expected, strlen('exact:'));
if (!isset($info['negative']) || !$info['negative']) {
PHPUnit_Framework_Assert::assertEquals($expected, $result, $message);
} else {
PHPUnit_Framework_Assert::assertNotEquals($expected, $result, $message);
}
} else {
$caseInsensitive = FALSE;
if (strpos($expected, 'regexp:') === 0) {
$expected = substr($expected, strlen('regexp:'));
}
else if (strpos($expected, 'regexpi:') === 0) {
$expected = substr($expected, strlen('regexpi:'));
$caseInsensitive = TRUE;
}
else {
if (strpos($expected, 'glob:') === 0) {
$expected = substr($expected, strlen('glob:'));
}
$expected = '^' . str_replace(
array('*', '?'), array('.*', '.?'), $expected
) . '$';
}
$expected = '/' . str_replace('/', '\/', $expected) . '/';
if ($caseInsensitive) {
$expected .= 'i';
}
if (!isset($info['negative']) || !$info['negative']) {
PHPUnit_Framework_Assert::assertRegExp(
$expected, $result, $message
);
} else {
PHPUnit_Framework_Assert::assertNotRegExp(
$expected, $result, $message
);
}
}
}
}
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)
{
$lastExceptionMessage = '';
for ($second = 0; ; $second++) {
if ($second > $this->httpTimeout) {
PHPUnit_Framework_Assert::fail(
"WaitFor timeout. \n"
. "Last exception message: \n" . $lastExceptionMessage
);
}
try {
$this->assertCommand($command, $arguments, $info);
return;
}
catch (Exception $e) {
$lastExceptionMessage = $e->getMessage();
}
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 $methodKey => $method) {
if (preg_match('/^(get|is)([A-Z].+)$/', $method, $methodMatches)) {
$baseName = $methodMatches[2];
$isBoolean = $methodMatches[1] == 'is';
$requiresTarget = (strlen($matches[3][$methodKey]) > 0);
if (preg_match('/^(.*)Present$/', $baseName, $methodMatches)) {
$notBaseName = $methodMatches[1] . 'NotPresent';
} else {
$notBaseName = 'Not' . $baseName;
}
self::$autoGeneratedCommands['store' . $baseName] = array(
'functionHelper' => FALSE
);
self::$autoGeneratedCommands['assert' . $baseName] = array(
'originalMethod' => $method,
'isBoolean' => $isBoolean,
'functionHelper' => 'assertCommand',
'requiresTarget' => $requiresTarget
);
self::$autoGeneratedCommands['assert' . $notBaseName] = array(
'originalMethod' => $method,
'isBoolean' => $isBoolean,
'negative' => TRUE,
'functionHelper' => 'assertCommand',
'requiresTarget' => $requiresTarget
);
self::$autoGeneratedCommands['verify' . $baseName] = array(
'originalMethod' => $method,
'isBoolean' => $isBoolean,
'functionHelper' => 'verifyCommand',
'requiresTarget' => $requiresTarget
);
self::$autoGeneratedCommands['verify' . $notBaseName] = array(
'originalMethod' => $method,
'isBoolean' => $isBoolean,
'negative' => TRUE,
'functionHelper' => 'verifyCommand',
'requiresTarget' => $requiresTarget
);
self::$autoGeneratedCommands['waitFor' . $baseName] = array(
'originalMethod' => $method,
'isBoolean' => $isBoolean,
'functionHelper' => 'waitForCommand',
'requiresTarget' => $requiresTarget
);
self::$autoGeneratedCommands['waitFor' . $notBaseName] = array(
'originalMethod' => $method,
'isBoolean' => $isBoolean,
'negative' => TRUE,
'functionHelper' => 'waitForCommand',
'requiresTarget' => $requiresTarget
);
}
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* TestSuite class for a set of tests from a single Testcase Class
* executed with a particular browser.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_SeleniumBrowserSuite extends PHPUnit_Framework_TestSuite
{
/**
* Overriding the default: Selenium suites are always built from a TestCase class.
* @var boolean
*/
protected $testCase = TRUE;
public function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
{
return parent::addTestMethod($class, $method);
}
public static function fromClassAndBrowser($className, array $browser)
{
$browserSuite = new self();
if (isset($browser['browserName'])) {
$name = $browser['browserName'];
} else if (isset($browser['name'])) {
$name = $browser['name'];
} else {
$name = $browser['browser'];
}
$browserSuite->setName($className . ': ' . $name);
return $browserSuite;
}
public function setupSpecificBrowser(array $browser)
{
$this->browserOnAllTests($this, $browser);
}
private function browserOnAllTests(PHPUnit_Framework_TestSuite $suite, array $browser)
{
foreach ($suite->tests() as $test) {
if ($test instanceof PHPUnit_Framework_TestSuite) {
$this->browserOnAllTests($test, $browser);
} else {
$test->setupSpecificBrowser($browser);
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* TestCase class that uses Selenium to provide
* the functionality required for web testing.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*
* @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 assertAlert
* @method unknown assertAlertNotPresent
* @method unknown assertAlertPresent
* @method unknown assertAllButtons
* @method unknown assertAllFields
* @method unknown assertAllLinks
* @method unknown assertAllWindowIds
* @method unknown assertAllWindowNames
* @method unknown assertAllWindowTitles
* @method unknown assertAttribute
* @method unknown assertAttributeFromAllWindows
* @method unknown assertBodyText
* @method unknown assertChecked
* @method unknown assertConfirmation
* @method unknown assertConfirmationNotPresent
* @method unknown assertConfirmationPresent
* @method unknown assertCookie
* @method unknown assertCookieByName
* @method unknown assertCookieNotPresent
* @method unknown assertCookiePresent
* @method unknown assertCssCount
* @method unknown assertCursorPosition
* @method unknown assertEditable
* @method unknown assertElementHeight
* @method unknown assertElementIndex
* @method unknown assertElementNotPresent
* @method unknown assertElementPositionLeft
* @method unknown assertElementPositionTop
* @method unknown assertElementPresent
* @method unknown assertElementWidth
* @method unknown assertEval
* @method unknown assertExpression
* @method unknown assertHtmlSource
* @method unknown assertLocation
* @method unknown assertLogMessages
* @method unknown assertMouseSpeed
* @method unknown assertNotAlert
* @method unknown assertNotAllButtons
* @method unknown assertNotAllFields
* @method unknown assertNotAllLinks
* @method unknown assertNotAllWindowIds
* @method unknown assertNotAllWindowNames
* @method unknown assertNotAllWindowTitles
* @method unknown assertNotAttribute
* @method unknown assertNotAttributeFromAllWindows
* @method unknown assertNotBodyText
* @method unknown assertNotChecked
* @method unknown assertNotConfirmation
* @method unknown assertNotCookie
* @method unknown assertNotCookieByName
* @method unknown assertNotCssCount
* @method unknown assertNotCursorPosition
* @method unknown assertNotEditable
* @method unknown assertNotElementHeight
* @method unknown assertNotElementIndex
* @method unknown assertNotElementPositionLeft
* @method unknown assertNotElementPositionTop
* @method unknown assertNotElementWidth
* @method unknown assertNotEval
* @method unknown assertNotExpression
* @method unknown assertNotHtmlSource
* @method unknown assertNotLocation
* @method unknown assertNotLogMessages
* @method unknown assertNotMouseSpeed
* @method unknown assertNotOrdered
* @method unknown assertNotPrompt
* @method unknown assertNotSelectOptions
* @method unknown assertNotSelectedId
* @method unknown assertNotSelectedIds
* @method unknown assertNotSelectedIndex
* @method unknown assertNotSelectedIndexes
* @method unknown assertNotSelectedLabel
* @method unknown assertNotSelectedLabels
* @method unknown assertNotSelectedValue
* @method unknown assertNotSelectedValues
* @method unknown assertNotSomethingSelected
* @method unknown assertNotSpeed
* @method unknown assertNotSpeedAndWait
* @method unknown assertNotTable
* @method unknown assertNotText
* @method unknown assertNotTitle
* @method unknown assertNotValue
* @method unknown assertNotVisible
* @method unknown assertNotWhetherThisFrameMatchFrameExpression
* @method unknown assertNotWhetherThisWindowMatchWindowExpression
* @method unknown assertNotXpathCount
* @method unknown assertOrdered
* @method unknown assertPrompt
* @method unknown assertPromptNotPresent
* @method unknown assertPromptPresent
* @method unknown assertSelectOptions
* @method unknown assertSelectedId
* @method unknown assertSelectedIds
* @method unknown assertSelectedIndex
* @method unknown assertSelectedIndexes
* @method unknown assertSelectedLabel
* @method unknown assertSelectedLabels
* @method unknown assertSelectedValue
* @method unknown assertSelectedValues
* @method unknown assertSomethingSelected
* @method unknown assertSpeed
* @method unknown assertSpeedAndWait
* @method unknown assertTable
* @method unknown assertText
* @method unknown assertTextNotPresent
* @method unknown assertTextPresent
* @method unknown assertTitle
* @method unknown assertValue
* @method unknown assertVisible
* @method unknown assertWhetherThisFrameMatchFrameExpression
* @method unknown assertWhetherThisWindowMatchWindowExpression
* @method unknown assertXpathCount
* @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 waitForAlert
* @method unknown waitForAlertNotPresent
* @method unknown waitForAlertPresent
* @method unknown waitForAllButtons
* @method unknown waitForAllFields
* @method unknown waitForAllLinks
* @method unknown waitForAllWindowIds
* @method unknown waitForAllWindowNames
* @method unknown waitForAllWindowTitles
* @method unknown waitForAttribute
* @method unknown waitForAttributeFromAllWindows
* @method unknown waitForBodyText
* @method unknown waitForChecked
* @method unknown waitForCondition()
* @method unknown waitForConfirmation
* @method unknown waitForConfirmationNotPresent
* @method unknown waitForConfirmationPresent
* @method unknown waitForCookie
* @method unknown waitForCookieByName
* @method unknown waitForCookieNotPresent
* @method unknown waitForCookiePresent
* @method unknown waitForCssCount
* @method unknown waitForCursorPosition
* @method unknown waitForEditable
* @method unknown waitForElementHeight
* @method unknown waitForElementIndex
* @method unknown waitForElementNotPresent
* @method unknown waitForElementPositionLeft
* @method unknown waitForElementPositionTop
* @method unknown waitForElementPresent
* @method unknown waitForElementWidth
* @method unknown waitForEval
* @method unknown waitForExpression
* @method unknown waitForHtmlSource
* @method unknown waitForLocation
* @method unknown waitForLogMessages
* @method unknown waitForMouseSpeed
* @method unknown waitForNotAlert
* @method unknown waitForNotAllButtons
* @method unknown waitForNotAllFields
* @method unknown waitForNotAllLinks
* @method unknown waitForNotAllWindowIds
* @method unknown waitForNotAllWindowNames
* @method unknown waitForNotAllWindowTitles
* @method unknown waitForNotAttribute
* @method unknown waitForNotAttributeFromAllWindows
* @method unknown waitForNotBodyText
* @method unknown waitForNotChecked
* @method unknown waitForNotConfirmation
* @method unknown waitForNotCookie
* @method unknown waitForNotCookieByName
* @method unknown waitForNotCssCount
* @method unknown waitForNotCursorPosition
* @method unknown waitForNotEditable
* @method unknown waitForNotElementHeight
* @method unknown waitForNotElementIndex
* @method unknown waitForNotElementPositionLeft
* @method unknown waitForNotElementPositionTop
* @method unknown waitForNotElementWidth
* @method unknown waitForNotEval
* @method unknown waitForNotExpression
* @method unknown waitForNotHtmlSource
* @method unknown waitForNotLocation
* @method unknown waitForNotLogMessages
* @method unknown waitForNotMouseSpeed
* @method unknown waitForNotOrdered
* @method unknown waitForNotPrompt
* @method unknown waitForNotSelectOptions
* @method unknown waitForNotSelectedId
* @method unknown waitForNotSelectedIds
* @method unknown waitForNotSelectedIndex
* @method unknown waitForNotSelectedIndexes
* @method unknown waitForNotSelectedLabel
* @method unknown waitForNotSelectedLabels
* @method unknown waitForNotSelectedValue
* @method unknown waitForNotSelectedValues
* @method unknown waitForNotSomethingSelected
* @method unknown waitForNotSpeed
* @method unknown waitForNotSpeedAndWait
* @method unknown waitForNotTable
* @method unknown waitForNotText
* @method unknown waitForNotTitle
* @method unknown waitForNotValue
* @method unknown waitForNotVisible
* @method unknown waitForNotWhetherThisFrameMatchFrameExpression
* @method unknown waitForNotWhetherThisWindowMatchWindowExpression
* @method unknown waitForNotXpathCount
* @method unknown waitForOrdered
* @method unknown waitForPageToLoad()
* @method unknown waitForPopUp()
* @method unknown waitForPrompt
* @method unknown waitForPromptNotPresent
* @method unknown waitForPromptPresent
* @method unknown waitForSelectOptions
* @method unknown waitForSelectedId
* @method unknown waitForSelectedIds
* @method unknown waitForSelectedIndex
* @method unknown waitForSelectedIndexes
* @method unknown waitForSelectedLabel
* @method unknown waitForSelectedLabels
* @method unknown waitForSelectedValue
* @method unknown waitForSelectedValues
* @method unknown waitForSomethingSelected
* @method unknown waitForSpeed
* @method unknown waitForSpeedAndWait
* @method unknown waitForTable
* @method unknown waitForText
* @method unknown waitForTextNotPresent
* @method unknown waitForTextPresent
* @method unknown waitForTitle
* @method unknown waitForValue
* @method unknown waitForVisible
* @method unknown waitForWhetherThisFrameMatchFrameExpression
* @method unknown waitForWhetherThisWindowMatchWindowExpression
* @method unknown waitForXpathCount
* @method unknown windowFocus()
* @method unknown windowMaximize()
*/
abstract class PHPUnit_Extensions_SeleniumTestCase extends PHPUnit_Framework_TestCase
{
/**
* @var array
*/
public static $browsers = array();
/**
* @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 = '';
/**
* @var integer the number of seconds to wait before declaring
* the Selenium server not reachable
*/
protected $serverConnectionTimeOut = 10;
/**
* @var boolean
*/
private $serverRunning;
/**
* @var boolean
*/
private static $shareSession;
/**
* The last sessionId used for running a test.
* @var string
*/
private static $sessionId;
/**
* @param boolean
*/
public static function shareSession($shareSession)
{
self::$shareSession = $shareSession;
}
/**
* @param string $name
* @param array $data
* @param string $dataName
* @param array $browser
* @throws InvalidArgumentException
*/
public function __construct($name = NULL, array $data = array(), $dataName = '')
{
parent::__construct($name, $data, $dataName);
$this->testId = md5(uniqid(rand(), TRUE));
$this->getDriver(array());
}
public function setupSpecificBrowser(array $browser)
{
$this->getDriver($browser);
}
/**
* Stops any shared session still open at the end of the current
* PHPUnit process.
*/
public function __destruct()
{
$this->stopSession();
}
/**
* @param string $className
* @return PHPUnit_Framework_TestSuite
*/
public static function suite($className)
{
return PHPUnit_Extensions_SeleniumTestSuite::fromTestCaseClass($className);
}
/**
* 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
);
}
parent::run($result);
if ($this->collectCodeCoverageInformation) {
$result->getCodeCoverage()->append(
$this->getCodeCoverage(), $this
);
}
return $result;
}
/**
* @param array $browser
* @return PHPUnit_Extensions_SeleniumTestCase_Driver
*/
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[0] = $driver;
return $driver;
}
public function skipWithNoServerRunning()
{
try {
fsockopen($this->drivers[0]->getHost(), $this->drivers[0]->getPort(), $errno, $errstr, $this->serverConnectionTimeOut);
$this->serverRunning = TRUE;
} catch (PHPUnit_Framework_Error_Warning $e) {
$this->markTestSkipped(
sprintf(
'Could not connect to the Selenium Server on %s:%d.',
$this->drivers[0]->getHost(),
$this->drivers[0]->getPort()
)
);
$this->serverRunning = FALSE;
}
}
/**
* @return string
*/
protected function prepareTestSession()
{
$testCaseClassVars = get_class_vars(get_class($this));
if ($testCaseClassVars['browsers']) {
return $this->start();
}
if (self::$shareSession && self::$sessionId !== NULL) {
$this->setSessionId(self::$sessionId);
$this->selectWindow('null');
} else {
self::$sessionId = $this->start();
}
return self::$sessionId;
}
/**
* @throws RuntimeException
*/
protected function runTest()
{
$this->skipWithNoServerRunning();
$this->prepareTestSession();
if (!is_file($this->getName(FALSE))) {
$result = parent::runTest();
} else {
$this->runSelenese($this->getName(FALSE));
$result = NULL;
}
if (!empty($this->verificationErrors)) {
$this->fail(implode("\n", $this->verificationErrors));
}
if (!self::$shareSession) {
$this->stopSession();
}
return $result;
}
private function stopSession()
{
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;
}
/**
* 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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
protected function defaultAssertions($action)
{
}
/**
* @return array
*/
protected function getCodeCoverage()
{
$coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
$this->coverageScriptUrl,
$this->testId
);
return $coverage->get();
}
/**
* @param string $action
*/
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
*/
protected function onNotSuccessfulTest(Exception $e)
{
if (!$this->serverRunning) {
throw $e;
}
try {
$this->restoreSessionStateAfterFailedTest();
$buffer = '';
if ($this->captureScreenshotOnFailure) {
$buffer .= 'Current URL: ' . $this->drivers[0]->getLocation() .
"\n";
$screenshotInfo = $this->takeScreenshot();
if ($screenshotInfo != '') {
$buffer .= $screenshotInfo;
}
}
$this->stopSession();
} catch (Exception $another) {
$buffer = "Issues while capturing the screenshot:\n" . $another->getMessage();
}
if ($e instanceof PHPUnit_Framework_ExpectationFailedException
&& is_object($e->getComparisonFailure())) {
$message = $e->getComparisonFailure()->toString();
} else {
$message = $e->getMessage();
}
$buffer .= "\n" . $message;
// gain the screenshot path, lose the stack trace
if ($this->captureScreenshotOnFailure) {
throw new PHPUnit_Framework_Error($buffer, $e->getCode(), $e->getFile(), $e->getLine(), $e);
}
// yes to stack trace and everything
if ($e instanceof PHPUnit_Framework_IncompleteTestError
|| $e instanceof PHPUnit_Framework_SkippedTestError
|| $e instanceof PHPUnit_Framework_AssertionFailedError) {
throw $e;
}
// yes to stack trace, only for F tests
// PHPUnit issue 471 prevents getTrace() from being useful
throw new PHPUnit_Framework_Error($buffer, $e->getCode(), $e->getFile(), $e->getLine(), $e);
}
private function restoreSessionStateAfterFailedTest()
{
self::$sessionId = NULL;
}
/**
* Returns correct path to screenshot save path.
*
* @return string
*/
protected function getScreenshotPath()
{
$path = $this->screenshotPath;
if (!in_array(substr($path, strlen($path) -1, 1), array("/","\\"))) {
$path .= DIRECTORY_SEPARATOR;
}
return $path;
}
/**
* Take a screenshot and return information about it.
* Return an empty string if the screenshotPath and screenshotUrl
* properties are empty.
* Issue #88.
*
* @access protected
* @return string
*/
protected function takeScreenshot()
{
if (!empty($this->screenshotPath) &&
!empty($this->screenshotUrl)) {
$filename = $this->getScreenshotPath() . $this->testId . '.png';
$this->drivers[0]->captureEntirePageScreenshot($filename);
return 'Screenshot: ' . $this->screenshotUrl . '/' .
$this->testId . ".png\n";
} else {
return '';
}
}
/**
* Pause support for runSelenese() HTML cases
* @param $milliseconds
*/
protected function pause($milliseconds){
sleep(round($milliseconds/1000));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Retrieves the value of a CSS property.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
/**
* @param array $propertyName
*/
public function __construct($propertyName,
PHPUnit_Extensions_Selenium2TestCase_URL $cssResourceBaseUrl)
{
$this->jsonParameters = array();
$this->url = $cssResourceBaseUrl->descend($propertyName);
}
public function httpMethod()
{
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Class for implementing commands that just return a value
* (obtained with GET).
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Checks equality (same element on the page) with another DOM element.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
/**
* @param array $parameter
*/
public function __construct($parameter,
PHPUnit_Extensions_Selenium2TestCase_URL $equalsResourceBaseUrl)
{
$this->jsonParameters = array();
if (!($parameter instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) {
throw new InvalidArgumentException("Elements can only test equality with other Element instances.");
}
$this->url = $equalsResourceBaseUrl->descend($parameter->getId());
}
public function httpMethod()
{
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2012 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Class for implementing commands that just accomplishes an action (via POST).
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2012 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Get and set the element's value attribute.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value
extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys
{
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Retrieves an attribute of a DOM element.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
/**
* @param array $parameter
*/
public function __construct($parameter,
PHPUnit_Extensions_Selenium2TestCase_URL $attributeResourceBaseUrl)
{
$this->jsonParameters = array();
$this->url = $attributeResourceBaseUrl->descend($parameter);
}
public function httpMethod()
{
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Clicks ok on an alert popup.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.12
*/
/**
* Class-mapper, that converts requested special key into correspondent Unicode character
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.12
* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
*/
class PHPUnit_Extensions_Selenium2TestCase_KeysHolder
{
private $_keys = array(
'null' => "\xEE\x80\x80",
'cancel' => "\xEE\x80\x81",
'help' => "\xEE\x80\x82",
'backspace' => "\xEE\x80\x83",
'tab' => "\xEE\x80\x84",
'clear' => "\xEE\x80\x85",
'return' => "\xEE\x80\x86",
'enter' => "\xEE\x80\x87",
'shift' => "\xEE\x80\x88",
'control' => "\xEE\x80\x89",
'alt' => "\xEE\x80\x8A",
'pause' => "\xEE\x80\x8B",
'escape' => "\xEE\x80\x8C",
'space' => "\xEE\x80\x8D",
'pageup' => "\xEE\x80\x8E",
'pagedown' => "\xEE\x80\x8F",
'end' => "\xEE\x80\x90",
'home' => "\xEE\x80\x91",
'left' => "\xEE\x80\x92",
'up' => "\xEE\x80\x93",
'right' => "\xEE\x80\x94",
'down' => "\xEE\x80\x95",
'insert' => "\xEE\x80\x96",
'delete' => "\xEE\x80\x97",
'semicolon' => "\xEE\x80\x98",
'equals' => "\xEE\x80\x99",
'numpad0' => "\xEE\x80\x9A",
'numpad1' => "\xEE\x80\x9B",
'numpad2' => "\xEE\x80\x9C",
'numpad3' => "\xEE\x80\x9D",
'numpad4' => "\xEE\x80\x9E",
'numpad5' => "\xEE\x80\x9F",
'numpad6' => "\xEE\x80\xA0",
'numpad7' => "\xEE\x80\xA1",
'numpad8' => "\xEE\x80\xA2",
'numpad9' => "\xEE\x80\xA3",
'multiply' => "\xEE\x80\xA4",
'add' => "\xEE\x80\xA5",
'separator' => "\xEE\x80\xA6",
'subtract' => "\xEE\x80\xA7",
'decimal' => "\xEE\x80\xA8",
'divide' => "\xEE\x80\xA9",
'f1' => "\xEE\x80\xB1",
'f2' => "\xEE\x80\xB2",
'f3' => "\xEE\x80\xB3",
'f4' => "\xEE\x80\xB4",
'f5' => "\xEE\x80\xB5",
'f6' => "\xEE\x80\xB6",
'f7' => "\xEE\x80\xB7",
'f8' => "\xEE\x80\xB8",
'f9' => "\xEE\x80\xB9",
'f10' => "\xEE\x80\xBA",
'f11' => "\xEE\x80\xBB",
'f12' => "\xEE\x80\xBC",
'command' => "\xEE\x80\xBD",
);
public function specialKey($name)
{
$normalizedName = strtolower($name);
if (!isset($this->_keys[$normalizedName])) {
throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is no special key '$name' defined");
}
return $this->_keys[$normalizedName];
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
*/
/**
* Provides access to /element and /elements commands
*
* @package PHPUnit_Selenium
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
*/
abstract class PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
{
/**
* @param string $value e.g. 'container'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byClassName($value)
{
return $this->by('class name', $value);
}
/**
* @param string $value e.g. 'div.container'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byCssSelector($value)
{
return $this->by('css selector', $value);
}
/**
* @param string $value e.g. 'uniqueId'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byId($value)
{
return $this->by('id', $value);
}
/**
* @param string $value e.g. 'Link text'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byLinkText($value)
{
return $this->by('link text', $value);
}
/**
* @param string $value e.g. 'email_address'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byName($value)
{
return $this->by('name', $value);
}
/**
* @param string $value e.g. 'body'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byTag($value)
{
return $this->by('tag name', $value);
}
/**
* @param string $value e.g. '/div[@attribute="value"]'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byXPath($value)
{
return $this->by('xpath', $value);
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function element(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
{
$value = $this->postCommand('element', $criteria);
return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue(
$value, $this->getSessionUrl()->descend('element'), $this->driver);
}
/**
* @return array instances of PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function elements(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
{
$values = $this->postCommand('elements', $criteria);
$elements = array();
foreach ($values as $value) {
$elements[] =
PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue(
$value, $this->getSessionUrl()->descend('element'), $this->driver);
}
return $elements;
}
/**
* @param string $strategy
* @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria
*/
public function using($strategy)
{
return new PHPUnit_Extensions_Selenium2TestCase_ElementCriteria($strategy);
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
protected abstract function getSessionUrl();
/**
* @param string $strategy supported by JsonWireProtocol element/ command
* @param string $value
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
private function by($strategy, $value)
{
return $this->element($this->using($strategy)->value($value));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.2
*/
/**
* Object representing a <select> element.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.2
*/
class PHPUnit_Extensions_Selenium2TestCase_Element_Select
extends PHPUnit_Extensions_Selenium2TestCase_Element
{
/**
* @return PHPUnit_Extensions_Selenium2TestCase_Element_Select
*/
public static function fromElement(PHPUnit_Extensions_Selenium2TestCase_Element $element)
{
return new self($element->driver, $element->url);
}
/**
* @return string
*/
public function selectedLabel()
{
return $this->selectedOption()->text();
}
/**
* @return string
*/
public function selectedValue()
{
return $this->selectedOption()->value();
}
/**
* @return string
*/
public function selectedId()
{
return $this->selectedOption()->attribute('id');
}
/**
* @return array
*/
public function selectedLabels()
{
$labels = array();
foreach ($this->selectedOptions() as $option) {
$labels[] = $option->text();
}
return $labels;
}
/**
* @return array
*/
public function selectedValues()
{
$values = array();
foreach ($this->selectedOptions() as $option) {
$values[] = $option->value();
}
return $values;
}
/**
* @return array
*/
public function selectedIds()
{
$id = array();
foreach ($this->selectedOptions() as $option) {
$values[] = $option->attribute('id');
}
return $id;
}
/**
* @param string $label the text appearing in the option
* @return void
*/
public function selectOptionByLabel($label)
{
$toSelect = $this->using('xpath')->value(".//option[.='$label']");
$this->selectOptionByCriteria($toSelect);
}
/**
* @param string $value the value attribute of the option
* @return void
*/
public function selectOptionByValue($value)
{
$toSelect = $this->using('xpath')->value(".//option[@value='$value']");
$this->selectOptionByCriteria($toSelect);
}
/**
* @param PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $localCriteria condiotions for selecting an option
* @return void
*/
public function selectOptionByCriteria(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $localCriteria)
{
$option = $this->element($localCriteria);
if (!$option->selected()) {
$option->click();
}
}
/**
* @return array
*/
public function selectOptionValues()
{
$options = array();
foreach ($this->options() as $option) {
$options[] = $option->value();
}
return $options;
}
/**
* @return array
*/
public function selectOptionLabels()
{
$options = array();
foreach ($this->options() as $option) {
$options[] = $option->text();
}
return $options;
}
/***
* @return array
*/
private function selectedOptions()
{
$options = array();
foreach ($this->options() as $option) {
if ($option->selected()) {
$options[] = $option;
}
}
return $options;
}
public function clearSelectedOptions()
{
foreach ($this->selectedOptions() as $option) {
$option->click();
}
}
private function selectedOption()
{
foreach ($this->options() as $option) {
if ($option->selected()) {
return $option;
}
}
}
private function options()
{
$onlyTheOptions = $this->using('css selector')->value('option');
return $this->elements($onlyTheOptions);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Base class for implementing commands with special semantics.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
abstract class PHPUnit_Extensions_Selenium2TestCase_Command
{
protected $jsonParameters;
private $commandName;
/**
* @param array $jsonParameters null in case of no parameters
*/
public function __construct($jsonParameters,
PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
if (!is_array($jsonParameters) && $jsonParameters !== NULL) {
throw new InvalidArgumentException("The JSON parameters must be an array, or a NULL value in case they are not required.");
}
$this->jsonParameters = $jsonParameters;
$this->url = $url;
}
public function url()
{
return $this->url;
}
/**
* @return string
*/
abstract public function httpMethod();
/**
* @param array $jsonParameters null in case of no parameters
*/
public function jsonParameters()
{
return $this->jsonParameters;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Indicates an exception during the execution of Selenium 2 commands.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_Selenium2TestCase_Exception extends RuntimeException
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Driver for creating browser session with Selenium 2 (WebDriver API).
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_Driver
{
private $seleniumServerUrl;
private $seleniumServerRequestsTimeout;
public function __construct(PHPUnit_Extensions_Selenium2TestCase_URL $seleniumServerUrl, $timeout = 60)
{
$this->seleniumServerUrl = $seleniumServerUrl;
$this->seleniumServerRequestsTimeout = $timeout;
}
public function startSession(array $desiredCapabilities, PHPUnit_Extensions_Selenium2TestCase_URL $browserUrl)
{
$sessionCreation = $this->seleniumServerUrl->descend("/wd/hub/session");
$response = $this->curl('POST', $sessionCreation, array(
'desiredCapabilities' => $desiredCapabilities
));
$sessionPrefix = $response->getURL();
$timeouts = new PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts(
$this,
$sessionPrefix->descend('timeouts'),
$this->seleniumServerRequestsTimeout * 1000
);
return new PHPUnit_Extensions_Selenium2TestCase_Session(
$this,
$sessionPrefix,
$browserUrl,
$timeouts
);
}
/**
* Performs an HTTP request to the Selenium 2 server.
*
* @param string $method 'GET'|'POST'|'DELETE'|...
* @param string $url
* @param array $params JSON parameters for POST requests
*/
public function curl($http_method,
PHPUnit_Extensions_Selenium2TestCase_URL $url,
$params = NULL)
{
$curl = curl_init($url->getValue());
curl_setopt($curl, CURLOPT_TIMEOUT, $this->seleniumServerRequestsTimeout);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl,
CURLOPT_HTTPHEADER,
array(
'Content-type: application/json;charset=UTF-8',
'Accept: application/json;charset=UTF-8'
));
if ($http_method === 'POST') {
curl_setopt($curl, CURLOPT_POST, TRUE);
if ($params && is_array($params)) {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
} else {
curl_setopt($curl, CURLOPT_POSTFIELDS, '');
}
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
} else if ($http_method == 'DELETE') {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
}
$rawResponse = trim(curl_exec($curl));
if (curl_errno($curl)) {
throw new PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException(
'Error connection[' . curl_errno($curl) .'] to ' .
$url->getValue() . ': ' . curl_error($curl)
);
}
$info = curl_getinfo($curl);
if ($info['http_code'] == 0) {
throw new PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException();
}
if ($info['http_code'] == 404) {
throw new BadMethodCallException("The command $url is not recognized by the server.");
}
curl_close($curl);
$content = json_decode($rawResponse, TRUE);
if ($info['http_code'] == 500) {
if (isset($content['value']['message'])) {
$message = $content['value']['message'];
} else {
$message = "Internal server error while executing $http_method request at $url. Response: " . var_export($content, TRUE);
}
throw new PHPUnit_Extensions_Selenium2TestCase_WebDriverException($message, isset($content['status']) ? $content['status'] : 13);
}
return new PHPUnit_Extensions_Selenium2TestCase_Response($content, $info);
}
public function execute(PHPUnit_Extensions_Selenium2TestCase_Command $command)
{
return $this->curl($command->httpMethod(),
$command->url(),
$command->jsonParameters());
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.5
*/
/**
* Gets or sets an attribute of an object.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.5
*/
class PHPUnit_Extensions_Selenium2TestCase_StateCommand
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Object representing an HTTP response from the Selenium Server.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_Response
{
/**
* @var array decoded response
*/
private $jsonResponse;
/**
* @var array CURL info for the response.
*/
private $info;
public function __construct($jsonResponse, $info)
{
$this->jsonResponse = $jsonResponse;
$this->info = $info;
}
public function getValue()
{
if (isset($this->jsonResponse['value'])) {
return $this->jsonResponse['value'];
}
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public function getURL()
{
return new PHPUnit_Extensions_Selenium2TestCase_URL($this->info['url']);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.9
*/
/**
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.8
*/
class PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException
extends PHPUnit_Extensions_Selenium2TestCase_Exception
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Christian Becker <chris@beckr.org>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since
*/
/**
* Indicates an exception as a result of a non-sucessful WebDriver response status code.
*
* @package PHPUnit_Selenium
* @author Christian Becker <chris@beckr.org>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since
*/
class PHPUnit_Extensions_Selenium2TestCase_WebDriverException extends PHPUnit_Extensions_Selenium2TestCase_Exception
{
/* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes */
const Success = 0;
const NoSuchDriver = 6;
const NoSuchElement = 7;
const NoSuchFrame = 8;
const UnknownCommand = 9;
const StaleElementReference = 10;
const ElementNotVisible = 11;
const InvalidElementState = 12;
const UnknownError = 13;
const ElementIsNotSelectable = 15;
const JavaScriptError = 17;
const XPathLookupError = 19;
const Timeout = 21;
const NoSuchWindow = 23;
const InvalidCookieDomain = 24;
const UnableToSetCookie = 25;
const UnexpectedAlertOpen = 26;
const NoAlertOpenError = 27;
const ScriptTimeout = 28;
const InvalidElementCoordinates = 29;
const IMENotAvailable = 30;
const IMEEngineActivationFailed = 31;
const InvalidSelector = 32;
const SessionNotCreatedException = 33;
const MoveTargetOutOfBounds = 34;
}<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Browser session for Selenium 2: main point of entry for functionality.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
* @method void acceptAlert() Press OK on an alert, or confirms a dialog
* @method mixed alertText($value = NULL) Gets the alert dialog text, or sets the text for a prompt dialog
* @method void back()
* @method void dismissAlert() Press Cancel on an alert, or does not confirm a dialog
* @method void doubleclick() Double-clicks at the current mouse coordinates (set by moveto).
* @method string execute(array $javaScriptCode) Injects arbitrary JavaScript in the page and returns the last. See unit tests for usage
* @method string executeAsync(array $javaScriptCode) Injects arbitrary JavaScript and wait for the callback (last element of arguments) to be called. See unit tests for usage
* @method void forward()
* @method void frame(mixed $element) Changes the focus to a frame in the page (by frameCount of type int, htmlId of type string, htmlName of type string or element of type \PHPUnit_Extensions_Selenium2TestCase_Element)
* @method void moveto(\PHPUnit_Extensions_Selenium2TestCase_Element $element) Move the mouse by an offset of the specificed element.
* @method void refresh()
* @method string source() Returns the HTML source of the page
* @method string title()
* @method void|string url($url = NULL)
* @method void window($name) Changes the focus to another window
* @method string windowHandle() Retrieves the current window handle
* @method string windowHandles() Retrieves a list of all available window handles
* @method string keys() Send a sequence of key strokes to the active element.
*/
class PHPUnit_Extensions_Selenium2TestCase_Session
extends PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
{
/**
* @var string the base URL for this session,
* which all relative URLs will refer to
*/
private $baseUrl;
/**
* @var PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts
*/
private $timeouts;
/**
* @var boolean
*/
private $stopped = FALSE;
public function __construct($driver,
PHPUnit_Extensions_Selenium2TestCase_URL $url,
PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl,
PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts $timeouts)
{
$this->baseUrl = $baseUrl;
$this->timeouts = $timeouts;
parent::__construct($driver, $url);
}
/**
* @return string
*/
public function id()
{
return $this->url->lastSegment();
}
protected function initCommands()
{
$baseUrl = $this->baseUrl;
return array(
'acceptAlert' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert',
'alertText' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText',
'back' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'click' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click',
'buttondown' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'buttonup' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'dismissAlert' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert',
'doubleclick' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'execute' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'executeAsync' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'forward' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'frame' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame',
'keys' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys',
'moveto' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo',
'refresh' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'screenshot' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'source' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
'title' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
'url' => function ($jsonParameters, $commandUrl) use ($baseUrl) {
return new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url($jsonParameters, $commandUrl, $baseUrl);
},
'window' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window',
'windowHandle' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
'windowHandles' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
'touchDown' => $this->touchCommandFactoryMethod('touch/down'),
'touchUp' => $this->touchCommandFactoryMethod('touch/up'),
'touchMove' => $this->touchCommandFactoryMethod('touch/move'),
'touchScroll' => $this->touchCommandFactoryMethod('touch/scroll'),
'flick' => $this->touchCommandFactoryMethod('touch/flick'),
'location' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location',
'orientation' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation'
);
}
private function touchCommandFactoryMethod($urlSegment)
{
$url = $this->url->addCommand($urlSegment);
return function ($jsonParameters, $commandUrl) use ($url) {
return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $url);
};
}
public function __destruct()
{
$this->stop();
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public function getSessionUrl()
{
return $this->url;
}
/**
* Closed the browser.
* @return void
*/
public function stop()
{
if ($this->stopped) {
return;
}
try {
$this->driver->curl('DELETE', $this->url);
} catch (Exception $e) {
// sessions which aren't closed because of sharing can time out on the server. In no way trying to close them should make a test fail, as it already finished before arriving here.
"Closing sessions: " . $e->getMessage() . "\n";
}
$this->stopped = TRUE;
if ($this->stopped) {
return;
}
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_Element_Select
*/
public function select(PHPUnit_Extensions_Selenium2TestCase_Element $element)
{
$tag = $element->name();
if ($tag !== 'select') {
throw new InvalidArgumentException("The element is not a `select` tag but a `$tag`.");
}
return PHPUnit_Extensions_Selenium2TestCase_Element_Select::fromElement($element);
}
/**
* @param array WebElement JSON object
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function elementFromResponseValue($value)
{
return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue($value, $this->getSessionUrl()->descend('element'), $this->driver);
}
/**
* @param string $id id attribute, e.g. 'container'
* @return void
*/
public function clickOnElement($id)
{
return $this->element($this->using('id')->value($id))->click();
}
public function timeouts()
{
return $this->timeouts;
}
/**
* @return string a BLOB of a PNG file
*/
public function currentScreenshot()
{
return base64_decode($this->screenshot());
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_Window
*/
public function currentWindow()
{
$url = $this->url->descend('window')->descend(trim($this->windowHandle(), '{}'));
return new PHPUnit_Extensions_Selenium2TestCase_Window($this->driver, $url);
}
public function closeWindow()
{
$this->driver->curl('DELETE', $this->url->descend('window'));
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie
*/
public function cookie()
{
$url = $this->url->descend('cookie');
return new PHPUnit_Extensions_Selenium2TestCase_Session_Cookie($this->driver, $url);
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_Session_Storage
*/
public function localStorage()
{
$url = $this->url->addCommand('localStorage');
return new PHPUnit_Extensions_Selenium2TestCase_Session_Storage($this->driver, $url);
}
public function landscape()
{
$this->orientation('LANDSCAPE');
}
public function portrait()
{
$this->orientation('PORTRAIT');
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Produces a new Session object shared for each test.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated
implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
{
public function session(array $parameters)
{
$seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']);
$driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']);
$capabilities = array_merge($parameters['desiredCapabilities'],
array(
'browserName' => $parameters['browserName']
));
$session = $driver->startSession($capabilities, $parameters['browserUrl']);
return $session;
}
public function notSuccessfulTest()
{
}
public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL)
{
if ($session !== NULL) {
$session->stop();
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Keeps a Session object shared between test runs to save time.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared
implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
{
private $original;
private $session;
private $mainWindow;
private $lastTestWasNotSuccessful = FALSE;
public function __construct(PHPUnit_Extensions_Selenium2TestCase_SessionStrategy $originalStrategy)
{
$this->original = $originalStrategy;
}
public function session(array $parameters)
{
if ($this->lastTestWasNotSuccessful) {
if ($this->session !== NULL) {
$this->session->stop();
$this->session = NULL;
}
$this->lastTestWasNotSuccessful = FALSE;
}
if ($this->session === NULL) {
$this->session = $this->original->session($parameters);
$this->mainWindow = $this->session->windowHandle();
} else {
$this->session->window($this->mainWindow);
}
return $this->session;
}
public function notSuccessfulTest()
{
$this->lastTestWasNotSuccessful = TRUE;
}
public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL)
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.5
*/
/**
* Object representing a browser window.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.5
* @method array size(array $size = null) Window size as array('width' => $x, 'height' => $y)
* @method array position(array $position = null) Window position as array('x' => $x, 'y' => $y)
* @method array maximize() Maximize window
*/
class PHPUnit_Extensions_Selenium2TestCase_Window extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
{
/**
* @return array class names
*/
protected function initCommands()
{
return array(
'size' => 'PHPUnit_Extensions_Selenium2TestCase_StateCommand',
'position' => 'PHPUnit_Extensions_Selenium2TestCase_StateCommand',
'maximize' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* URL Value Object allowing easy concatenation.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
final class PHPUnit_Extensions_Selenium2TestCase_URL
{
/**
* @var string
*/
private $value;
/**
* @param string $value
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* @param string $host
* @param int port
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public static function fromHostAndPort($host, $port)
{
return new self("http://{$host}:{$port}");
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
public function __toString()
{
return $this->getValue();
}
/**
* @param string $addition
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public function descend($addition)
{
if ($addition == '') {
// if we're adding nothing, respect the current url's choice of
// whether or not to include a trailing slash; prevents inadvertent
// adding of slashes to urls that can't handle it
$newValue = $this->value;
} else {
$newValue = rtrim($this->value, '/')
. '/'
. ltrim($addition, '/');
}
return new self($newValue);
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public function ascend()
{
$lastSlash = strrpos($this->value, "/");
$newValue = substr($this->value, 0, $lastSlash);
return new self($newValue);
}
/**
* @return string
*/
public function lastSegment()
{
$segments = explode('/', $this->value);
return end($segments);
}
/**
* @param string $command
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public function addCommand($command)
{
return $this->descend($this->camelCaseToUnderScores($command));
}
/**
* @param string $newUrl
* @return PHPUnit_Extensions_Selenium2TestCase_URL
*/
public function jump($newUrl)
{
if ($this->isAbsolute($newUrl)) {
return new self($newUrl);
} else {
return $this->descend($newUrl);
}
}
private function camelCaseToUnderScores($string)
{
$string = preg_replace('/([A-Z]{1,1})/', ' \1', $string);
$string = strtolower($string);
return str_replace(' ', '_', $string);
}
private function isAbsolute($urlValue)
{
return preg_match('/^(http|https):\/\//', $urlValue) > 0;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.12
*/
/**
* Class to hold the special keys Unicode entities
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.3.0
* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
*/
class PHPUnit_Extensions_Selenium2TestCase_Keys
{
const NULL = "\xEE\x80\x80";
const CANCEL = "\xEE\x80\x81";
const HELP = "\xEE\x80\x82";
const BACKSPACE = "\xEE\x80\x83";
const TAB = "\xEE\x80\x84";
const CLEAR = "\xEE\x80\x85";
const RETURN_ = "\xEE\x80\x86";
const ENTER = "\xEE\x80\x87";
const SHIFT = "\xEE\x80\x88";
const CONTROL = "\xEE\x80\x89";
const ALT = "\xEE\x80\x8A";
const PAUSE = "\xEE\x80\x8B";
const ESCAPE = "\xEE\x80\x8C";
const SPACE = "\xEE\x80\x8D";
const PAGEUP = "\xEE\x80\x8E";
const PAGEDOWN = "\xEE\x80\x8F";
const END = "\xEE\x80\x90";
const HOME = "\xEE\x80\x91";
const LEFT = "\xEE\x80\x92";
const UP = "\xEE\x80\x93";
const RIGHT = "\xEE\x80\x94";
const DOWN = "\xEE\x80\x95";
const INSERT = "\xEE\x80\x96";
const DELETE = "\xEE\x80\x97";
const SEMICOLON = "\xEE\x80\x98";
const EQUALS = "\xEE\x80\x99";
const NUMPAD0 = "\xEE\x80\x9A";
const NUMPAD1 = "\xEE\x80\x9B";
const NUMPAD2 = "\xEE\x80\x9C";
const NUMPAD3 = "\xEE\x80\x9D";
const NUMPAD4 = "\xEE\x80\x9E";
const NUMPAD5 = "\xEE\x80\x9F";
const NUMPAD6 = "\xEE\x80\xA0";
const NUMPAD7 = "\xEE\x80\xA1";
const NUMPAD8 = "\xEE\x80\xA2";
const NUMPAD9 = "\xEE\x80\xA3";
const MULTIPLY = "\xEE\x80\xA4";
const ADD = "\xEE\x80\xA5";
const SEPARATOR = "\xEE\x80\xA6";
const SUBTRACT = "\xEE\x80\xA7";
const DECIMAL = "\xEE\x80\xA8";
const DIVIDE = "\xEE\x80\xA9";
const F1 = "\xEE\x80\xB1";
const F2 = "\xEE\x80\xB2";
const F3 = "\xEE\x80\xB3";
const F4 = "\xEE\x80\xB4";
const F5 = "\xEE\x80\xB5";
const F6 = "\xEE\x80\xB6";
const F7 = "\xEE\x80\xB7";
const F8 = "\xEE\x80\xB8";
const F9 = "\xEE\x80\xB9";
const F10 = "\xEE\x80\xBA";
const F11 = "\xEE\x80\xBB";
const F12 = "\xEE\x80\xBC";
const COMMAND = "\xEE\x80\xBD";
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Manage the local storage HTML 5 database.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_Selenium2TestCase_Session_Storage
{
private $driver;
private $url;
public function __construct(PHPUnit_Extensions_Selenium2TestCase_Driver $driver,
PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
$this->driver = $driver;
$this->url = $url;
}
public function __set($name, $value)
{
$this->driver->curl('POST', $this->url, array(
'key' => $name,
'value' => (string)$value
));
}
public function __get($name)
{
return $this->driver->curl(
'GET',
$this->url->descend('key')->descend($name)
)->getValue();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Adds and remove cookies.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_Selenium2TestCase_Session_Cookie
{
private $driver;
private $url;
public function __construct(PHPUnit_Extensions_Selenium2TestCase_Driver $driver,
PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
$this->driver = $driver;
$this->url = $url;
}
/**
* @param string $name
* @param string $value
* @return void
*/
public function add($name, $value)
{
return new PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder($this, $name, $value);
}
/**
* @param string $name
* @return string
*/
public function get($name)
{
$cookies = $this->driver->curl('GET', $this->url)->getValue();
foreach ($cookies as $cookie) {
if ($cookie['name'] == $name) {
return $cookie['value'];
}
}
throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is no '$name' cookie available on this page.");
}
/**
* @param string $name
* @return void
*/
public function remove($name)
{
$url = $this->url->descend($name);
$this->driver->curl('DELETE', $url);
}
/**
* @return void
*/
public function clear()
{
$this->driver->curl('DELETE', $this->url);
}
/**
* @internal
* @param array $data
* @return void
*/
public function postCookie(array $data)
{
$this->driver->curl('POST',
$this->url,
array(
'cookie' => $data
));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Adds a cookie.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
class PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
{
private $name;
private $value;
private $path;
private $domain;
private $secure = FALSE;
private $expiry;
public function __construct($cookieFacade, $name, $value)
{
$this->cookieFacade = $cookieFacade;
$this->name = $name;
$this->value = $value;
}
/**
* @param string
* @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
*/
public function path($path)
{
$this->path = $path;
return $this;
}
/**
* @param string
* @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
*/
public function domain($domain)
{
$this->domain = $domain;
return $this;
}
/**
* @param boolean
* @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
*/
public function secure($secure)
{
$this->secure = $secure;
return $this;
}
/**
* @param integer
* @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
*/
public function expiry($expiry)
{
$this->expiry = $expiry;
return $this;
}
/**
* @return void
*/
public function set()
{
$cookieData = array(
'name' => $this->name,
'value' => $this->value,
'secure' => $this->secure,
);
foreach (array('path', 'domain', 'expiry') as $parameter) {
if ($this->$parameter !== NULL) {
$cookieData[$parameter] = $this->$parameter;
}
}
$this->cookieFacade->postCookie($cookieData);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Manages timeouts for the current browser session.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
* @method implicitWait(int $ms) Sets timeout when searching for elements
* @method asyncScript(int $ms) Sets timeout for asynchronous scripts executed by Session::executeAsync()
*/
class PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts
extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
{
private $maximumTimeout;
private $lastImplicitWaitValue = 0;
public function __construct($driver,
PHPUnit_Extensions_Selenium2TestCase_URL $url,
$maximumTimeout)
{
parent::__construct($driver, $url);
$this->maximumTimeout = $maximumTimeout;
}
protected function initCommands()
{
$self = $this;
return array(
'implicitWait' => function ($milliseconds, $commandUrl) use ($self) {
$self->check($milliseconds);
$self->setLastImplicitWaitValue($milliseconds);
$jsonParameters = array('ms' => $milliseconds);
return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $commandUrl);
},
'asyncScript' => function ($milliseconds, $commandUrl) use ($self) {
$self->check($milliseconds);
$jsonParameters = array('ms' => $milliseconds);
return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $commandUrl);
},
);
}
public function setLastImplicitWaitValue($implicitWait)
{
$this->lastImplicitWaitValue = $implicitWait;
}
public function getLastImplicitWaitValue()
{
return $this->lastImplicitWaitValue;
}
public function check($timeout) {
if ($timeout > $this->maximumTimeout) {
throw new PHPUnit_Extensions_Selenium2TestCase_Exception('There is no use in setting this timeout unless you also call $this->setSeleniumServerRequestsTimeout($seconds) in setUp().');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.6
*/
/**
* Specifies how to create Session objects for running tests.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.6
*/
interface PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
{
/**
* @param array $parameters 'host' => Selenium Server machine
'port' => Selenium Server port
'browser' => a browser name
* 'browserUrl' => base URL to use during the test
*/
public function session(array $parameters);
public function notSuccessfulTest();
public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Conditions for selecting a DOM element.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element
*/
class PHPUnit_Extensions_Selenium2TestCase_ElementCriteria extends ArrayObject
{
public function __construct($strategy)
{
$this['using'] = $strategy;
}
/**
* @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria
*/
public function value($searchTarget)
{
$this['value'] = $searchTarget;
return $this;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Jonathan Lipps <jlipps@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Gets or posts an attribute from/to the session (title, alert text, etc.)
*
* @package PHPUnit_Selenium
* @author Jonathan Lipps <jlipps@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.9
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location
extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
{
public function __construct($location, $commandUrl) {
if ($location !== NULL) {
$jsonParameters = array('location' => $location);
} else {
$jsonParameters = NULL;
}
parent::__construct($jsonParameters, $commandUrl);
}
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Clicks Cancel on an alert popup.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Changes the focus to a frame.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($id, $commandUrl)
{
$jsonParameters = array(
'id' => $this->extractId($id)
);
parent::__construct($jsonParameters, $commandUrl);
}
/**
* @param $id
* @return array
*/
private function extractId($id)
{
if ($this->isElement($id)) { //selenium-element
return $id->toWebDriverObject();
}
//html-id or null
return $id;
}
/**
* @param $id
* @return bool
*/
private function isElement($id)
{
return $id instanceof PHPUnit_Extensions_Selenium2TestCase_Element;
}
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Gets an attribute from the session (title, alert text, etc.)
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Gets or sets the current URL of the window.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($url, $commandUrl, PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl)
{
if ($url !== NULL) {
$absoluteLocation = $baseUrl->jump($url)->getValue();
$jsonParameters = array('url' => $absoluteLocation);
} else {
$jsonParameters = NULL;
}
parent::__construct($jsonParameters, $commandUrl);
}
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Obtains the text of an alert, or types into a prompt.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
if (is_string($argument)) {
$jsonParameters =array('text' => $argument);
} else if ($argument == NULL) {
$jsonParameters = NULL;
} else {
throw new BadMethodCallException('Wrong parameters for alertText().');
}
parent::__construct($jsonParameters, $url);
}
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Changes the focus to a window.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($name, $commandUrl)
{
$jsonParameters = array('name' => $name);
parent::__construct($jsonParameters, $commandUrl);
}
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Christian Soronellas <csoronellas@emagister.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Gets or sets the current URL of the window.
*
* @package PHPUnit_Selenium
* @author Christian Soronellas <csoronellas@emagister.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($jsonParameters,
PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
if ($jsonParameters === NULL) {
parent::__construct(NULL, $url);
} else {
$jsonParameters = $this->keysForText($jsonParameters);
parent::__construct($jsonParameters, $url);
}
}
/**
* @return string
*/
public function httpMethod()
{
return 'POST';
}
/**
* Given a string returns an array of the characters that compose the string
*
* @param string $text
* @throws InvalidArgumentException
* @return array
*/
public function keysForText($text)
{
if (is_scalar($text)) {
return array('value' => preg_split('//u', (string) $text, -1, PREG_SPLIT_NO_EMPTY));
}
if (is_array($text)) {
return $text;
}
throw new InvalidArgumentException('The "text" argument should be a string or an array of special characters!');
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.8
*/
/**
* Moves the mouse pointer.
*
* @author Giorgio Sironi <info@giorgiosironi.com>
* @package PHPUnit_Selenium
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.8
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($element,
PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
if ($element instanceof PHPUnit_Extensions_Selenium2TestCase_Element) {
$jsonParameters = array(
'element' => $element->getId()
);
} else {
throw new PHPUnit_Extensions_Selenium2TestCase_Exception('Only moving over an element is supported. Please pass a PHPUnit_Extensions_Selenium2TestCase_Element instance.');
}
parent::__construct($jsonParameters, $url);
}
/**
* @return string
*/
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Jonathan Lipps <jlipps@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Gets or posts an attribute from/to the session (title, alert text, etc.)
*
* @package PHPUnit_Selenium
* @author Jonathan Lipps <jlipps@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.9
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Clicks Ok on an alert popup.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Jonathan Lipps <jlipps@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Gets or posts an attribute from/to the session (title, alert text, etc.)
*
* @package PHPUnit_Selenium
* @author Jonathan Lipps <jlipps@gmail.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.9
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation
extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
{
public function __construct($orientation, $commandUrl) {
if ($orientation !== NULL) {
$jsonParameters = array('orientation' => $orientation);
} else {
$jsonParameters = NULL;
}
parent::__construct($jsonParameters, $commandUrl);
}
public function httpMethod()
{
if ($this->jsonParameters) {
return 'POST';
}
return 'GET';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.13
*/
/**
* Sends session click command for emulating LEFT, MIDDLE or RIGHT mouse buttons
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.13
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
const LEFT = 0;
const MIDDLE = 1;
const RIGHT = 2;
public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
if (is_null($argument)) {
$jsonParameters = NULL;
} elseif (!is_scalar($argument) || !in_array($argument, array(
self::LEFT, self::RIGHT, self::MIDDLE
))) {
throw new BadMethodCallException('Wrong parameter for click(): expecting 0, 1 or 2.');
} else {
$jsonParameters = array('button' => $argument);
}
parent::__construct($jsonParameters, $url);
}
public function httpMethod()
{
return 'POST';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.8
*/
/**
* Base class for implementing commands with special semantics.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.8
*/
class PHPUnit_Extensions_Selenium2TestCase_ScreenshotListener implements PHPUnit_Framework_TestListener
{
private $directory;
public function __construct($directory)
{
$this->directory = $directory;
}
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->storeAScreenshot($test);
}
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
{
$this->storeAScreenshot($test);
}
private function storeAScreenshot(PHPUnit_Framework_Test $test)
{
if ($test instanceof PHPUnit_Extensions_Selenium2TestCase)
{
try {
$file = $this->directory . '/' . get_class($test) . '__' . $test->getName() . '__ ' . date('Y-m-d\TH-i-s') . '.png';
file_put_contents($file, $test->currentScreenshot());
} catch (Exception $e) {
$file = $this->directory . '/' . get_class($test) . '__' . $test->getName() . '__ ' . date('Y-m-d\TH-i-s') . '.txt';
file_put_contents($file, "Screenshot generation doesn't work." . "\n"
. $e->getMessage() . "\n"
. $e->getTraceAsString());
}
}
}
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function startTest(PHPUnit_Framework_Test $test) {}
public function endTest(PHPUnit_Framework_Test $test, $time) {}
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.0
*/
/**
* Object representing a DOM element.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.0
* @method string attribute($name) Retrieves an element's attribute
* @method void clear() Empties the content of a form element.
* @method void click() Clicks on element
* @method string css($propertyName) Retrieves the value of a CSS property
* @method bool displayed() Checks an element's visibility
* @method bool enabled() Checks a form element's state
* @method bool equals(PHPUnit_Extensions_Selenium2TestCase_Element $another) Checks if the two elements are the same on the page
* @method array location() Retrieves the element's position in the page: keys 'x' and 'y' in the returned array
* @method bool selected() Checks the state of an option or other form element
* @method array size() Retrieves the dimensions of the element: 'width' and 'height' of the returned array
* @method void submit() Submits a form; can be called on its children
* @method string value($newValue = NULL) Get or set value of form elements. If the element already has a value, the set one will be appended to it.
* @method string text() Get content of ordinary elements
*/
class PHPUnit_Extensions_Selenium2TestCase_Element
extends PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
{
/**
* @return \self
* @throws InvalidArgumentException
*/
public static function fromResponseValue(
array $value,
PHPUnit_Extensions_Selenium2TestCase_URL $parentFolder,
PHPUnit_Extensions_Selenium2TestCase_Driver $driver)
{
if (!isset($value['ELEMENT'])) {
throw new InvalidArgumentException('Element not found.');
}
$url = $parentFolder->descend($value['ELEMENT']);
return new self($driver, $url);
}
/**
* @return integer
*/
public function getId()
{
return $this->url->lastSegment();
}
/**
* @return array class names
*/
protected function initCommands()
{
return array(
'attribute' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute',
'clear' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'click' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click',
'css' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css',
'displayed' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'enabled' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'equals' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals',
'location' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'name' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'selected' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'size' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'submit' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
'text' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
'value' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value',
'tap' => $this->touchCommandFactoryMethod('touch/click'),
'scroll' => $this->touchCommandFactoryMethod('touch/scroll'),
'doubletap' => $this->touchCommandFactoryMethod('touch/doubleclick'),
'longtap' => $this->touchCommandFactoryMethod('touch/longclick'),
'flick' => $this->touchCommandFactoryMethod('touch/flick')
);
}
protected function getSessionUrl()
{
return $this->url->ascend()->ascend();
}
private function touchCommandFactoryMethod($urlSegment)
{
$url = $this->getSessionUrl()->addCommand($urlSegment);
$self = $this;
return function ($jsonParameters, $commandUrl) use ($url, $self) {
if ((is_array($jsonParameters) &&
!isset($jsonParameters['element'])) ||
is_null($jsonParameters)) {
$jsonParameters['element'] = $self->getId();
}
return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $url);
};
}
/**
* Retrieves the tag name
* @return string
*/
public function name()
{
return strtolower(parent::name());
}
/**
* Generates an array that is structured as the WebDriver Object of the JSONWireProtocoll
*
* @return array
*/
public function toWebDriverObject()
{
return array('ELEMENT' => (string)$this->getId());
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.4
*/
/**
* Object representing elements, or everything that may have subcommands.
*
* @package PHPUnit_Selenium
* @author Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.4
*/
abstract class PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
{
/**
* @var PHPUnit_Extensions_Selenium2TestCase_Driver
*/
protected $driver;
/**
* @var string the API URL for this element,
*/
protected $url;
/**
* @var array instances of
* PHPUnit_Extensions_Selenium2TestCase_ElementCommand
*/
protected $commands;
public function __construct($driver,
PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
$this->driver = $driver;
$this->url = $url;
$this->commands = array();
foreach ($this->initCommands() as $commandName => $handler) {
if (is_string($handler)) {
$this->commands[$commandName] = $this->factoryMethod($handler);
} else if (is_callable($handler)) {
$this->commands[$commandName] = $handler;
} else {
throw new InvalidArgumentException("Command $commandName is not configured correctly.");
}
}
}
/**
* @return array class names, or
* callables of the form function($parameter, $commandUrl)
*/
protected abstract function initCommands();
public function __call($commandName, $arguments)
{
$jsonParameters = $this->extractJsonParameters($arguments);
$response = $this->driver->execute($this->newCommand($commandName, $jsonParameters));
return $response->getValue();
}
protected function postCommand($name, PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
{
$response = $this->driver->curl('POST',
$this->url->addCommand($name),
$criteria->getArrayCopy());
return $response->getValue();
}
/**
* @params string $commandClass a class name, descending from
PHPUnit_Extensions_Selenium2TestCase_Command
* @return callable
*/
private function factoryMethod($commandClass)
{
return function($jsonParameters, $url) use ($commandClass) {
return new $commandClass($jsonParameters, $url);
};
}
private function extractJsonParameters($arguments)
{
$this->checkArguments($arguments);
if (count($arguments) == 0) {
return NULL;
}
return $arguments[0];
}
private function checkArguments($arguments)
{
if (count($arguments) > 1) {
throw new Exception('You cannot call a command with multiple method arguments.');
}
}
/**
* @param string $commandName The called method name
* defined as a key in initCommands()
* @param array $jsonParameters
* @return PHPUnit_Extensions_Selenium2TestCase_Command
*/
protected function newCommand($commandName, $jsonParameters)
{
if (isset($this->commands[$commandName])) {
$factoryMethod = $this->commands[$commandName];
$url = $this->url->addCommand($commandName);
$command = $factoryMethod($jsonParameters, $url);
return $command;
}
throw new BadMethodCallException("The command '$commandName' is not existent or not supported yet.");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.2.12
*/
/**
* The WaitUntil implementation, inspired by Java and .NET clients
*
* @package PHPUnit_Selenium
* @author Ivan Kurnosov <zerkms@zerkms.com>
* @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.3.1
* @link http://www.phpunit.de/
* @since Class available since Release 1.2.12
* @see http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/WebDriverWait.cs
* @see http://selenium.googlecode.com/svn/trunk/java/client/src/org/openqa/selenium/support/ui/FluentWait.java
*/
class PHPUnit_Extensions_Selenium2TestCase_WaitUntil
{
/**
* PHPUnit Test Case instance
*
* @var PHPUnit_Extensions_Selenium2TestCase
*/
private $_testCase;
/**
* Default timeout, ms
*
* @var int
*/
private $_defaultTimeout = 0;
/**
* The sleep interval between iterations, ms
*
* @var int
*/
private $_defaultSleepInterval = 500;
/**
* @param PHPUnit_Extensions_Selenium2TestCase $testCase
*/
public function __construct(PHPUnit_Extensions_Selenium2TestCase $testCase)
{
$this->_testCase = $testCase;
}
/**
* @param $callback Callback to run until it returns not null or timeout occurs
* @param null $timeout
* @return mixed
* @throws PHPUnit_Extensions_Selenium2TestCase_Exception
* @throws PHPUnit_Extensions_Selenium2TestCase_WebDriverException
*/
public function run($callback, $timeout = null)
{
if (!is_callable($callback)) {
throw new PHPUnit_Extensions_Selenium2TestCase_Exception('The valid callback is expected');
}
// if there was an implicit timeout specified - remember it and temporarily turn it off
$implicitWait = $this->_testCase->timeouts()->getLastImplicitWaitValue();
if ($implicitWait) {
$this->_testCase->timeouts()->implicitWait(0);
}
if (is_null($timeout)) {
$timeout = $this->_defaultTimeout;
}
$timeout /= 1000;
$endTime = microtime(true) + $timeout;
$lastException = null;
while (true) {
try {
$result = $callback($this->_testCase);
if (!is_null($result)) {
if ($implicitWait) {
$this->_testCase->timeouts()->implicitWait($implicitWait);
}
return $result;
}
} catch(Exception $e) {
$lastException = $e;
}
if (microtime(true) > $endTime) {
if ($implicitWait) {
$this->_testCase->timeouts()->implicitWait($implicitWait);
}
$message = "Timed out after {$timeout} second" . ($timeout != 1 ? 's' : '');
throw new PHPUnit_Extensions_Selenium2TestCase_WebDriverException($message,
PHPUnit_Extensions_Selenium2TestCase_WebDriverException::Timeout, $lastException);
}
usleep($this->_defaultSleepInterval * 1000);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
// 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.
if (!isset($GLOBALS['PHPUNIT_COVERAGE_DATA_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);
}
<?php
class PHPUnit_Extensions_SeleniumCommon_RemoteCoverage
{
public function __construct($coverageScriptUrl, $testId)
{
$this->coverageScriptUrl = $coverageScriptUrl;
$this->testId = $testId;
}
public function get()
{
if (!empty($this->coverageScriptUrl)) {
$url = sprintf(
'%s?PHPUNIT_SELENIUM_TEST_ID=%s',
$this->coverageScriptUrl,
$this->testId
);
$buffer = @file_get_contents($url);
if ($buffer !== FALSE) {
$coverageData = unserialize($buffer);
if (is_array($coverageData)) {
return $this->matchLocalAndRemotePaths($coverageData);
} else {
throw new Exception('Empty or invalid code coverage data received from url "' . $url . '"');
}
}
}
return array();
}
/**
* @param array $coverage
* @return array
* @author Mattis Stordalen Flister <mattis@xait.no>
*/
protected function matchLocalAndRemotePaths(array $coverage)
{
$coverageWithLocalPaths = array();
foreach ($coverage as $originalRemotePath => $data) {
$remotePath = $originalRemotePath;
$separator = $this->findDirectorySeparator($remotePath);
while (!($localpath = stream_resolve_include_path($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 <mattis@xait.no>
*/
protected function findDirectorySeparator($path)
{
if (strpos($path, '/') !== FALSE) {
return '/';
}
return '\\';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
require_once 'File/Iterator/Autoload.php';
require_once 'PHP/CodeCoverage/Autoload.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'])) {
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray(
$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'],
$_GET['PHPUNIT_SELENIUM_TEST_ID']
);
$coverage = array();
foreach ($files as $file) {
$data = unserialize(file_get_contents($file));
unlink($file);
unset($file);
$filter = new PHP_CodeCoverage_Filter();
foreach ($data as $file => $lines) {
if ($filter->isFile($file)) {
if (!isset($coverage[$file])) {
$coverage[$file] = array(
'md5' => md5_file($file), 'coverage' => $lines
);
} else {
foreach ($lines as $line => $flag) {
if (!isset($coverage[$file]['coverage'][$line]) ||
$flag > $coverage[$file]['coverage'][$line]) {
$coverage[$file]['coverage'][$line] = $flag;
}
}
}
}
}
}
print serialize($coverage);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit_Selenium
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
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(
$name = $file . '.' . md5(uniqid(rand(), TRUE)) . '.' . $_COOKIE['PHPUNIT_SELENIUM_TEST_ID'],
serialize($data)
);
}
PHPUnit_Selenium 1.2
====================
This is the list of changes for the PHPUnit_Selenium 1.2 release series.
PHPUnit_Selenium 1.3.1
----------------------
* setupPage() method that can be defined to be executed after the session is opened but before tests start
* Docblocks work now in Eclipse PDT
PHPUnit_Selenium 1.3.0
----------------------
* BC break: setBrowserUrl() argument is not loaded at the start of a test
* waitUntil() now works nicely with implicitWait()
* keysHolder() is deprecated, use keys() instead
* More complete frame() supportk
* Research of elements inside other element objects with by*() methods
* Supporting Selenium 2.32.0
* Element names are always lowercase for consistency
* Pause support for runSelenese() HTML cases
PHPUnit_Selenium 1.2.12
----------------------
* Added waitUntil(), byTag()
* Added specialKeys() for non-alphanumeric keys
PHPUnit_Selenium 1.2.11
----------------------
* Fixing Composer autoload support.
PHPUnit_Selenium 1.2.9
----------------------
* Support for PHPUnit 3.7, requiring PHP 5.3.
* New getter methods available for extendibility.
* Window maximization command.
* Multiple strategies for browser sessions: isolated and shared can coexist.
PHPUnit_Selenium 1.2.8
----------------------
* Implemented ScreenshotListener for taking screenshots in a red Selenium2TestCase.
PHPUnit_Selenium 1.2.7
----------------------
* Implemented #130: version number available programmatically.
* Implemented $this->keys().
* Session is now closed on failure.
* Added various docblocks for SeleniumTestCase.
* Browser session can now be started even in setUp().
PHPUnit_Selenium 1.2.6
----------------------
* Fixed #114 and #115: regressions of @depends/@dataProvider.
* Added $this->cookie() for adding and removing cookies via a Builder.
* Added Selenium2TestCase_Exception in the Cookie api.
* Supporting absolute URLs (http://...) in $this->url().
* Supporting uppercase URLs.
* Raising error message for stale elements reference (#117).
* No 500 errors when communicating with Selenium Server.
* Supporting Selenium 2.20.
* Tests for 404 pages.
* Supporting @depends/@dataProvider and similar annotations in SeleniumTestCase.
* Added getCssCount() in SeleniumTestCase.
PHPUnit_Selenium 1.2.5
----------------------
* Added Window object accessible via $this->currentWindow().
* Implemented $this->timeouts()->asyncScript().
* Fixed #105: $browsers static property.
PHPUnit_Selenium 1.2.4
----------------------
* Implemented $element->size().
* Implemented $element->location().
* Implemented $element->name(), $element->attribute(), $element->equals(), $element->enabled(), $element->displayed(), $element->css().
* Implemented $this->elements() for multiple element selection in the whole page.
* Implemented $this->frame() to switch focus between frames on a page.
* Implemented $this->execute() and $this->executeAsync() for executing arbitrary JavaScript.
* Implemented $this->windowHandle(), $this->windowHandles and $this->source().
* Implemented $this->alertText("...") for answering prompts.
* Supporting form submit (also via children elements).
* Supporting radio boxes.
* Supporting implicit waits on $this->by*().
* Supporting back and forward buttons via $this->back() and $this->forward().
* Supporting refresh of pages via $this->refresh().
* Supporting $element->clear().
* Correctly marking Selenium 1 tests as skipped when server is not running.
PHPUnit_Selenium 1.2.3
----------------------
* Fixed package.xml to include missing SeleniumTestSuite.php file.
PHPUnit_Selenium 1.2.2
----------------------
* Implemented Select object, available via $this->select().
* Added defaults for Selenium Server host and port.
* Added @method annotations on Selenium2TestCase.
* Fixed #83: `setUpBeforeClass` and `tearDownAfterClass` do not work with `PHPUnit_Extensions_SeleniumTestCase`.
* Fixed #85: using POST instead of GET in Selenium RC Driver.
* Supporting AndroidDriver, both on devices and emulators.
* Supporting UTF-8 characters in Element::value().
PHPUnit_Selenium 1.2.1
----------------------
* Fixed #82: `@depends` annotation does not work with `PHPUnit_Extensions_SeleniumTestCase`.
* `package.xml` misses classes for Selenium 2 support.
PHPUnit_Selenium 1.2.0
----------------------
* Introduced `PHPUnit_Extensions_Selenium2TestCase` class for using WebDriver API.
* Introduced session sharing for WebDriver API.
* Introduced URL opening and element selection in WebDriver API.
* Introduced clicking on elements and `clickOnElement($id)` shorthand in WebDriver API.
* Introduced partial `alert()` management in WebDriver API.
* Introduced element manipulation in WebDriver API: text accessor, value mutator.
* Introduced `by*()` quick selectors in WebDriver API.
* Extracted a base command class for extending the supported session and element commands in WebDriver API.
@echo off
REM PHPUnit
REM
REM Copyright (c) 2002-2010, Sebastian Bergmann <sb@sebastian-bergmann.de>.
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
if "%PHPBIN%" == "" set PHPBIN=@php_bin@
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
GOTO RUN
:USE_PEAR_PATH
set PHPBIN=%PHP_PEAR_PHP_BIN%
:RUN
"%PHPBIN%" "@bin_dir@\dbunit" %*
DbUnit
Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for communicating with a database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection implements PHPUnit_Extensions_Database_DB_IDatabaseConnection
{
/**
* @var PDO
*/
protected $connection;
/**
* 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);
$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->getMetaData()->getSchema();
}
/**
* 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
* @return int
*/
public function getRowCount($tableName, $whereClause = NULL)
{
$query = "SELECT COUNT(*) FROM ".$this->quoteSchemaObject($tableName);
if (isset($whereClause)) {
$query .= " WHERE {$whereClause}";
}
return (int) $this->connection->query($query)->fetchColumn();
}
/**
* 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();
}
/**
* Disables primary keys if connection does not allow setting them otherwise
*
* @param string $tableName
*/
public function disablePrimaryKeys($tableName)
{
$this->getMetaData()->disablePrimaryKeys($tableName);
}
/**
* Reenables primary keys after they have been disabled
*
* @param string $tableName
*/
public function enablePrimaryKeys($tableName)
{
$this->getMetaData()->enablePrimaryKeys($tableName);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides the functionality to represent a database table.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for retreiving metadata from a database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
/**
* Disables primary keys if rdbms does not allow setting them otherwise
*
* @param string $tableName
*/
public function disablePrimaryKeys($tableName);
/**
* Reenables primary keys after they have been disabled
*
* @param string $tableName
*/
public function enablePrimaryKeys($tableName);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides iterative access to tables from a database instance.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for communicating with a database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
/**
* Disables primary keys if connection does not allow setting them otherwise
*
* @param string $tableName
*/
public function disablePrimaryKeys($tableName);
/**
* Reenables primary keys after they have been disabled
*
* @param string $tableName
*/
public function enablePrimaryKeys($tableName);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides access to a database instance as a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides access to a database instance as a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides functionality to retrieve meta data from a database with information_schema support.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Trond Hansen <trond@xait.no>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.2.3
*/
/**
* Provides functionality to retrieve meta data from an Oracle database.
*
* @package DbUnit
* @author Trond Hansen <trond@xait.no>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @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.
* @var string
*/
protected $schemaObjectQuoteChar = '';
/**
* The command used to perform a TRUNCATE operation.
* @var string
*/
protected $truncateCommand = 'TRUNCATE TABLE';
/**
* @var array
*/
protected $columns = array();
/**
* @var 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;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides functionality to retrieve meta data from a PostgreSQL database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_DB_MetaData_PgSQL extends PHPUnit_Extensions_Database_DB_MetaData
{
/**
* 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 database table.
*
* @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 = ?
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.KEY_COLUMN_USAGE as KCU
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC
ON TC.TABLE_NAME = KCU.TABLE_NAME
WHERE
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;
}
}
/**
* Returns the schema for the connection.
*
* @return string
*/
public function getSchema()
{
if (empty($this->schema)) {
return 'public';
} else {
return $this->schema;
}
}
/**
* Returns true if the rdbms allows cascading
*
* @return bool
*/
public function allowsCascading()
{
return TRUE;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides functionality to retrieve meta data from an Sqlite database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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];
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides functionality to retrieve meta data from a MySQL database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_DB_MetaData_MySQL extends PHPUnit_Extensions_Database_DB_MetaData
{
protected $schemaObjectQuoteChar = '`';
/**
* 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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Nils Adermann <naderman@naderman.de>
* @copyright 2002-2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.1.0
*/
/**
* Provides functionality to retrieve meta data from a Microsoft SQL Server database.
*
* @package DbUnit
* @author Nils Adermann <naderman@naderman.de>
* @copyright 2002-2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.1.0
*/
class PHPUnit_Extensions_Database_DB_MetaData_SqlSrv extends PHPUnit_Extensions_Database_DB_MetaData
{
/**
* No character used to quote schema objects.
* @var string
*/
protected $schemaObjectQuoteChar = '';
/**
* The command used to perform a TRUNCATE operation.
* @var string
*/
protected $truncateCommand = 'TRUNCATE TABLE';
/**
* Returns an array containing the names of all the tables in the database.
*
* @return array
*/
public function getTableNames()
{
$query = "SELECT name
FROM sysobjects
WHERE type='U'";
$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 = "SELECT c.name
FROM syscolumns c
LEFT JOIN sysobjects o ON c.id = o.id
WHERE o.name = '$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 = "EXEC sp_statistics '$tableName'";
$statement = $this->pdo->prepare($query);
$statement->execute();
$statement->setFetchMode(PDO::FETCH_ASSOC);
$columnNames = array();
while (($column = $statement->fetch())) {
if ($column['TYPE'] == 1) {
$columnNames[] = $column['COLUMN_NAME'];
}
}
return $columnNames;
}
/**
* Allow overwriting identities for the given table.
*
* @param string $tableName
*/
public function disablePrimaryKeys($tableName)
{
try {
$query = "SET IDENTITY_INSERT $tableName ON";
$this->pdo->exec($query);
}
catch (PDOException $e) {
// ignore the error here - can happen if primary key is not an identity
}
}
/**
* Reenable auto creation of identities for the given table.
*
* @param string $tableName
*/
public function enablePrimaryKeys($tableName)
{
try {
$query = "SET IDENTITY_INSERT $tableName OFF";
$this->pdo->exec($query);
}
catch (PDOException $e) {
// ignore the error here - can happen if primary key is not an identity
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* This class loads a table metadata object with database metadata.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides the functionality to represent a database result set as a DBUnit
* table.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @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 1.0.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));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic constructor for all meta data classes and a factory for
* generating the appropriate meta data class.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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',
'sqlite2'=> 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite',
'sqlsrv' => 'PHPUnit_Extensions_Database_DB_MetaData_SqlSrv'
);
/**
* 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 PHPUnit_Extensions_Database_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 PHPUnit_Extensions_Database_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 PHPUnit_Extensions_Database_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;
}
/**
* Disables primary keys if the rdbms does not allow setting them otherwise
*
* @param string $tableName
*/
public function disablePrimaryKeys($tableName)
{
return;
}
/**
* Reenables primary keys after they have been disabled
*
* @param string $tableName
*/
public function enablePrimaryKeys($tableName)
{
return;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A TestCase extension that provides functionality for testing and asserting
* against a real database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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)
{
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)
{
return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($xmlFile);
}
/**
* Create a a new MysqlXmlDataSet with the given $xmlFile. (absolute path.)
*
* @param string $xmlFile
* @return PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet
* @since Method available since Release 1.0.0
*/
protected function createMySQLXMLDataSet($xmlFile)
{
return new PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet($xmlFile);
}
/**
* Returns an operation factory instance that can be used to instantiate
* new operations.
*
* @return PHPUnit_Extensions_Database_Operation_Factory
*/
protected function getOperations()
{
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);
}
/**
* Assert that a given table has a given amount of rows
*
* @param string $tableName Name of the table
* @param int $expected Expected amount of rows in the table
* @param string $message Optional message
*/
public function assertTableRowCount($tableName, $expected, $message = '')
{
$constraint = new PHPUnit_Extensions_Database_Constraint_TableRowCount($tableName, $expected);
$actual = self::getConnection()->getRowCount($tableName);
self::assertThat($actual, $constraint, $message);
}
/**
* Asserts that a given table contains a given row
*
* @param array $expectedRow Row expected to find
* @param PHPUnit_Extensions_Database_DataSet_ITable $table Table to look into
* @param string $message Optional message
*/
public function assertTableContains(array $expectedRow, PHPUnit_Extensions_Database_DataSet_ITable $table, $message = '')
{
self::assertThat($table->assertContainsRow($expectedRow), self::isTrue(), $message);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Delegates database extension commands to the appropriate mode classes.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Defines the interface necessary to create new mediums.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Represents arguments received from a medium.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default factory for db extension modes.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Holds the context of a particular database extension ui call.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* An exception thrown when an invalid mode is requested from a mode factory.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Defines the interface necessary to create new modes
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Defines the interface necessary to create new medium printers.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Defines the interface necessary to create new mode factories
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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();
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Thrown for exceptions encountered with database operations. Provides
* information regarding which operations failed and the query (if any) it
* failed on.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Deletes the rows in a given dataset using primary key columns.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* This class provides functionality for inserting rows from a dataset into a database.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
{
if (count($databaseTableMetaData->getPrimaryKeys())) {
return TRUE;
}
return FALSE;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
/**
* Allows an operation to disable primary keys if necessary.
*
* @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData
* @param PHPUnit_Extensions_Database_DataSet_ITable $table
* @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
*/
protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
{
return FALSE;
}
/**
* @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);
$disablePrimaryKeys = $this->disablePrimaryKeys($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!");
}
if ($disablePrimaryKeys) {
$connection->disablePrimaryKeys($databaseTableMetaData->getTableName());
}
$statement = $connection->getConnection()->prepare($query);
$rowCount = $table->getRowCount();
for ($i = 0; $i < $rowCount; $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()
);
}
}
if ($disablePrimaryKeys) {
$connection->enablePrimaryKeys($databaseTableMetaData->getTableName());
}
}
}
protected function buildPreparedColumnArray($columns, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
{
$columnArray = array();
foreach ($columns as $columnName) {
$columnArray[] = "{$connection->quoteSchemaObject($columnName)} = ?";
}
return $columnArray;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Deletes all rows from all tables in a dataset.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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());
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Updates the rows in a given dataset using primary key columns.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
{
if (count($databaseTableMetaData->getPrimaryKeys())) {
return TRUE;
}
return FALSE;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* This class represents a null database operation.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 */
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface and functionality for executing database
* operations against a connection using a specific dataSet.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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());
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Executes a truncate against all tables in a dataset.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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());
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Updates the rows in a given dataset using primary key columns.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
$rowCount = $table->getRowCount();
for ($i = 0; $i < $rowCount; $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()
);
}
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A class factory to easily return database operations.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Thrown for exceptions encountered with database operations. Provides
* information regarding which operations failed and the query (if any) it
* failed on.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_Exception extends Exception
{
}<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Asserts whether or not two dbunit tables are equal.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* This method can be overridden to implement the evaluation algorithm.
*
* @param mixed $other Value or object to evaluate.
* @return bool
*/
protected function matches($other)
{
if (!$other instanceof PHPUnit_Extensions_Database_DataSet_ITable) {
throw new InvalidArgumentException(
'PHPUnit_Extensions_Database_DataSet_ITable expected'
);
}
return $this->value->matches($other);
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return $other->__toString() . ' ' . $this->toString();
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf(
'is equal to expected %s', $this->value->__toString()
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Asserts whether or not two dbunit datasets are equal.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* This method can be overridden to implement the evaluation algorithm.
*
* @param mixed $other Value or object to evaluate.
* @return bool
*/
protected function matches($other)
{
if (!$other instanceof PHPUnit_Extensions_Database_DataSet_IDataSet) {
throw new InvalidArgumentException(
'PHPUnit_Extensions_Database_DataSet_IDataSet expected'
);
}
return $this->value->matches($other);
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return $other->__toString() . ' ' . $this->toString();
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf(
'is equal to expected %s', $this->value->__toString()
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Asserts the row count in a table
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_Constraint_TableRowCount extends PHPUnit_Framework_Constraint
{
/**
* @var int
*/
protected $value;
/**
* @var string
*/
protected $tableName;
/**
* Creates a new constraint.
*
* @param int $expected
*/
public function __construct($tableName, $value)
{
$this->tableName = $tableName;
$this->value = $value;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* This method can be overridden to implement the evaluation algorithm.
*
* @param mixed $other Value or object to evaluate.
* @return bool
*/
protected function matches($other)
{
return $other == $this->value;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf('is equal to expected row count %d', $this->value);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* An interface for classes that require a list of databases to operate.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
interface PHPUnit_Extensions_Database_IDatabaseListConsumer
{
/**
* Sets the database for the spec
*
* @param array $databases
*/
public function setDatabases(array $databases);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides access to a database instance as a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Matthew Turland <tobias382@gmail.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Data set implementation for the output of mysqldump --xml.
*
* @package DbUnit
* @author Matthew Turland <tobias382@gmail.com>
* @copyright 2010-2013 Matthew Turland <tobias382@gmail.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
{
protected function getTableInfo(array &$tableColumns, array &$tableValues)
{
if ($this->xmlFileContents->getName() != 'mysqldump') {
throw new PHPUnit_Extensions_Database_Exception('The root element of a MySQL XML data set file must be called <mysqldump>');
}
foreach ($this->xmlFileContents->xpath('./database/table_data') as $tableElement) {
if (empty($tableElement['name'])) {
throw new PHPUnit_Extensions_Database_Exception('<table_data> elements must include a name attribute');
}
$tableName = (string)$tableElement['name'];
if (!isset($tableColumns[$tableName])) {
$tableColumns[$tableName] = array();
}
if (!isset($tableValues[$tableName])) {
$tableValues[$tableName] = array();
}
foreach ($tableElement->xpath('./row') as $rowElement) {
$rowValues = array();
foreach ($rowElement->xpath('./field') as $columnElement) {
if (empty($columnElement['name'])) {
throw new PHPUnit_Extensions_Database_Exception('<field> element name attributes cannot be empty');
}
$columnName = (string)$columnElement['name'];
if (!in_array($columnName, $tableColumns[$tableName])) {
$tableColumns[$tableName][] = $columnName;
}
}
foreach ($tableColumns[$tableName] as $columnName) {
$fields = $rowElement->xpath('./field[@name="' . $columnName . '"]');
$column = $fields[0];
$attr = $column->attributes('http://www.w3.org/2001/XMLSchema-instance');
if (isset($attr['type']) && (string) $attr['type'] === 'xs:hexBinary') {
$columnValue = pack('H*',(string)$column);
} else {
$null = isset($column['nil']) || isset($attr[0]);
$columnValue = $null ? NULL : (string)$column;
}
$rowValues[$columnName] = $columnValue;
}
$tableValues[$tableName][] = $rowValues;
}
}
foreach ($this->xmlFileContents->xpath('./database/table_structure') as $tableElement) {
if (empty($tableElement['name'])) {
throw new PHPUnit_Extensions_Database_Exception('<table_structure> elements must include a name attribute');
}
$tableName = (string) $tableElement['name'];
foreach ($tableElement->xpath('./field') as $fieldElement) {
if (empty($fieldElement['Field'])) {
throw new PHPUnit_Extensions_Database_Exception('<field> elements must include a Field attribute');
}
$columnName = (string) $fieldElement['Field'];
if (!in_array($columnName, $tableColumns[$tableName])) {
$tableColumns[$tableName][] = $columnName;
}
}
}
}
public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
{
$pers = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml;
$pers->setFileName($filename);
try {
$pers->write($dataset);
}
catch (RuntimeException $e) {
throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides the functionality to represent a database table.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
{
$this->loadData();
return parent::matches($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();
// if some rows are in the table
$columns = array();
if (isset($this->data[0]))
// get column names from data
$columns = array_keys($this->data[0]);
else {
// if no rows found, get column names from database
$pdoStatement = $this->databaseConnection->getConnection()->prepare("SELECT column_name FROM information_schema.COLUMNS WHERE table_schema=:schema AND table_name=:table");
$pdoStatement->execute(array(
"table" => $this->tableName,
"schema" => $this->databaseConnection->getSchema()
));
$columns = $pdoStatement->fetchAll(PDO::FETCH_COLUMN, 0);
}
// create metadata
$this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, $columns);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides an interface for creating data sets from data set spec strings.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default implementation of a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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}"
);
}
$errorReporting = error_reporting(0);
$libxmlErrorReporting = libxml_use_internal_errors(TRUE);
$this->xmlFileContents = simplexml_load_file($xmlFile);
if (!$this->xmlFileContents) {
$message = '';
foreach (libxml_get_errors() as $error) {
$message .= $error->message;
}
throw new RuntimeException($message);
}
libxml_clear_errors();
libxml_use_internal_errors($libxmlErrorReporting);
error_reporting($errorReporting);
$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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for creating and reading data from data sets.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_ITable $other);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides default table functionality.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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())
{
$this->data[] = array_merge(
array_fill_keys($this->getTableMetaData()->getColumns(), 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();
$rowCount = $table->getRowCount();
for ($i = 0; $i < $rowCount; $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.");
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default table iterator
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for creating and reading data from data sets.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default implementation of a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Allows for replacing arbitrary strings in your data sets with other values.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
{
$thisMetaData = $this->getTableMetaData();
$otherMetaData = $other->getTableMetaData();
if (!$thisMetaData->matches($otherMetaData) ||
$this->getRowCount() != $other->getRowCount()) {
return FALSE;
}
$columns = $thisMetaData->getColumns();
$rowCount = $this->getRowCount();
for ($i = 0; $i < $rowCount; $i++) {
foreach ($columns as $columnName) {
if ($this->getValue($i, $columnName) != $other->getValue($i, $columnName)) {
return FALSE;
}
}
}
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;
$rowCount = $this->getRowCount();
for ($i = 0; $i < $rowCount; $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];
}
else if (count($this->subStrReplacements) && isset($value)) {
return str_replace(array_keys($this->subStrReplacements), array_values($this->subStrReplacements), $value);
}
else {
return $value;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic functionality for dbunit tables
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
{
$thisMetaData = $this->getTableMetaData();
$otherMetaData = $other->getTableMetaData();
if (!$thisMetaData->matches($otherMetaData) ||
$this->getRowCount() != $other->getRowCount()) {
return FALSE;
}
$columns = $thisMetaData->getColumns();
$rowCount = $this->getRowCount();
for ($i = 0; $i < $rowCount; $i++) {
foreach ($columns as $columnName) {
if ($this->getValue($i, $columnName) != $other->getValue($i, $columnName)) {
return FALSE;
}
}
}
return TRUE;
}
/**
* Checks if a given row is in the table
*
* @param array $row
*
* @return bool
*/
public function assertContainsRow(array $row)
{
return in_array($row, $this->data);
}
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;
$rowCount = $this->getRowCount();
for ($i = 0; $i < $rowCount; $i++) {
$values = array();
foreach ($columns as $columnName) {
$values[] = $this->getValue($i, $columnName);
}
$tableString .= $this->rowToString($values) . $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";
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for creating and reading data from data sets.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Creates CsvDataSets.
*
* You can incrementally add CSV files as tables to your datasets
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_DataSet_CsvDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
{
/**
* @var array
*/
protected $tables = array();
/**
* @var string
*/
protected $delimiter = ',';
/**
* @var string
*/
protected $enclosure = '"';
/**
* @var string
*/
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);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default implementation of table meta data
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0CSV
*/
/**
* Creates a YAML dataset based off of a spec string.
*
* The format of the spec string is as follows:
*
* <filename>
*
* The filename should be the location of a yaml file relative to the
* current working directory.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0CSV
*/
/**
* Creates a XML dataset based off of a spec string.
*
* The format of the spec string is as follows:
*
* <filename>
*
* The filename should be the location of a xml file relative to the
* current working directory.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* An interface for data set spec factories.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Creates CsvDataSets based off of a spec string.
*
* The format of the spec string is as follows:
*
* <csv options>|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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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:
*
* <db label>:<schema>:<tables>
*
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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)
{
list($dbLabel, $schema, $tables) = explode(':', $dataSetSpec, 3);
$databaseInfo = $this->databases[$dbLabel];
$pdoRflc = new ReflectionClass('PDO');
$pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo));
$dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema);
return !empty($tables) ? $dbConnection->createDataSet(explode(',', $tables)) : $dbConnection->createDataSet();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* 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:
*
* <db label>:<schema>:<table name>:<sql>
*
* 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.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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)
{
list($dbLabel, $schema, $table, $sql) = explode(':', $dataSetSpec, 4);
$databaseInfo = $this->databases[$dbLabel];
$pdoRflc = new ReflectionClass('PDO');
$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));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0CSV
*/
/**
* Creates a FlatXML dataset based off of a spec string.
*
* The format of the spec string is as follows:
*
* <filename>
*
* The filename should be the location of a flat xml file relative to the
* current working directory.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Creates the appropriate DataSet Spec based on a given type.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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':
return new PHPUnit_Extensions_Database_DataSet_Specs_Xml();
case 'flatxml':
return new PHPUnit_Extensions_Database_DataSet_Specs_FlatXml();
case 'csv':
return new PHPUnit_Extensions_Database_DataSet_Specs_Csv();
case 'yaml':
return new PHPUnit_Extensions_Database_DataSet_Specs_Yaml();
case 'dbtable':
return new PHPUnit_Extensions_Database_DataSet_Specs_DbTable();
case 'dbquery':
return new PHPUnit_Extensions_Database_DataSet_Specs_DbQuery();
default:
throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me.");
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default table iterator
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A dataset decorator that allows filtering out tables and table columns from
* results.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides a basic interface for returning table meta data.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Implements the basic functionality of data sets.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other)
{
$thisTableNames = $this->getTableNames();
$otherTableNames = $other->getTableNames();
sort($thisTableNames);
sort($otherTableNames);
if ($thisTableNames != $otherTableNames) {
return FALSE;
}
foreach ($thisTableNames as $tableName) {
$table = $this->getTable($tableName);
if (!$table->matches($other->getTable($tableName))) {
return FALSE;
}
}
return TRUE;
}
public function __toString()
{
$iterator = $this->getIterator();
$dataSetString = '';
foreach ($iterator as $table) {
$dataSetString .= $table->__toString();
}
return $dataSetString;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default implementation of a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 PHPUnit_Extensions_Database_Exception("The root element of an xml data set file must be called <dataset>");
}
foreach ($this->xmlFileContents->xpath('/dataset/table') as $tableElement) {
if (empty($tableElement['name'])) {
throw new PHPUnit_Extensions_Database_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 PHPUnit_Extensions_Database_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 PHPUnit_Extensions_Database_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.');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A yaml dataset persistor
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
$emptyTables = array();
foreach ($dataset as $table) {
$tableName = $table->getTableMetaData()->getTableName();
$rowCount = $table->getRowCount();
if (!$rowCount) {
$emptyTables[] = $tableName;
continue;
}
$phpArr[$tableName] = array();
for ($i = 0; $i < $rowCount; $i++) {
$phpArr[$tableName][] = $table->getRow($i);
}
}
$emptyTablesAsString = '';
if (count($emptyTables)) {
$emptyTablesAsString = implode(":\n", $emptyTables) . ":\n\n";
}
file_put_contents(
$this->filename,
Symfony\Component\Yaml\Yaml::dump($phpArr, 3) . $emptyTablesAsString
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A XML dataset persistor.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
fwrite($this->fh, "<dataset>\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, "</dataset>\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, "\t<table name=\"{$table->getTableMetaData()->getTableName()}\">\n");
foreach ($table->getTableMetaData()->getColumns() as $columnName) {
fwrite($this->fh, "\t\t<column>{$columnName}</column>\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</table>\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<row>\n");
foreach ($table->getTableMetaData()->getColumns() as $columnName) {
if (isset($row[$columnName])) {
fwrite($this->fh, "\t\t\t<value>" . htmlspecialchars($row[$columnName]) . "</value>\n");
} else {
fwrite($this->fh, "\t\t\t<null />\n");
}
}
fwrite($this->fh, "\t\t</row>\n");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Matthew Turland <tobias382@gmail.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A MySQL XML dataset persistor.
*
* @package DbUnit
* @author Matthew Turland <tobias382@gmail.com>
* @copyright 2010-2013 Matthew Turland <tobias382@gmail.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
{
/**
* @var string
*/
protected $filename;
/**
* @var string
*/
protected $database;
/**
* @var resource
*/
protected $fh;
/**
* Sets the filename that this persistor will save to.
*
* @param string $filename
*/
public function setFileName($filename)
{
$this->filename = $filename;
}
/**
* Sets the name of the database.
*
* @param string $database
*/
public function setDatabase($database)
{
$this->database = $database;
}
/**
* 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, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
fwrite($this->fh, '<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . "\n");
fwrite($this->fh, '<database name="' . $this->database . '">' . "\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, '</database>' . "\n");
fwrite($this->fh, '</mysqldump>' . "\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, "\t" . '<table_data name="' . $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)
{
fwrite($this->fh, "\t" . '</table_data>' . "\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" . '<row>' . "\n");
foreach ($table->getTableMetaData()->getColumns() as $columnName) {
fwrite($this->fh, "\t\t" . '<field name="' . $columnName . '"');
if (isset($row[$columnName])) {
fwrite($this->fh, '>' . htmlspecialchars($row[$columnName]) . '</field>' . "\n");
} else {
fwrite($this->fh, ' xsi:nil="true" />' . "\n");
}
}
fwrite($this->fh, "\t" . '</row>' . "\n");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* An abstract implementation of a dataset persistor.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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)
{
$rowCount = $table->getRowCount();
$this->startTable($table);
for ($i = 0; $i < $rowCount; $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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A Flat XML dataset persistor.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
fwrite($this->fh, "<dataset>\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, "</dataset>\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");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Creates the appropriate Persistor based on a given type and spec.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de//**
* @since Class available since Release 1.0.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':
$xmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml();
$xmlPersistor->setFileName($spec);
return $xmlPersistor;
case 'flatxml':
$flatXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml();
$flatXmlPersistor->setFileName($spec);
return $flatXmlPersistor;
case 'yaml':
$yamlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml();
$yamlPersistor->setFileName($spec);
return $yamlPersistor;
default:
throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me. PERSISTOR");
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* An interface for persisting datasets
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* The default implementation of a data set.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 PHPUnit_Extensions_Database_Exception("The root element of a flat xml data set file must be called <dataset>");
}
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.');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Creates Composite Datasets
*
* Allows for creating datasets from multiple sources (csv, query, xml, etc.)
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Creates YamlDataSets.
*
* You can incrementally add YAML files as tables to your datasets
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 = Symfony\Component\Yaml\Yaml::parse($yamlFile);
foreach ($data as $tableName => $rows) {
if (!isset($rows)) {
$rows = array();
}
if (!is_array($rows)) {
continue;
}
if (!array_key_exists($tableName, $this->tables)) {
$columns = $this->getColumns($rows);
$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 a unique list of columns from all the rows in a table.
* If the table is defined another time in the Yaml, and if the Yaml
* parser could return the multiple occerrences, then this would be
* insufficient unless we grouped all the occurences of the table
* into onwe row set. sfYaml, however, does not provide multiple tables
* with the same name, it only supplies the last table.
*
* @params all the rows in a table.
*/
private function getColumns($rows) {
$columns = array();
foreach ($rows as $row) {
$columns = array_merge($columns, array_keys($row));
}
return array_values(array_unique($columns));
}
/**
* 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.'
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides basic functionality for table meta data.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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 matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other)
{
if ($this->getTableName() != $other->getTableName() ||
$this->getColumns() != $other->getColumns()) {
return FALSE;
}
return TRUE;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* A table decorator that allows filtering out table columns from results.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Can be used as a foundation for new DatabaseTesters.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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.
*/
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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* This is the default implementation of the database tester. It receives its
* connection object from the constructor.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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)
{
parent::__construct();
$this->connection = $connection;
}
/**
* Returns the test database connection.
*
* @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
*/
public function getConnection()
{
return $this->connection;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* This is the interface for DatabaseTester objects. These objects are used to
* add database testing to existing test cases using composition instead of
* extension.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2010-2013 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
DbUnit 1.2
==========
This is the list of changes for the DbUnit 1.2 release series.
DbUnit 1.2.3
------------
* No changes.
DbUnit 1.2.2
------------
* No changes.
DbUnit 1.2.1
------------
* No changes.
DbUnit 1.2.0
-------------
* Updated for PHPUnit 3.7.
#!/usr/bin/env php
<?php
/* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF 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());
}
require_once 'PHPUnit/Autoload.php';
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'PHPUNIT');
$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()
);
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
require_once 'BankAccount.php';
/**
* Tests for the BankAccount class.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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());
}
/*
*/
}
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<bank_account account_number="12345678912345678" balance="0.00" />
<bank_account account_number="12348612357236185" balance="89.00" />
<bank_account account_number="15934903649620486" balance="100.00" />
<bank_account account_number="15936487230215067" balance="1216.00" />
</dataset><?xml version="1.0" encoding="UTF-8"?>
<dataset>
<bank_account account_number="12348612357236185" balance="113.00" />
<bank_account account_number="15934903649620486" balance="200.00" />
<bank_account account_number="15936487230215067" balance="1446.00" />
</dataset><?xml version="1.0" encoding="UTF-8"?>
<dataset>
<bank_account account_number="12348612357236185" balance="65.00" />
<bank_account account_number="15934903649620486" balance="0.00" />
<bank_account account_number="15936487230215067" balance="986.00" />
</dataset><?xml version="1.0" encoding="UTF-8"?>
<dataset>
<bank_account account_number="15934903649620486" balance="100.00" />
<bank_account account_number="15936487230215067" balance="1216.00" />
<bank_account account_number="12348612357236185" balance="89.00" />
</dataset><?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
class BankAccountException extends RuntimeException {}
/**
* A bank account.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
require_once 'BankAccount.php';
/**
* Tests for the BankAccount class.
*
* @package DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.2.3
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.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());
}
/*
*/
}
<?php
/**
* PHP_Timer
*
* Copyright (c) 2010-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHP
* @subpackage Timer
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-timer
* @since File available since Release 1.0.0
*/
/**
* Utility class for timing.
*
* @package PHP
* @subpackage Timer
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2010-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.0.4
* @link http://github.com/sebastianbergmann/php-timer
* @since Class available since Release 1.0.0
*/
class PHP_Timer
{
/**
* @var array
*/
protected static $startTimes = array();
/**
* @var float
*/
public static $requestTime;
/**
* Starts the timer.
*/
public static function start()
{
array_push(self::$startTimes, microtime(TRUE));
}
/**
* Stops the timer and returns the elapsed time.
*
* @return float
*/
public static function stop()
{
return microtime(TRUE) - array_pop(self::$startTimes);
}
/**
* Formats the elapsed time as a string.
*
* @param float $time
* @return string
*/
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;
}
/**
* Formats the elapsed time since the start of the request as a string.
*
* @return string
*/
public static function timeSinceStartOfRequest()
{
return self::secondsToTimeString(time() - self::$requestTime);
}
/**
* Returns the resources (time, memory) of the request as a string.
*
* @return string
*/
public static function resourceUsage()
{
return sprintf(
'Time: %s, Memory: %4.2fMb',
self::timeSinceStartOfRequest(),
memory_get_peak_usage(TRUE) / 1048576
);
}
}
if (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME_FLOAT'];
}
else if (isset($_SERVER['REQUEST_TIME'])) {
PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME'];
}
else {
PHP_Timer::$requestTime = time();
}PHP_Timer
Copyright (c) 2010-2012, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
PHP_Timer 1.0
=============
This is the list of changes for the PHP_Timer 1.0 release series.
PHP_Timer 1.0.4
---------------
* No changes.
PHP_Timer 1.0.3
---------------
* No changes.
PHP_Timer 1.0.2
---------------
* `$_SERVER['REQUEST_TIME_FLOAT']` is used when available.
PHP_Timer 1.0.1
---------------
* No changes.
PHP_Timer 1.0.0
---------------
* Initial release.
PHP_Timer
=========
Installation
------------
PHP_Timer should be installed using the [PEAR Installer](http://pear.php.net/). This installer is the backbone of PEAR, which provides a distribution system for PHP packages, and is shipped with every release of PHP since version 4.3.0.
The PEAR channel (`pear.phpunit.de`) that is used to distribute PHP_Timer needs to be registered with the local PEAR environment:
sb@ubuntu ~ % pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded
This has to be done only once. Now the PEAR Installer can be used to install packages from the PHPUnit channel:
sb@vmware ~ % pear install phpunit/PHP_Timer
downloading PHP_Timer-1.0.0.tgz ...
Starting to download PHP_Timer-1.0.0.tgz (2,536 bytes)
....done: 2,536 bytes
install ok: channel://pear.phpunit.de/PHP_Timer-1.0.0
After the installation you can find the PHP_Timer source files inside your local PEAR directory; the path is usually `/usr/lib/php/PHP`.
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
use Symfony\Component\Yaml\Exception\ParseException;
/**
* Yaml offers convenience methods to load and dump YAML.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
*/
class Yaml
{
/**
* Be warned that PHP support will be removed in Symfony 2.3.
*
* @deprecated Deprecated since version 2.0, to be removed in 2.3.
*/
public static $enablePhpParsing = false;
/**
* Enables PHP support when parsing YAML files.
*
* Be warned that PHP support will be removed in Symfony 2.3.
*
* @deprecated Deprecated since version 2.0, to be removed in 2.3.
*/
public static function enablePhpParsing()
{
self::$enablePhpParsing = true;
}
/**
* Sets the PHP support flag when parsing YAML files.
*
* Be warned that PHP support will be removed in Symfony 2.3.
*
* @param Boolean $boolean true if PHP parsing support is enabled, false otherwise
*
* @deprecated Deprecated since version 2.0, to be removed in 2.3.
*/
public static function setPhpParsing($boolean)
{
self::$enablePhpParsing = (Boolean) $boolean;
}
/**
* Checks if PHP support is enabled when parsing YAML files.
*
* Be warned that PHP support will be removed in Symfony 2.3.
*
* @return Boolean true if PHP parsing support is enabled, false otherwise
*
* @deprecated Deprecated since version 2.0, to be removed in 2.3.
*/
public static function supportsPhpParsing()
{
return self::$enablePhpParsing;
}
/**
* Parses YAML into a PHP array.
*
* The parse method, when supplied with a YAML stream (string or file),
* will do its best to convert YAML in a file into a PHP array.
*
* Usage:
* <code>
* $array = Yaml::parse('config.yml');
* print_r($array);
* </code>
*
* As this method accepts both plain strings and file names as an input,
* you must validate the input before calling this method. Passing a file
* as an input is a deprecated feature and will be removed in 3.0.
*
* @param string $input Path to a YAML file or a string containing YAML
*
* @return array The YAML converted to a PHP array
*
* @throws ParseException If the YAML is not valid
*
* @api
*/
public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false)
{
// if input is a file, process it
$file = '';
if (strpos($input, "\n") === false && is_file($input)) {
if (false === is_readable($input)) {
throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
}
$file = $input;
if (self::$enablePhpParsing) {
ob_start();
$retval = include($file);
$content = ob_get_clean();
// if an array is returned by the config file assume it's in plain php form else in YAML
$input = is_array($retval) ? $retval : $content;
// if an array is returned by the config file assume it's in plain php form else in YAML
if (is_array($input)) {
return $input;
}
} else {
$input = file_get_contents($file);
}
}
$yaml = new Parser();
try {
return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport);
} catch (ParseException $e) {
if ($file) {
$e->setParsedFile($file);
}
throw $e;
}
}
/**
* Dumps a PHP array to a YAML string.
*
* The dump method, when supplied with an array, will do its best
* to convert the array into friendly YAML.
*
* @param array $array PHP array
* @param integer $inline The level where you switch to inline YAML
* @param integer $indent The amount of spaces to use for indentation of nested nodes.
* @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param Boolean $objectSupport true if object support is enabled, false otherwise
*
* @return string A YAML string representing the original PHP array
*
* @api
*/
public static function dump($array, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false)
{
$yaml = new Dumper();
$yaml->setIndentation($indent);
return $yaml->dump($array, $inline, 0, $exceptionOnInvalidType, $objectSupport);
}
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Tests;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Dumper;
class DumperTest extends \PHPUnit_Framework_TestCase
{
protected $parser;
protected $dumper;
protected $path;
protected function setUp()
{
$this->parser = new Parser();
$this->dumper = new Dumper();
$this->path = __DIR__.'/Fixtures';
}
protected function tearDown()
{
$this->parser = null;
$this->dumper = null;
$this->path = null;
}
public function testSpecifications()
{
$files = $this->parser->parse(file_get_contents($this->path.'/index.yml'));
foreach ($files as $file) {
$yamls = file_get_contents($this->path.'/'.$file.'.yml');
// split YAMLs documents
foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
if (!$yaml) {
continue;
}
$test = $this->parser->parse($yaml);
if (isset($test['dump_skip']) && $test['dump_skip']) {
continue;
} elseif (isset($test['todo']) && $test['todo']) {
// TODO
} else {
$expected = eval('return '.trim($test['php']).';');
$this->assertEquals($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
}
}
}
}
public function testInlineLevel()
{
// inline level
$array = array(
'' => 'bar',
'foo' => '#bar',
'foo\'bar' => array(),
'bar' => array(1, 'foo'),
'foobar' => array(
'foo' => 'bar',
'bar' => array(1, 'foo'),
'foobar' => array(
'foo' => 'bar',
'bar' => array(1, 'foo'),
),
),
);
$expected = <<<EOF
{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } }
EOF;
$this->assertEquals($expected, $this->dumper->dump($array, -10), '->dump() takes an inline level argument');
$this->assertEquals($expected, $this->dumper->dump($array, 0), '->dump() takes an inline level argument');
$expected = <<<EOF
'': bar
foo: '#bar'
'foo''bar': { }
bar: [1, foo]
foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } }
EOF;
$this->assertEquals($expected, $this->dumper->dump($array, 1), '->dump() takes an inline level argument');
$expected = <<<EOF
'': bar
foo: '#bar'
'foo''bar': { }
bar:
- 1
- foo
foobar:
foo: bar
bar: [1, foo]
foobar: { foo: bar, bar: [1, foo] }
EOF;
$this->assertEquals($expected, $this->dumper->dump($array, 2), '->dump() takes an inline level argument');
$expected = <<<EOF
'': bar
foo: '#bar'
'foo''bar': { }
bar:
- 1
- foo
foobar:
foo: bar
bar:
- 1
- foo
foobar:
foo: bar
bar: [1, foo]
EOF;
$this->assertEquals($expected, $this->dumper->dump($array, 3), '->dump() takes an inline level argument');
$expected = <<<EOF
'': bar
foo: '#bar'
'foo''bar': { }
bar:
- 1
- foo
foobar:
foo: bar
bar:
- 1
- foo
foobar:
foo: bar
bar:
- 1
- foo
EOF;
$this->assertEquals($expected, $this->dumper->dump($array, 4), '->dump() takes an inline level argument');
$this->assertEquals($expected, $this->dumper->dump($array, 10), '->dump() takes an inline level argument');
}
public function testObjectSupportEnabled()
{
$dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true);
$this->assertEquals('{ foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects');
}
public function testObjectSupportDisabledButNoExceptions()
{
$dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1));
$this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled');
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\DumpException
*/
public function testObjectSupportDisabledWithExceptions()
{
$this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false);
}
}
class A
{
public $a = 'foo';
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Tests;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Inline;
class InlineTest extends \PHPUnit_Framework_TestCase
{
public function testParse()
{
foreach ($this->getTestsForParse() as $yaml => $value) {
$this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
}
}
public function testDump()
{
$testsForDump = $this->getTestsForDump();
foreach ($testsForDump as $yaml => $value) {
$this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));
}
foreach ($this->getTestsForParse() as $yaml => $value) {
$this->assertEquals($value, Inline::parse(Inline::dump($value)), 'check consistency');
}
foreach ($testsForDump as $yaml => $value) {
$this->assertEquals($value, Inline::parse(Inline::dump($value)), 'check consistency');
}
}
public function testDumpNumericValueWithLocale()
{
$locale = setlocale(LC_NUMERIC, 0);
if (false === $locale) {
$this->markTestSkipped('Your platform does not support locales.');
}
$required_locales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
if (false === setlocale(LC_ALL, $required_locales)) {
$this->markTestSkipped('Could not set any of required locales: ' . implode(", ", $required_locales));
}
$this->assertEquals('1.2', Inline::dump(1.2));
$this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
setlocale(LC_ALL, $locale);
}
public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()
{
$value = '686e444';
$this->assertSame($value, Inline::parse(Inline::dump($value)));
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
{
$value = "'don't do somthin' like that'";
Inline::parse($value);
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
{
$value = '"don"t do somthin" like that"';
Inline::parse($value);
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseInvalidMappingKeyShouldThrowException()
{
$value = '{ "foo " bar": "bar" }';
Inline::parse($value);
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseInvalidMappingShouldThrowException()
{
Inline::parse('[foo] bar');
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseInvalidSequenceShouldThrowException()
{
Inline::parse('{ foo: bar } bar');
}
public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
{
$value = "'don''t do somthin'' like that'";
$expect = "don't do somthin' like that";
$this->assertSame($expect, Inline::parseScalar($value));
}
protected function getTestsForParse()
{
return array(
'' => '',
'null' => null,
'false' => false,
'true' => true,
'12' => 12,
'-12' => -12,
'"quoted string"' => 'quoted string',
"'quoted string'" => 'quoted string',
'12.30e+02' => 12.30e+02,
'0x4D2' => 0x4D2,
'02333' => 02333,
'.Inf' => -log(0),
'-.Inf' => log(0),
"'686e444'" => '686e444',
'686e444' => 646e444,
'123456789123456789123456789123456789' => '123456789123456789123456789123456789',
'"foo\r\nbar"' => "foo\r\nbar",
"'foo#bar'" => 'foo#bar',
"'foo # bar'" => 'foo # bar',
"'#cfcfcf'" => '#cfcfcf',
'::form_base.html.twig' => '::form_base.html.twig',
'2007-10-30' => mktime(0, 0, 0, 10, 30, 2007),
'2007-10-30T02:59:43Z' => gmmktime(2, 59, 43, 10, 30, 2007),
'2007-10-30 02:59:43 Z' => gmmktime(2, 59, 43, 10, 30, 2007),
'1960-10-30 02:59:43 Z' => gmmktime(2, 59, 43, 10, 30, 1960),
'1730-10-30T02:59:43Z' => gmmktime(2, 59, 43, 10, 30, 1730),
'"a \\"string\\" with \'quoted strings inside\'"' => 'a "string" with \'quoted strings inside\'',
"'a \"string\" with ''quoted strings inside'''" => 'a "string" with \'quoted strings inside\'',
// sequences
// urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
'[foo, http://urls.are/no/mappings, false, null, 12]' => array('foo', 'http://urls.are/no/mappings', false, null, 12),
'[ foo , bar , false , null , 12 ]' => array('foo', 'bar', false, null, 12),
'[\'foo,bar\', \'foo bar\']' => array('foo,bar', 'foo bar'),
// mappings
'{foo:bar,bar:foo,false:false,null:null,integer:12}' => array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12),
'{ foo : bar, bar : foo, false : false, null : null, integer : 12 }' => array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12),
'{foo: \'bar\', bar: \'foo: bar\'}' => array('foo' => 'bar', 'bar' => 'foo: bar'),
'{\'foo\': \'bar\', "bar": \'foo: bar\'}' => array('foo' => 'bar', 'bar' => 'foo: bar'),
'{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}' => array('foo\'' => 'bar', "bar\"" => 'foo: bar'),
'{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}' => array('foo: ' => 'bar', "bar: " => 'foo: bar'),
// nested sequences and mappings
'[foo, [bar, foo]]' => array('foo', array('bar', 'foo')),
'[foo, {bar: foo}]' => array('foo', array('bar' => 'foo')),
'{ foo: {bar: foo} }' => array('foo' => array('bar' => 'foo')),
'{ foo: [bar, foo] }' => array('foo' => array('bar', 'foo')),
'[ foo, [ bar, foo ] ]' => array('foo', array('bar', 'foo')),
'[{ foo: {bar: foo} }]' => array(array('foo' => array('bar' => 'foo'))),
'[foo, [bar, [foo, [bar, foo]], foo]]' => array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo')),
'[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]' => array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo'))),
'[foo, bar: { foo: bar }]' => array('foo', '1' => array('bar' => array('foo' => 'bar'))),
'[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']' => array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%',), true, '@service_container',),
);
}
protected function getTestsForDump()
{
return array(
'null' => null,
'false' => false,
'true' => true,
'12' => 12,
"'quoted string'" => 'quoted string',
'12.30e+02' => 12.30e+02,
'1234' => 0x4D2,
'1243' => 02333,
'.Inf' => -log(0),
'-.Inf' => log(0),
"'686e444'" => '686e444',
'.Inf' => 646e444,
'"foo\r\nbar"' => "foo\r\nbar",
"'foo#bar'" => 'foo#bar',
"'foo # bar'" => 'foo # bar',
"'#cfcfcf'" => '#cfcfcf',
"'a \"string\" with ''quoted strings inside'''" => 'a "string" with \'quoted strings inside\'',
// sequences
'[foo, bar, false, null, 12]' => array('foo', 'bar', false, null, 12),
'[\'foo,bar\', \'foo bar\']' => array('foo,bar', 'foo bar'),
// mappings
'{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }' => array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12),
'{ foo: bar, bar: \'foo: bar\' }' => array('foo' => 'bar', 'bar' => 'foo: bar'),
// nested sequences and mappings
'[foo, [bar, foo]]' => array('foo', array('bar', 'foo')),
'[foo, [bar, [foo, [bar, foo]], foo]]' => array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo')),
'{ foo: { bar: foo } }' => array('foo' => array('bar' => 'foo')),
'[foo, { bar: foo }]' => array('foo', array('bar' => 'foo')),
'[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]' => array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo'))),
'[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']' => array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%',), true, '@service_container',),
);
}
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Tests;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Parser;
class ParserTest extends \PHPUnit_Framework_TestCase
{
protected $parser;
protected function setUp()
{
$this->parser = new Parser();
}
protected function tearDown()
{
$this->parser = null;
}
/**
* @dataProvider getDataFormSpecifications
*/
public function testSpecifications($file, $expected, $yaml, $comment)
{
if ('escapedCharacters' == $file) {
if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
$this->markTestSkipped('The iconv and mbstring extensions are not available.');
}
}
$this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
}
public function getDataFormSpecifications()
{
$parser = new Parser();
$path = __DIR__.'/Fixtures';
$tests = array();
$files = $parser->parse(file_get_contents($path.'/index.yml'));
foreach ($files as $file) {
$yamls = file_get_contents($path.'/'.$file.'.yml');
// split YAMLs documents
foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
if (!$yaml) {
continue;
}
$test = $parser->parse($yaml);
if (isset($test['todo']) && $test['todo']) {
// TODO
} else {
$expected = var_export(eval('return '.trim($test['php']).';'), true);
$tests[] = array($file, $expected, $test['yaml'], $test['test']);
}
}
}
return $tests;
}
public function testTabsInYaml()
{
// test tabs in YAML
$yamls = array(
"foo:\n bar",
"foo:\n bar",
"foo:\n bar",
"foo:\n bar",
);
foreach ($yamls as $yaml) {
try {
$content = $this->parser->parse($yaml);
$this->fail('YAML files must not contain tabs');
} catch (\Exception $e) {
$this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
$this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
}
}
}
public function testEndOfTheDocumentMarker()
{
$yaml = <<<EOF
--- %YAML:1.0
foo
...
EOF;
$this->assertEquals('foo', $this->parser->parse($yaml));
}
public function getBlockChompingTests()
{
$tests = array();
$yaml = <<<'EOF'
foo: |-
one
two
bar: |-
one
two
EOF;
$expected = array(
'foo' => "one\ntwo",
'bar' => "one\ntwo",
);
$tests['Literal block chomping strip with trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: |-
one
two
bar: |-
one
two
EOF;
$expected = array(
'foo' => "one\ntwo",
'bar' => "one\ntwo",
);
$tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: |
one
two
bar: |
one
two
EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo\n",
);
$tests['Literal block chomping clip with trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: |
one
two
bar: |
one
two
EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo\n",
);
$tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: |+
one
two
bar: |+
one
two
EOF;
$expected = array(
'foo' => "one\ntwo\n\n",
'bar' => "one\ntwo\n\n",
);
$tests['Literal block chomping keep with trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: |+
one
two
bar: |+
one
two
EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo\n",
);
$tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: >-
one
two
bar: >-
one
two
EOF;
$expected = array(
'foo' => "one two",
'bar' => "one two",
);
$tests['Folded block chomping strip with trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: >-
one
two
bar: >-
one
two
EOF;
$expected = array(
'foo' => "one two",
'bar' => "one two",
);
$tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: >
one
two
bar: >
one
two
EOF;
$expected = array(
'foo' => "one two\n",
'bar' => "one two\n",
);
$tests['Folded block chomping clip with trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: >
one
two
bar: >
one
two
EOF;
$expected = array(
'foo' => "one two\n",
'bar' => "one two\n",
);
$tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: >+
one
two
bar: >+
one
two
EOF;
$expected = array(
'foo' => "one two\n\n",
'bar' => "one two\n\n",
);
$tests['Folded block chomping keep with trailing newline'] = array($expected, $yaml);
$yaml = <<<'EOF'
foo: >+
one
two
bar: >+
one
two
EOF;
$expected = array(
'foo' => "one two\n",
'bar' => "one two\n",
);
$tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);
return $tests;
}
/**
* @dataProvider getBlockChompingTests
*/
public function testBlockChomping($expected, $yaml)
{
$this->assertSame($expected, $this->parser->parse($yaml));
}
public function testObjectSupportEnabled()
{
$input = <<<EOF
foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
$this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');
}
public function testObjectSupportDisabledButNoExceptions()
{
$input = <<<EOF
foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
$this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testObjectsSupportDisabledWithExceptions()
{
$this->parser->parse('foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}', true, false);
}
public function testNonUtf8Exception()
{
if (!function_exists('mb_detect_encoding') || !function_exists('iconv')) {
$this->markTestSkipped('Exceptions for non-utf8 charsets require the mb_detect_encoding() and iconv() functions.');
return;
}
$yamls = array(
iconv("UTF-8", "ISO-8859-1", "foo: 'äöüß'"),
iconv("UTF-8", "ISO-8859-15", "euro: '€'"),
iconv("UTF-8", "CP1252", "cp1252: '©ÉÇáñ'")
);
foreach ($yamls as $yaml) {
try {
$this->parser->parse($yaml);
$this->fail('charsets other than UTF-8 are rejected.');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
}
}
}
/**
*
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*
*/
public function testUnindentedCollectionException()
{
$yaml = <<<EOF
collection:
-item1
-item2
-item3
EOF;
$this->parser->parse($yaml);
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testSequenceInAMapping()
{
Yaml::parse(<<<EOF
yaml:
hash: me
- array stuff
EOF
);
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testMappingInASequence()
{
Yaml::parse(<<<EOF
yaml:
- array stuff
hash: me
EOF
);
}
}
class B
{
public $b = 'foo';
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Tests;
use Symfony\Component\Yaml\Yaml;
class YamlTest extends \PHPUnit_Framework_TestCase
{
public function testParseAndDump()
{
$data = array('lorem' => 'ipsum', 'dolor' => 'sit');
$yml = Yaml::dump($data);
$parsed = Yaml::parse($yml);
$this->assertEquals($data, $parsed);
$filename = __DIR__.'/Fixtures/index.yml';
$contents = file_get_contents($filename);
$parsedByFilename = Yaml::parse($filename);
$parsedByContents = Yaml::parse($contents);
$this->assertEquals($parsedByFilename, $parsedByContents);
}
public function testEmbededPhp()
{
$filename = __DIR__.'/Fixtures/embededPhp.yml';
Yaml::enablePhpParsing();
$parsed = Yaml::parse($filename);
$this->assertEquals(array('value' => 6), $parsed);
}
}
--- %YAML:1.0
test: Objects
brief: >
Comments at the end of a line
yaml: |
ex1: "foo # bar"
ex2: "foo # bar" # comment
ex3: 'foo # bar' # comment
ex4: foo # comment
php: |
array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
--- %YAML:1.0
test: Empty Sequence
brief: >
You can represent the empty sequence
with an empty inline sequence.
yaml: |
empty: []
php: |
array('empty' => array())
---
test: Empty Mapping
brief: >
You can represent the empty mapping
with an empty inline mapping.
yaml: |
empty: {}
php: |
array('empty' => array())
---
test: Empty Sequence as Entire Document
yaml: |
[]
php: |
array()
---
test: Empty Mapping as Entire Document
yaml: |
{}
php: |
array()
---
test: Null as Document
yaml: |
~
php: |
null
---
test: Empty String
brief: >
You can represent an empty string
with a pair of quotes.
yaml: |
''
php: |
''
--- %YAML:1.0
test: Multiple quoted string on one line
brief: >
Multiple quoted string on one line
yaml: |
stripped_title: { name: "foo bar", help: "bar foo" }
php: |
array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo'))
---
test: Empty sequence
yaml: |
foo: [ ]
php: |
array('foo' => array())
---
test: Empty value
yaml: |
foo:
php: |
array('foo' => null)
---
test: Inline string parsing
brief: >
Inline string parsing
yaml: |
test: ['complex: string', 'another [string]']
php: |
array('test' => array('complex: string', 'another [string]'))
---
test: Boolean
brief: >
Boolean
yaml: |
- false
- true
- null
- ~
- 'false'
- 'true'
- 'null'
- '~'
php: |
array(
false,
true,
null,
null,
'false',
'true',
'null',
'~',
)
---
test: Empty lines in folded blocks
brief: >
Empty lines in folded blocks
yaml: |
foo:
bar: |
foo
bar
php: |
array('foo' => array('bar' => "foo\n\n\n \nbar\n"))
---
test: IP addresses
brief: >
IP addresses
yaml: |
foo: 10.0.0.2
php: |
array('foo' => '10.0.0.2')
---
test: A sequence with an embedded mapping
brief: >
A sequence with an embedded mapping
yaml: |
- foo
- bar: { bar: foo }
php: |
array('foo', array('bar' => array('bar' => 'foo')))
---
test: A sequence with an unordered array
brief: >
A sequence with an unordered array
yaml: |
1: foo
0: bar
php: |
array(1 => 'foo', 0 => 'bar')
---
test: Octal
brief: as in spec example 2.19, octal value is converted
yaml: |
foo: 0123
php: |
array('foo' => 83)
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |
foo: "0123"
php: |
array('foo' => '0123')
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |
foo: '0123'
php: |
array('foo' => '0123')
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |
foo: |
0123
php: |
array('foo' => "0123\n")
---
test: Document as a simple hash
brief: Document as a simple hash
yaml: |
{ foo: bar }
php: |
array('foo' => 'bar')
---
test: Document as a simple array
brief: Document as a simple array
yaml: |
[ foo, bar ]
php: |
array('foo', 'bar')
--- %YAML:1.0
test: Compact notation
brief: |
Compact notation for sets of mappings with single element
yaml: |
---
# products purchased
- item : Super Hoop
- item : Basketball
quantity: 1
- item:
name: Big Shoes
nick: Biggies
quantity: 1
php: |
array (
array (
'item' => 'Super Hoop',
),
array (
'item' => 'Basketball',
'quantity' => 1,
),
array (
'item' => array(
'name' => 'Big Shoes',
'nick' => 'Biggies'
),
'quantity' => 1
)
)
---
test: Compact notation combined with inline notation
brief: |
Combinations of compact and inline notation are allowed
yaml: |
---
items:
- { item: Super Hoop, quantity: 1 }
- [ Basketball, Big Shoes ]
php: |
array (
'items' => array (
array (
'item' => 'Super Hoop',
'quantity' => 1,
),
array (
'Basketball',
'Big Shoes'
)
)
)
--- %YAML:1.0
test: Compact notation
brief: |
Compact notation for sets of mappings with single element
yaml: |
---
# products purchased
- item : Super Hoop
- item : Basketball
quantity: 1
- item:
name: Big Shoes
nick: Biggies
quantity: 1
php: |
array (
array (
'item' => 'Super Hoop',
),
array (
'item' => 'Basketball',
'quantity' => 1,
),
array (
'item' => array(
'name' => 'Big Shoes',
'nick' => 'Biggies'
),
'quantity' => 1
)
)
---
test: Compact notation combined with inline notation
brief: |
Combinations of compact and inline notation are allowed
yaml: |
---
items:
- { item: Super Hoop, quantity: 1 }
- [ Basketball, Big Shoes ]
php: |
array (
'items' => array (
array (
'item' => 'Super Hoop',
'quantity' => 1,
),
array (
'Basketball',
'Big Shoes'
)
)
)
--- %YAML:1.0
test: Compact notation
brief: |
Compact notation for sets of mappings with single element
yaml: |
---
# products purchased
- item : Super Hoop
- item : Basketball
quantity: 1
- item:
name: Big Shoes
nick: Biggies
quantity: 1
php: |
array (
array (
'item' => 'Super Hoop',
),
array (
'item' => 'Basketball',
'quantity' => 1,
),
array (
'item' => array(
'name' => 'Big Shoes',
'nick' => 'Biggies'
),
'quantity' => 1
)
)
---
test: Compact notation combined with inline notation
brief: |
Combinations of compact and inline notation are allowed
yaml: |
---
items:
- { item: Super Hoop, quantity: 1 }
- [ Basketball, Big Shoes ]
php: |
array (
'items' => array (
array (
'item' => 'Super Hoop',
'quantity' => 1,
),
array (
'Basketball',
'Big Shoes'
)
)
)
---
test: Missing value for hash item
todo: true
brief: |
Third item in this hash doesn't have a value
yaml: |
okay: value
also okay: ~
causes error because no value specified
last key: value okay here too
python-error: causes error because no value specified
---
test: Not indenting enough
brief: |
There was a bug in PyYaml where it was off by one
in the indentation check. It was allowing the YAML
below.
# This is actually valid YAML now. Someone should tell showell.
yaml: |
foo:
firstline: 1
secondline: 2
php: |
array('foo' => null, 'firstline' => 1, 'secondline' => 2)
test: outside double quotes
yaml: |
\0 \ \a \b \n
php: |
"\\0 \\ \\a \\b \\n"
---
test: null
yaml: |
"\0"
php: |
"\x00"
---
test: bell
yaml: |
"\a"
php: |
"\x07"
---
test: backspace
yaml: |
"\b"
php: |
"\x08"
---
test: horizontal tab (1)
yaml: |
"\t"
php: |
"\x09"
---
test: horizontal tab (2)
yaml: |
"\ "
php: |
"\x09"
---
test: line feed
yaml: |
"\n"
php: |
"\x0a"
---
test: vertical tab
yaml: |
"\v"
php: |
"\x0b"
---
test: form feed
yaml: |
"\f"
php: |
"\x0c"
---
test: carriage return
yaml: |
"\r"
php: |
"\x0d"
---
test: escape
yaml: |
"\e"
php: |
"\x1b"
---
test: space
yaml: |
"\ "
php: |
"\x20"
---
test: slash
yaml: |
"\/"
php: |
"\x2f"
---
test: backslash
yaml: |
"\\"
php: |
"\\"
---
test: Unicode next line
yaml: |
"\N"
php: |
"\xc2\x85"
---
test: Unicode non-breaking space
yaml: |
"\_"
php: |
"\xc2\xa0"
---
test: Unicode line separator
yaml: |
"\L"
php: |
"\xe2\x80\xa8"
---
test: Unicode paragraph separator
yaml: |
"\P"
php: |
"\xe2\x80\xa9"
---
test: Escaped 8-bit Unicode
yaml: |
"\x42"
php: |
"B"
---
test: Escaped 16-bit Unicode
yaml: |
"\u20ac"
php: |
"\xe2\x82\xac"
---
test: Escaped 32-bit Unicode
yaml: |
"\U00000043"
php: |
"C"
---
test: Example 5.13 Escaped Characters
note: |
Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support
continuation of string across multiple lines? Keeping test here but disabled.
todo: true
yaml: |
"Fun with \\
\" \a \b \e \f \
\n \r \t \v \0 \
\ \_ \N \L \P \
\x41 \u0041 \U00000041"
php: |
"Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A"
---
test: Double quotes with a line feed
yaml: |
{ double: "some value\n \"some quoted string\" and 'some single quotes one'" }
php: |
array(
'double' => "some value\n \"some quoted string\" and 'some single quotes one'"
)
--- %YAML:1.0
test: Sequence of scalars
spec: 2.1
yaml: |
- Mark McGwire
- Sammy Sosa
- Ken Griffey
php: |
array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey')
---
test: Mapping of scalars to scalars
spec: 2.2
yaml: |
hr: 65
avg: 0.278
rbi: 147
php: |
array('hr' => 65, 'avg' => 0.278, 'rbi' => 147)
---
test: Mapping of scalars to sequences
spec: 2.3
yaml: |
american:
- Boston Red Sox
- Detroit Tigers
- New York Yankees
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves
php: |
array('american' =>
array( 'Boston Red Sox', 'Detroit Tigers',
'New York Yankees' ),
'national' =>
array( 'New York Mets', 'Chicago Cubs',
'Atlanta Braves' )
)
---
test: Sequence of mappings
spec: 2.4
yaml: |
-
name: Mark McGwire
hr: 65
avg: 0.278
-
name: Sammy Sosa
hr: 63
avg: 0.288
php: |
array(
array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278),
array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288)
)
---
test: Legacy A5
todo: true
spec: legacy_A5
yaml: |
?
- New York Yankees
- Atlanta Braves
:
- 2001-07-02
- 2001-08-12
- 2001-08-14
?
- Detroit Tigers
- Chicago Cubs
:
- 2001-07-23
perl-busted: >
YAML.pm will be able to emulate this behavior soon. In this regard
it may be somewhat more correct than Python's native behaviour which
can only use tuples as mapping keys. PyYAML will also need to figure
out some clever way to roundtrip structured keys.
python: |
[
{
('New York Yankees', 'Atlanta Braves'):
[yaml.timestamp('2001-07-02'),
yaml.timestamp('2001-08-12'),
yaml.timestamp('2001-08-14')],
('Detroit Tigers', 'Chicago Cubs'):
[yaml.timestamp('2001-07-23')]
}
]
ruby: |
{
[ 'New York Yankees', 'Atlanta Braves' ] =>
[ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ],
[ 'Detroit Tigers', 'Chicago Cubs' ] =>
[ Date.new( 2001, 7, 23 ) ]
}
syck: |
struct test_node seq1[] = {
{ T_STR, 0, "New York Yankees" },
{ T_STR, 0, "Atlanta Braves" },
end_node
};
struct test_node seq2[] = {
{ T_STR, 0, "2001-07-02" },
{ T_STR, 0, "2001-08-12" },
{ T_STR, 0, "2001-08-14" },
end_node
};
struct test_node seq3[] = {
{ T_STR, 0, "Detroit Tigers" },
{ T_STR, 0, "Chicago Cubs" },
end_node
};
struct test_node seq4[] = {
{ T_STR, 0, "2001-07-23" },
end_node
};
struct test_node map[] = {
{ T_SEQ, 0, 0, seq1 },
{ T_SEQ, 0, 0, seq2 },
{ T_SEQ, 0, 0, seq3 },
{ T_SEQ, 0, 0, seq4 },
end_node
};
struct test_node stream[] = {
{ T_MAP, 0, 0, map },
end_node
};
---
test: Sequence of sequences
spec: 2.5
yaml: |
- [ name , hr , avg ]
- [ Mark McGwire , 65 , 0.278 ]
- [ Sammy Sosa , 63 , 0.288 ]
php: |
array(
array( 'name', 'hr', 'avg' ),
array( 'Mark McGwire', 65, 0.278 ),
array( 'Sammy Sosa', 63, 0.288 )
)
---
test: Mapping of mappings
todo: true
spec: 2.6
yaml: |
Mark McGwire: {hr: 65, avg: 0.278}
Sammy Sosa: {
hr: 63,
avg: 0.288
}
php: |
array(
'Mark McGwire' =>
array( 'hr' => 65, 'avg' => 0.278 ),
'Sammy Sosa' =>
array( 'hr' => 63, 'avg' => 0.288 )
)
---
test: Two documents in a stream each with a leading comment
todo: true
spec: 2.7
yaml: |
# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey
# Team ranking
---
- Chicago Cubs
- St Louis Cardinals
ruby: |
y = YAML::Stream.new
y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] )
y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] )
documents: 2
---
test: Play by play feed from a game
todo: true
spec: 2.8
yaml: |
---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
...
---
time: 20:03:47
player: Sammy Sosa
action: grand slam
...
perl: |
[ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ]
documents: 2
---
test: Single document with two comments
spec: 2.9
yaml: |
hr: # 1998 hr ranking
- Mark McGwire
- Sammy Sosa
rbi:
# 1998 rbi ranking
- Sammy Sosa
- Ken Griffey
php: |
array(
'hr' => array( 'Mark McGwire', 'Sammy Sosa' ),
'rbi' => array( 'Sammy Sosa', 'Ken Griffey' )
)
---
test: Node for Sammy Sosa appears twice in this document
spec: 2.10
yaml: |
---
hr:
- Mark McGwire
# Following node labeled SS
- &SS Sammy Sosa
rbi:
- *SS # Subsequent occurance
- Ken Griffey
php: |
array(
'hr' =>
array('Mark McGwire', 'Sammy Sosa'),
'rbi' =>
array('Sammy Sosa', 'Ken Griffey')
)
---
test: Mapping between sequences
todo: true
spec: 2.11
yaml: |
? # PLAY SCHEDULE
- Detroit Tigers
- Chicago Cubs
:
- 2001-07-23
? [ New York Yankees,
Atlanta Braves ]
: [ 2001-07-02, 2001-08-12,
2001-08-14 ]
ruby: |
{
[ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
[ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ]
}
syck: |
struct test_node seq1[] = {
{ T_STR, 0, "New York Yankees" },
{ T_STR, 0, "Atlanta Braves" },
end_node
};
struct test_node seq2[] = {
{ T_STR, 0, "2001-07-02" },
{ T_STR, 0, "2001-08-12" },
{ T_STR, 0, "2001-08-14" },
end_node
};
struct test_node seq3[] = {
{ T_STR, 0, "Detroit Tigers" },
{ T_STR, 0, "Chicago Cubs" },
end_node
};
struct test_node seq4[] = {
{ T_STR, 0, "2001-07-23" },
end_node
};
struct test_node map[] = {
{ T_SEQ, 0, 0, seq3 },
{ T_SEQ, 0, 0, seq4 },
{ T_SEQ, 0, 0, seq1 },
{ T_SEQ, 0, 0, seq2 },
end_node
};
struct test_node stream[] = {
{ T_MAP, 0, 0, map },
end_node
};
---
test: Sequence key shortcut
spec: 2.12
yaml: |
---
# products purchased
- item : Super Hoop
quantity: 1
- item : Basketball
quantity: 4
- item : Big Shoes
quantity: 1
php: |
array (
array (
'item' => 'Super Hoop',
'quantity' => 1,
),
array (
'item' => 'Basketball',
'quantity' => 4,
),
array (
'item' => 'Big Shoes',
'quantity' => 1,
)
)
perl: |
[
{ item => 'Super Hoop', quantity => 1 },
{ item => 'Basketball', quantity => 4 },
{ item => 'Big Shoes', quantity => 1 }
]
ruby: |
[
{ 'item' => 'Super Hoop', 'quantity' => 1 },
{ 'item' => 'Basketball', 'quantity' => 4 },
{ 'item' => 'Big Shoes', 'quantity' => 1 }
]
python: |
[
{ 'item': 'Super Hoop', 'quantity': 1 },
{ 'item': 'Basketball', 'quantity': 4 },
{ 'item': 'Big Shoes', 'quantity': 1 }
]
syck: |
struct test_node map1[] = {
{ T_STR, 0, "item" },
{ T_STR, 0, "Super Hoop" },
{ T_STR, 0, "quantity" },
{ T_STR, 0, "1" },
end_node
};
struct test_node map2[] = {
{ T_STR, 0, "item" },
{ T_STR, 0, "Basketball" },
{ T_STR, 0, "quantity" },
{ T_STR, 0, "4" },
end_node
};
struct test_node map3[] = {
{ T_STR, 0, "item" },
{ T_STR, 0, "Big Shoes" },
{ T_STR, 0, "quantity" },
{ T_STR, 0, "1" },
end_node
};
struct test_node seq[] = {
{ T_MAP, 0, 0, map1 },
{ T_MAP, 0, 0, map2 },
{ T_MAP, 0, 0, map3 },
end_node
};
struct test_node stream[] = {
{ T_SEQ, 0, 0, seq },
end_node
};
---
test: Literal perserves newlines
todo: true
spec: 2.13
yaml: |
# ASCII Art
--- |
\//||\/||
// || ||_
perl: |
"\\//||\\/||\n// || ||_\n"
ruby: |
"\\//||\\/||\n// || ||_\n"
python: |
[
flushLeft(
"""
\//||\/||
// || ||_
"""
)
]
syck: |
struct test_node stream[] = {
{ T_STR, 0, "\\//||\\/||\n// || ||_\n" },
end_node
};
---
test: Folded treats newlines as a space
todo: true
spec: 2.14
yaml: |
---
Mark McGwire's
year was crippled
by a knee injury.
perl: |
"Mark McGwire's year was crippled by a knee injury."
ruby: |
"Mark McGwire's year was crippled by a knee injury."
python: |
[ "Mark McGwire's year was crippled by a knee injury." ]
syck: |
struct test_node stream[] = {
{ T_STR, 0, "Mark McGwire's year was crippled by a knee injury." },
end_node
};
---
test: Newlines preserved for indented and blank lines
todo: true
spec: 2.15
yaml: |
--- >
Sammy Sosa completed another
fine season with great stats.
63 Home Runs
0.288 Batting Average
What a year!
perl: |
"Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
ruby: |
"Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
python: |
[
flushLeft(
"""
Sammy Sosa completed another fine season with great stats.
63 Home Runs
0.288 Batting Average
What a year!
"""
)
]
syck: |
struct test_node stream[] = {
{ T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" },
end_node
};
---
test: Indentation determines scope
spec: 2.16
yaml: |
name: Mark McGwire
accomplishment: >
Mark set a major league
home run record in 1998.
stats: |
65 Home Runs
0.278 Batting Average
php: |
array(
'name' => 'Mark McGwire',
'accomplishment' => "Mark set a major league home run record in 1998.\n",
'stats' => "65 Home Runs\n0.278 Batting Average\n"
)
---
test: Quoted scalars
todo: true
spec: 2.17
yaml: |
unicode: "Sosa did fine.\u263A"
control: "\b1998\t1999\t2000\n"
hexesc: "\x0D\x0A is \r\n"
single: '"Howdy!" he cried.'
quoted: ' # not a ''comment''.'
tie-fighter: '|\-*-/|'
ruby: |
{
"tie-fighter" => "|\\-*-/|",
"control"=>"\0101998\t1999\t2000\n",
"unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'),
"quoted"=>" # not a 'comment'.",
"single"=>"\"Howdy!\" he cried.",
"hexesc"=>"\r\n is \r\n"
}
---
test: Multiline flow scalars
todo: true
spec: 2.18
yaml: |
plain:
This unquoted scalar
spans many lines.
quoted: "So does this
quoted scalar.\n"
ruby: |
{
'plain' => 'This unquoted scalar spans many lines.',
'quoted' => "So does this quoted scalar.\n"
}
---
test: Integers
spec: 2.19
yaml: |
canonical: 12345
decimal: +12,345
octal: 014
hexadecimal: 0xC
php: |
array(
'canonical' => 12345,
'decimal' => 12345,
'octal' => 014,
'hexadecimal' => 0xC
)
---
# FIX: spec shows parens around -inf and NaN
test: Floating point
spec: 2.20
yaml: |
canonical: 1.23015e+3
exponential: 12.3015e+02
fixed: 1,230.15
negative infinity: -.inf
not a number: .NaN
php: |
array(
'canonical' => 1230.15,
'exponential' => 1230.15,
'fixed' => 1230.15,
'negative infinity' => log(0),
'not a number' => -log(0),
)
---
test: Miscellaneous
spec: 2.21
yaml: |
null: ~
true: true
false: false
string: '12345'
php: |
array(
'' => null,
1 => true,
0 => false,
'string' => '12345'
)
---
test: Timestamps
todo: true
spec: 2.22
yaml: |
canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -05:00
date: 2002-12-14 # Time is noon UTC
php: |
array(
'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
'date' => Date.new( 2002, 12, 14 )
)
---
test: legacy Timestamps test
todo: true
spec: legacy D4
yaml: |
canonical: 2001-12-15T02:59:43.00Z
iso8601: 2001-02-28t21:59:43.00-05:00
spaced: 2001-12-14 21:59:43.00 -05:00
date: 2002-12-14
php: |
array(
'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ),
'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ),
'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ),
'date' => Date.new( 2002, 12, 14 )
)
---
test: Various explicit families
todo: true
spec: 2.23
yaml: |
not-date: !str 2002-04-28
picture: !binary |
R0lGODlhDAAMAIQAAP//9/X
17unp5WZmZgAAAOfn515eXv
Pz7Y6OjuDg4J+fn5OTk6enp
56enmleECcgggoBADs=
application specific tag: !!something |
The semantics of the tag
above may be different for
different documents.
ruby-setup: |
YAML.add_private_type( "something" ) do |type, val|
"SOMETHING: #{val}"
end
ruby: |
{
'not-date' => '2002-04-28',
'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;",
'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n"
}
---
test: Application specific family
todo: true
spec: 2.24
yaml: |
# Establish a tag prefix
--- !clarkevans.com,2002/graph/^shape
# Use the prefix: shorthand for
# !clarkevans.com,2002/graph/circle
- !^circle
center: &ORIGIN {x: 73, 'y': 129}
radius: 7
- !^line # !clarkevans.com,2002/graph/line
start: *ORIGIN
finish: { x: 89, 'y': 102 }
- !^label
start: *ORIGIN
color: 0xFFEEBB
value: Pretty vector drawing.
ruby-setup: |
YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
if Array === val
val << "Shape Container"
val
else
raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
end
}
one_shape_proc = Proc.new { |type, val|
scheme, domain, type = type.split( /:/, 3 )
if val.is_a? ::Hash
val['TYPE'] = "Shape: #{type}"
val
else
raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
end
}
YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc )
ruby: |
[
{
"radius" => 7,
"center"=>
{
"x" => 73,
"y" => 129
},
"TYPE" => "Shape: graph/circle"
}, {
"finish" =>
{
"x" => 89,
"y" => 102
},
"TYPE" => "Shape: graph/line",
"start" =>
{
"x" => 73,
"y" => 129
}
}, {
"TYPE" => "Shape: graph/label",
"value" => "Pretty vector drawing.",
"start" =>
{
"x" => 73,
"y" => 129
},
"color" => 16772795
},
"Shape Container"
]
# ---
# test: Unordered set
# spec: 2.25
# yaml: |
# # sets are represented as a
# # mapping where each key is
# # associated with the empty string
# --- !set
# ? Mark McGwire
# ? Sammy Sosa
# ? Ken Griff
---
test: Ordered mappings
todo: true
spec: 2.26
yaml: |
# ordered maps are represented as
# a sequence of mappings, with
# each mapping having one key
--- !omap
- Mark McGwire: 65
- Sammy Sosa: 63
- Ken Griffy: 58
ruby: |
YAML::Omap[
'Mark McGwire', 65,
'Sammy Sosa', 63,
'Ken Griffy', 58
]
---
test: Invoice
dump_skip: true
spec: 2.27
yaml: |
--- !clarkevans.com,2002/^invoice
invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
ship-to: *id001
product:
-
sku : BL394D
quantity : 4
description : Basketball
price : 450.00
-
sku : BL4438H
quantity : 1
description : Super Hoop
price : 2392.00
tax : 251.42
total: 4443.52
comments: >
Late afternoon is best.
Backup contact is Nancy
Billsmer @ 338-4338.
php: |
array(
'invoice' => 34843, 'date' => mktime(0, 0, 0, 1, 23, 2001),
'bill-to' =>
array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
, 'ship-to' =>
array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
, 'product' =>
array(
array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ),
array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 )
),
'tax' => 251.42, 'total' => 4443.52,
'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n"
)
---
test: Log file
todo: true
spec: 2.28
yaml: |
---
Time: 2001-11-23 15:01:42 -05:00
User: ed
Warning: >
This is an error message
for the log file
---
Time: 2001-11-23 15:02:31 -05:00
User: ed
Warning: >
A slightly different error
message.
---
Date: 2001-11-23 15:03:17 -05:00
User: ed
Fatal: >
Unknown variable "bar"
Stack:
- file: TopClass.py
line: 23
code: |
x = MoreObject("345\n")
- file: MoreClass.py
line: 58
code: |-
foo = bar
ruby: |
y = YAML::Stream.new
y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
'Stack' => [
{ 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
{ 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
documents: 3
---
test: Throwaway comments
yaml: |
### These are four throwaway comment ###
### lines (the second line is empty). ###
this: | # Comments may trail lines.
contains three lines of text.
The third one starts with a
# character. This isn't a comment.
# These are three throwaway comment
# lines (the first line is empty).
php: |
array(
'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"
)
---
test: Document with a single value
todo: true
yaml: |
--- >
This YAML stream contains a single text value.
The next stream is a log file - a sequence of
log entries. Adding an entry to the log is a
simple matter of appending it at the end.
ruby: |
"This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n"
---
test: Document stream
todo: true
yaml: |
---
at: 2001-08-12 09:25:00.00 Z
type: GET
HTTP: '1.0'
url: '/index.html'
---
at: 2001-08-12 09:25:10.00 Z
type: GET
HTTP: '1.0'
url: '/toc.html'
ruby: |
y = YAML::Stream.new
y.add( {
'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ),
'type' => 'GET',
'HTTP' => '1.0',
'url' => '/index.html'
} )
y.add( {
'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ),
'type' => 'GET',
'HTTP' => '1.0',
'url' => '/toc.html'
} )
documents: 2
---
test: Top level mapping
yaml: |
# This stream is an example of a top-level mapping.
invoice : 34843
date : 2001-01-23
total : 4443.52
php: |
array(
'invoice' => 34843,
'date' => mktime(0, 0, 0, 1, 23, 2001),
'total' => 4443.52
)
---
test: Single-line documents
todo: true
yaml: |
# The following is a sequence of three documents.
# The first contains an empty mapping, the second
# an empty sequence, and the last an empty string.
--- {}
--- [ ]
--- ''
ruby: |
y = YAML::Stream.new
y.add( {} )
y.add( [] )
y.add( '' )
documents: 3
---
test: Document with pause
todo: true
yaml: |
# A communication channel based on a YAML stream.
---
sent at: 2002-06-06 11:46:25.10 Z
payload: Whatever
# Receiver can process this as soon as the following is sent:
...
# Even if the next message is sent long after:
---
sent at: 2002-06-06 12:05:53.47 Z
payload: Whatever
...
ruby: |
y = YAML::Stream.new
y.add(
{ 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ),
'payload' => 'Whatever' }
)
y.add(
{ "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) }
)
documents: 2
---
test: Explicit typing
yaml: |
integer: 12
also int: ! "12"
string: !str 12
php: |
array( 'integer' => 12, 'also int' => 12, 'string' => '12' )
---
test: Private types
todo: true
yaml: |
# Both examples below make use of the 'x-private:ball'
# type family URI, but with different semantics.
---
pool: !!ball
number: 8
color: black
---
bearing: !!ball
material: steel
ruby: |
y = YAML::Stream.new
y.add( { 'pool' =>
YAML::PrivateType.new( 'ball',
{ 'number' => 8, 'color' => 'black' } ) }
)
y.add( { 'bearing' =>
YAML::PrivateType.new( 'ball',
{ 'material' => 'steel' } ) }
)
documents: 2
---
test: Type family under yaml.org
yaml: |
# The URI is 'tag:yaml.org,2002:str'
- !str a Unicode string
php: |
array( 'a Unicode string' )
---
test: Type family under perl.yaml.org
todo: true
yaml: |
# The URI is 'tag:perl.yaml.org,2002:Text::Tabs'
- !perl/Text::Tabs {}
ruby: |
[ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ]
---
test: Type family under clarkevans.com
todo: true
yaml: |
# The URI is 'tag:clarkevans.com,2003-02:timesheet'
- !clarkevans.com,2003-02/timesheet {}
ruby: |
[ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ]
---
test: URI Escaping
todo: true
yaml: |
same:
- !domain.tld,2002/type\x30 value
- !domain.tld,2002/type0 value
different: # As far as the YAML parser is concerned
- !domain.tld,2002/type%30 value
- !domain.tld,2002/type0 value
ruby-setup: |
YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
"ONE: #{val}"
}
YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
"TWO: #{val}"
}
ruby: |
{ 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] }
---
test: URI Prefixing
todo: true
yaml: |
# 'tag:domain.tld,2002:invoice' is some type family.
invoice: !domain.tld,2002/^invoice
# 'seq' is shorthand for 'tag:yaml.org,2002:seq'.
# This does not effect '^customer' below
# because it is does not specify a prefix.
customers: !seq
# '^customer' is shorthand for the full
# notation 'tag:domain.tld,2002:customer'.
- !^customer
given : Chris
family : Dumars
ruby-setup: |
YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val|
if val.is_a? ::Hash
scheme, domain, type = type.split( /:/, 3 )
val['type'] = "domain #{type}"
val
else
raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect
end
}
ruby: |
{ "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }
---
test: Overriding anchors
yaml: |
anchor : &A001 This scalar has an anchor.
override : &A001 >
The alias node below is a
repeated use of this value.
alias : *A001
php: |
array( 'anchor' => 'This scalar has an anchor.',
'override' => "The alias node below is a repeated use of this value.\n",
'alias' => "The alias node below is a repeated use of this value.\n" )
---
test: Flow and block formatting
todo: true
yaml: |
empty: []
flow: [ one, two, three # May span lines,
, four, # indentation is
five ] # mostly ignored.
block:
- First item in top sequence
-
- Subordinate sequence entry
- >
A folded sequence entry
- Sixth item in top sequence
ruby: |
{ 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ],
'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
"A folded sequence entry\n", 'Sixth item in top sequence' ] }
---
test: Complete mapping test
todo: true
yaml: |
empty: {}
flow: { one: 1, two: 2 }
spanning: { one: 1,
two: 2 }
block:
first : First entry
second:
key: Subordinate mapping
third:
- Subordinate sequence
- { }
- Previous mapping is empty.
- A key: value pair in a sequence.
A second: key:value pair.
- The previous entry is equal to the following one.
-
A key: value pair in a sequence.
A second: key:value pair.
!float 12 : This key is a float.
? >
?
: This key had to be protected.
"\a" : This key had to be escaped.
? >
This is a
multi-line
folded key
: Whose value is
also multi-line.
? this also works as a key
: with a value at the next line.
?
- This key
- is a sequence
:
- With a sequence value.
?
This: key
is a: mapping
:
with a: mapping value.
ruby: |
{ 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 },
'spanning' => { 'one' => 1, 'two' => 2 },
'block' => { 'first' => 'First entry', 'second' =>
{ 'key' => 'Subordinate mapping' }, 'third' =>
[ 'Subordinate sequence', {}, 'Previous mapping is empty.',
{ 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
'The previous entry is equal to the following one.',
{ 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
"\a" => 'This key had to be escaped.',
"This is a multi-line folded key\n" => "Whose value is also multi-line.",
'this also works as a key' => 'with a value at the next line.',
[ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }
# Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact
obj_y['block'].keys.each { |k|
if Hash === k
v = obj_y['block'][k]
if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.'
obj_r['block'][k] = v
end
end
}
---
test: Literal explicit indentation
yaml: |
# Explicit indentation must
# be given in all the three
# following cases.
leading spaces: |2
This value starts with four spaces.
leading line break: |2
This value starts with a line break.
leading comment indicator: |2
# first line starts with a
# character.
# Explicit indentation may
# also be given when it is
# not required.
redundant: |2
This value is indented 2 spaces.
php: |
array(
'leading spaces' => " This value starts with four spaces.\n",
'leading line break' => "\nThis value starts with a line break.\n",
'leading comment indicator' => "# first line starts with a\n# character.\n",
'redundant' => "This value is indented 2 spaces.\n"
)
---
test: Chomping and keep modifiers
yaml: |
clipped: |
This has one newline.
same as "clipped" above: "This has one newline.\n"
stripped: |-
This has no newline.
same as "stripped" above: "This has no newline."
kept: |+
This has two newlines.
same as "kept" above: "This has two newlines.\n\n"
php: |
array(
'clipped' => "This has one newline.\n",
'same as "clipped" above' => "This has one newline.\n",
'stripped' => 'This has no newline.',
'same as "stripped" above' => 'This has no newline.',
'kept' => "This has two newlines.\n\n",
'same as "kept" above' => "This has two newlines.\n\n"
)
---
test: Literal combinations
todo: true
yaml: |
empty: |
literal: |
The \ ' " characters may be
freely used. Leading white
space is significant.
Line breaks are significant.
Thus this value contains one
empty line and ends with a
single line break, but does
not start with one.
is equal to: "The \\ ' \" characters may \
be\nfreely used. Leading white\n space \
is significant.\n\nLine breaks are \
significant.\nThus this value contains \
one\nempty line and ends with a\nsingle \
line break, but does\nnot start with one.\n"
# Comments may follow a block
# scalar value. They must be
# less indented.
# Modifiers may be combined in any order.
indented and chomped: |2-
This has no newline.
also written as: |-2
This has no newline.
both are equal to: " This has no newline."
php: |
array(
'empty' => '',
'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
"is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
"empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
"is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
"empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
'indented and chomped' => ' This has no newline.',
'also written as' => ' This has no newline.',
'both are equal to' => ' This has no newline.'
)
---
test: Folded combinations
todo: true
yaml: |
empty: >
one paragraph: >
Line feeds are converted
to spaces, so this value
contains no line breaks
except for the final one.
multiple paragraphs: >2
An empty line, either
at the start or in
the value:
Is interpreted as a
line break. Thus this
value contains three
line breaks.
indented text: >
This is a folded
paragraph followed
by a list:
* first entry
* second entry
Followed by another
folded paragraph,
another list:
* first entry
* second entry
And a final folded
paragraph.
above is equal to: |
This is a folded paragraph followed by a list:
* first entry
* second entry
Followed by another folded paragraph, another list:
* first entry
* second entry
And a final folded paragraph.
# Explicit comments may follow
# but must be less indented.
php: |
array(
'empty' => '',
'one paragraph' => 'Line feeds are converted to spaces, so this value'.
" contains no line breaks except for the final one.\n",
'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n".
"Is interpreted as a line break. Thus this value contains three line breaks.\n",
'indented text' => "This is a folded paragraph followed by a list:\n".
" * first entry\n * second entry\nFollowed by another folded paragraph, ".
"another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n",
'above is equal to' => "This is a folded paragraph followed by a list:\n".
" * first entry\n * second entry\nFollowed by another folded paragraph, ".
"another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n"
)
---
test: Single quotes
todo: true
yaml: |
empty: ''
second: '! : \ etc. can be used freely.'
third: 'a single quote '' must be escaped.'
span: 'this contains
six spaces
and one
line break'
is same as: "this contains six spaces\nand one line break"
php: |
array(
'empty' => '',
'second' => '! : \\ etc. can be used freely.',
'third' => "a single quote ' must be escaped.",
'span' => "this contains six spaces\nand one line break",
'is same as' => "this contains six spaces\nand one line break"
)
---
test: Double quotes
todo: true
yaml: |
empty: ""
second: "! : etc. can be used freely."
third: "a \" or a \\ must be escaped."
fourth: "this value ends with an LF.\n"
span: "this contains
four \
spaces"
is equal to: "this contains four spaces"
php: |
array(
'empty' => '',
'second' => '! : etc. can be used freely.',
'third' => 'a " or a \\ must be escaped.',
'fourth' => "this value ends with an LF.\n",
'span' => "this contains four spaces",
'is equal to' => "this contains four spaces"
)
---
test: Unquoted strings
todo: true
yaml: |
first: There is no unquoted empty string.
second: 12 ## This is an integer.
third: !str 12 ## This is a string.
span: this contains
six spaces
and one
line break
indicators: this has no comments.
#:foo and bar# are
both text.
flow: [ can span
lines, # comment
like
this ]
note: { one-line keys: but multi-line values }
php: |
array(
'first' => 'There is no unquoted empty string.',
'second' => 12,
'third' => '12',
'span' => "this contains six spaces\nand one line break",
'indicators' => "this has no comments. #:foo and bar# are both text.",
'flow' => [ 'can span lines', 'like this' ],
'note' => { 'one-line keys' => 'but multi-line values' }
)
---
test: Spanning sequences
todo: true
yaml: |
# The following are equal seqs
# with different identities.
flow: [ one, two ]
spanning: [ one,
two ]
block:
- one
- two
php: |
array(
'flow' => [ 'one', 'two' ],
'spanning' => [ 'one', 'two' ],
'block' => [ 'one', 'two' ]
)
---
test: Flow mappings
yaml: |
# The following are equal maps
# with different identities.
flow: { one: 1, two: 2 }
block:
one: 1
two: 2
php: |
array(
'flow' => array( 'one' => 1, 'two' => 2 ),
'block' => array( 'one' => 1, 'two' => 2 )
)
---
test: Representations of 12
todo: true
yaml: |
- 12 # An integer
# The following scalars
# are loaded to the
# string value '1' '2'.
- !str 12
- '12'
- "12"
- "\
1\
2\
"
# Strings containing paths and regexps can be unquoted:
- /foo/bar
- d:/foo/bar
- foo/bar
- /a.*b/
php: |
array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' )
---
test: "Null"
todo: true
yaml: |
canonical: ~
english: null
# This sequence has five
# entries, two with values.
sparse:
- ~
- 2nd entry
- Null
- 4th entry
-
four: This mapping has five keys,
only two with values.
php: |
array (
'canonical' => null,
'english' => null,
'sparse' => array( null, '2nd entry', null, '4th entry', null ]),
'four' => 'This mapping has five keys, only two with values.'
)
---
test: Omap
todo: true
yaml: |
# Explicitly typed dictionary.
Bestiary: !omap
- aardvark: African pig-like ant eater. Ugly.
- anteater: South-American ant eater. Two species.
- anaconda: South-American constrictor snake. Scary.
# Etc.
ruby: |
{
'Bestiary' => YAML::Omap[
'aardvark', 'African pig-like ant eater. Ugly.',
'anteater', 'South-American ant eater. Two species.',
'anaconda', 'South-American constrictor snake. Scary.'
]
}
---
test: Pairs
todo: true
yaml: |
# Explicitly typed pairs.
tasks: !pairs
- meeting: with team.
- meeting: with boss.
- break: lunch.
- meeting: with client.
ruby: |
{
'tasks' => YAML::Pairs[
'meeting', 'with team.',
'meeting', 'with boss.',
'break', 'lunch.',
'meeting', 'with client.'
]
}
---
test: Set
todo: true
yaml: |
# Explicitly typed set.
baseball players: !set
Mark McGwire:
Sammy Sosa:
Ken Griffey:
ruby: |
{
'baseball players' => YAML::Set[
'Mark McGwire', nil,
'Sammy Sosa', nil,
'Ken Griffey', nil
]
}
---
test: Boolean
yaml: |
false: used as key
logical: true
answer: false
php: |
array(
false => 'used as key',
'logical' => true,
'answer' => false
)
---
test: Integer
yaml: |
canonical: 12345
decimal: +12,345
octal: 014
hexadecimal: 0xC
php: |
array(
'canonical' => 12345,
'decimal' => 12345,
'octal' => 12,
'hexadecimal' => 12
)
---
test: Float
yaml: |
canonical: 1.23015e+3
exponential: 12.3015e+02
fixed: 1,230.15
negative infinity: -.inf
not a number: .NaN
php: |
array(
'canonical' => 1230.15,
'exponential' => 1230.15,
'fixed' => 1230.15,
'negative infinity' => log(0),
'not a number' => -log(0)
)
---
test: Timestamp
todo: true
yaml: |
canonical: 2001-12-15T02:59:43.1Z
valid iso8601: 2001-12-14t21:59:43.10-05:00
space separated: 2001-12-14 21:59:43.10 -05:00
date (noon UTC): 2002-12-14
ruby: |
array(
'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
'date (noon UTC)' => Date.new( 2002, 12, 14 )
)
---
test: Binary
todo: true
yaml: |
canonical: !binary "\
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
base64: !binary |
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
description: >
The binary value above is a tiny arrow
encoded as a gif image.
ruby-setup: |
arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
ruby: |
{
'canonical' => arrow_gif,
'base64' => arrow_gif,
'description' => "The binary value above is a tiny arrow encoded as a gif image.\n"
}
---
test: Merge key
todo: true
yaml: |
---
- &CENTER { x: 1, y: 2 }
- &LEFT { x: 0, y: 2 }
- &BIG { r: 10 }
- &SMALL { r: 1 }
# All the following maps are equal:
- # Explicit keys
x: 1
y: 2
r: 10
label: center/big
- # Merge one map
<< : *CENTER
r: 10
label: center/big
- # Merge multiple maps
<< : [ *CENTER, *BIG ]
label: center/big
- # Override
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big
ruby-setup: |
center = { 'x' => 1, 'y' => 2 }
left = { 'x' => 0, 'y' => 2 }
big = { 'r' => 10 }
small = { 'r' => 1 }
node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' }
node2 = center.dup
node2.update( { 'r' => 10, 'label' => 'center/big' } )
node3 = big.dup
node3.update( center )
node3.update( { 'label' => 'center/big' } )
node4 = small.dup
node4.update( left )
node4.update( big )
node4.update( { 'x' => 1, 'label' => 'center/big' } )
ruby: |
[
center, left, big, small, node1, node2, node3, node4
]
---
test: Default key
todo: true
yaml: |
--- # Old schema
link with:
- library1.dll
- library2.dll
--- # New schema
link with:
- = : library1.dll
version: 1.2
- = : library2.dll
version: 2.3
ruby: |
y = YAML::Stream.new
y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } )
obj_h = Hash[ 'version' => 1.2 ]
obj_h.default = 'library1.dll'
obj_h2 = Hash[ 'version' => 2.3 ]
obj_h2.default = 'library2.dll'
y.add( { 'link with' => [ obj_h, obj_h2 ] } )
documents: 2
---
test: Special keys
todo: true
yaml: |
"!": These three keys
"&": had to be quoted
"=": and are normal strings.
# NOTE: the following node should NOT be serialized this way.
encoded node :
!special '!' : '!type'
!special|canonical '&' : 12
= : value
# The proper way to serialize the above node is as follows:
node : !!type &12 value
ruby: |
{ '!' => 'These three keys', '&' => 'had to be quoted',
'=' => 'and are normal strings.',
'encoded node' => YAML::PrivateType.new( 'type', 'value' ),
'node' => YAML::PrivateType.new( 'type', 'value' ) }
--- %YAML:1.0
test: Simple Sequence
brief: |
You can specify a list in YAML by placing each
member of the list on a new line with an opening
dash. These lists are called sequences.
yaml: |
- apple
- banana
- carrot
php: |
array('apple', 'banana', 'carrot')
---
test: Nested Sequences
brief: |
You can include a sequence within another
sequence by giving the sequence an empty
dash, followed by an indented list.
yaml: |
-
- foo
- bar
- baz
php: |
array(array('foo', 'bar', 'baz'))
---
test: Mixed Sequences
brief: |
Sequences can contain any YAML data,
including strings and other sequences.
yaml: |
- apple
-
- foo
- bar
- x123
- banana
- carrot
php: |
array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot')
---
test: Deeply Nested Sequences
brief: |
Sequences can be nested even deeper, with each
level of indentation representing a level of
depth.
yaml: |
-
-
- uno
- dos
php: |
array(array(array('uno', 'dos')))
---
test: Simple Mapping
brief: |
You can add a keyed list (also known as a dictionary or
hash) to your document by placing each member of the
list on a new line, with a colon seperating the key
from its value. In YAML, this type of list is called
a mapping.
yaml: |
foo: whatever
bar: stuff
php: |
array('foo' => 'whatever', 'bar' => 'stuff')
---
test: Sequence in a Mapping
brief: |
A value in a mapping can be a sequence.
yaml: |
foo: whatever
bar:
- uno
- dos
php: |
array('foo' => 'whatever', 'bar' => array('uno', 'dos'))
---
test: Nested Mappings
brief: |
A value in a mapping can be another mapping.
yaml: |
foo: whatever
bar:
fruit: apple
name: steve
sport: baseball
php: |
array(
'foo' => 'whatever',
'bar' => array(
'fruit' => 'apple',
'name' => 'steve',
'sport' => 'baseball'
)
)
---
test: Mixed Mapping
brief: |
A mapping can contain any assortment
of mappings and sequences as values.
yaml: |
foo: whatever
bar:
-
fruit: apple
name: steve
sport: baseball
- more
-
python: rocks
perl: papers
ruby: scissorses
php: |
array(
'foo' => 'whatever',
'bar' => array(
array(
'fruit' => 'apple',
'name' => 'steve',
'sport' => 'baseball'
),
'more',
array(
'python' => 'rocks',
'perl' => 'papers',
'ruby' => 'scissorses'
)
)
)
---
test: Mapping-in-Sequence Shortcut
todo: true
brief: |
If you are adding a mapping to a sequence, you
can place the mapping on the same line as the
dash as a shortcut.
yaml: |
- work on YAML.py:
- work on Store
php: |
array(array('work on YAML.py' => array('work on Store')))
---
test: Sequence-in-Mapping Shortcut
todo: true
brief: |
The dash in a sequence counts as indentation, so
you can add a sequence inside of a mapping without
needing spaces as indentation.
yaml: |
allow:
- 'localhost'
- '%.sourceforge.net'
- '%.freepan.org'
php: |
array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org'))
---
todo: true
test: Merge key
brief: |
A merge key ('<<') can be used in a mapping to insert other mappings. If
the value associated with the merge key is a mapping, each of its key/value
pairs is inserted into the current mapping.
yaml: |
mapping:
name: Joe
job: Accountant
<<:
age: 38
php: |
array(
'mapping' =>
array(
'name' => 'Joe',
'job' => 'Accountant',
'age' => 38
)
)
---
test: Simple Inline Array
brief: >
Sequences can be contained on a
single line, using the inline syntax.
Separate each entry with commas and
enclose in square brackets.
yaml: |
seq: [ a, b, c ]
php: |
array('seq' => array('a', 'b', 'c'))
---
test: Simple Inline Hash
brief: >
Mapping can also be contained on
a single line, using the inline
syntax. Each key-value pair is
separated by a colon, with a comma
between each entry in the mapping.
Enclose with curly braces.
yaml: |
hash: { name: Steve, foo: bar }
php: |
array('hash' => array('name' => 'Steve', 'foo' => 'bar'))
---
test: Multi-line Inline Collections
todo: true
brief: >
Both inline sequences and inline mappings
can span multiple lines, provided that you
indent the additional lines.
yaml: |
languages: [ Ruby,
Perl,
Python ]
websites: { YAML: yaml.org,
Ruby: ruby-lang.org,
Python: python.org,
Perl: use.perl.org }
php: |
array(
'languages' => array('Ruby', 'Perl', 'Python'),
'websites' => array(
'YAML' => 'yaml.org',
'Ruby' => 'ruby-lang.org',
'Python' => 'python.org',
'Perl' => 'use.perl.org'
)
)
---
test: Commas in Values (not in the spec!)
todo: true
brief: >
List items in collections are delimited by commas, but
there must be a space after each comma. This allows you
to add numbers without quoting.
yaml: |
attendances: [ 45,123, 70,000, 17,222 ]
php: |
array('attendances' => array(45123, 70000, 17222))
value: <?php echo 1 + 2 + 3 ?>
--- %YAML:1.0
test: Comments at the end of a line
brief: >
Comments at the end of a line
yaml: |
ex1: "foo # bar"
ex2: "foo # bar" # comment
ex3: 'foo # bar' # comment
ex4: foo # comment
php: |
array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
---
test: Comments in the middle
brief: >
Comments in the middle
yaml: |
foo:
# some comment
# some comment
bar: foo
# some comment
# some comment
php: |
array('foo' => array('bar' => 'foo'))
---
test: Comments on a hash line
brief: >
Comments on a hash line
yaml: |
foo: # a comment
foo: bar # a comment
php: |
array('foo' => array('foo' => 'bar'))
---
test: 'Value starting with a #'
brief: >
'Value starting with a #'
yaml: |
foo: '#bar'
php: |
array('foo' => '#bar')
---
test: Document starting with a comment and a separator
brief: >
Commenting before document start is allowed
yaml: |
# document comment
---
foo: bar # a comment
php: |
array('foo' => 'bar')
--- %YAML:1.0
test: Strings
brief: >
Any group of characters beginning with an
alphabetic or numeric character is a string,
unless it belongs to one of the groups below
(such as an Integer or Time).
yaml: |
String
php: |
'String'
---
test: String characters
brief: >
A string can contain any alphabetic or
numeric character, along with many
punctuation characters, including the
period, dash, space, quotes, exclamation, and
question mark.
yaml: |
- What's Yaml?
- It's for writing data structures in plain text.
- And?
- And what? That's not good enough for you?
- No, I mean, "And what about Yaml?"
- Oh, oh yeah. Uh.. Yaml for Ruby.
php: |
array(
"What's Yaml?",
"It's for writing data structures in plain text.",
"And?",
"And what? That's not good enough for you?",
"No, I mean, \"And what about Yaml?\"",
"Oh, oh yeah. Uh.. Yaml for Ruby."
)
---
test: Indicators in Strings
brief: >
Be careful using indicators in strings. In particular,
the comma, colon, and pound sign must be used carefully.
yaml: |
the colon followed by space is an indicator: but is a string:right here
same for the pound sign: here we have it#in a string
the comma can, honestly, be used in most cases: [ but not in, inline collections ]
php: |
array(
'the colon followed by space is an indicator' => 'but is a string:right here',
'same for the pound sign' => 'here we have it#in a string',
'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections')
)
---
test: Forcing Strings
brief: >
Any YAML type can be forced into a string using the
explicit !str method.
yaml: |
date string: !str 2001-08-01
number string: !str 192
php: |
array(
'date string' => '2001-08-01',
'number string' => '192'
)
---
test: Single-quoted Strings
brief: >
You can also enclose your strings within single quotes,
which allows use of slashes, colons, and other indicators
freely. Inside single quotes, you can represent a single
quote in your string by using two single quotes next to
each other.
yaml: |
all my favorite symbols: '#:!/%.)'
a few i hate: '&(*'
why do i hate them?: 'it''s very hard to explain'
entities: '&pound; me'
php: |
array(
'all my favorite symbols' => '#:!/%.)',
'a few i hate' => '&(*',
'why do i hate them?' => 'it\'s very hard to explain',
'entities' => '&pound; me'
)
---
test: Double-quoted Strings
brief: >
Enclosing strings in double quotes allows you
to use escapings to represent ASCII and
Unicode characters.
yaml: |
i know where i want my line breaks: "one here\nand another here\n"
php: |
array(
'i know where i want my line breaks' => "one here\nand another here\n"
)
---
test: Multi-line Quoted Strings
todo: true
brief: >
Both single- and double-quoted strings may be
carried on to new lines in your YAML document.
They must be indented a step and indentation
is interpreted as a single space.
yaml: |
i want a long string: "so i'm going to
let it go on and on to other lines
until i end it with a quote."
php: |
array('i want a long string' => "so i'm going to ".
"let it go on and on to other lines ".
"until i end it with a quote."
)
---
test: Plain scalars
todo: true
brief: >
Unquoted strings may also span multiple lines, if they
are free of YAML space indicators and indented.
yaml: |
- My little toe is broken in two places;
- I'm crazy to have skied this way;
- I'm not the craziest he's seen, since there was always the German guy
who skied for 3 hours on a broken shin bone (just below the kneecap);
- Nevertheless, second place is respectable, and he doesn't
recommend going for the record;
- He's going to put my foot in plaster for a month;
- This would impair my skiing ability somewhat for the
duration, as can be imagined.
php: |
array(
"My little toe is broken in two places;",
"I'm crazy to have skied this way;",
"I'm not the craziest he's seen, since there was always ".
"the German guy who skied for 3 hours on a broken shin ".
"bone (just below the kneecap);",
"Nevertheless, second place is respectable, and he doesn't ".
"recommend going for the record;",
"He's going to put my foot in plaster for a month;",
"This would impair my skiing ability somewhat for the duration, ".
"as can be imagined."
)
---
test: 'Null'
brief: >
You can use the tilde '~' character for a null value.
yaml: |
name: Mr. Show
hosted by: Bob and David
date of next season: ~
php: |
array(
'name' => 'Mr. Show',
'hosted by' => 'Bob and David',
'date of next season' => null
)
---
test: Boolean
brief: >
You can use 'true' and 'false' for Boolean values.
yaml: |
Is Gus a Liar?: true
Do I rely on Gus for Sustenance?: false
php: |
array(
'Is Gus a Liar?' => true,
'Do I rely on Gus for Sustenance?' => false
)
---
test: Integers
dump_skip: true
brief: >
An integer is a series of numbers, optionally
starting with a positive or negative sign. Integers
may also contain commas for readability.
yaml: |
zero: 0
simple: 12
one-thousand: 1,000
negative one-thousand: -1,000
php: |
array(
'zero' => 0,
'simple' => 12,
'one-thousand' => 1000,
'negative one-thousand' => -1000
)
---
test: Integers as Map Keys
brief: >
An integer can be used a dictionary key.
yaml: |
1: one
2: two
3: three
php: |
array(
1 => 'one',
2 => 'two',
3 => 'three'
)
---
test: Floats
dump_skip: true
brief: >
Floats are represented by numbers with decimals,
allowing for scientific notation, as well as
positive and negative infinity and "not a number."
yaml: |
a simple float: 2.00
larger float: 1,000.09
scientific notation: 1.00009e+3
php: |
array(
'a simple float' => 2.0,
'larger float' => 1000.09,
'scientific notation' => 1000.09
)
---
test: Time
todo: true
brief: >
You can represent timestamps by using
ISO8601 format, or a variation which
allows spaces between the date, time and
time zone.
yaml: |
iso8601: 2001-12-14t21:59:43.10-05:00
space seperated: 2001-12-14 21:59:43.10 -05:00
php: |
array(
'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
'space seperated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" )
)
---
test: Date
todo: true
brief: >
A date can be represented by its year,
month and day in ISO8601 order.
yaml: |
1976-07-31
php: |
date( 1976, 7, 31 )
---
test: One Element Mapping
brief: |
A mapping with one key/value pair
yaml: |
foo: bar
php: |
array('foo' => 'bar')
---
test: Multi Element Mapping
brief: |
More than one key/value pair
yaml: |
red: baron
white: walls
blue: berries
php: |
array(
'red' => 'baron',
'white' => 'walls',
'blue' => 'berries',
)
---
test: Values aligned
brief: |
Often times human editors of documents will align the values even
though YAML emitters generally don't.
yaml: |
red: baron
white: walls
blue: berries
php: |
array(
'red' => 'baron',
'white' => 'walls',
'blue' => 'berries',
)
---
test: Colons aligned
brief: |
Spaces can come before the ': ' key/value separator.
yaml: |
red : baron
white : walls
blue : berries
php: |
array(
'red' => 'baron',
'white' => 'walls',
'blue' => 'berries',
)
--- %YAML:1.0
test: Simple Alias Example
brief: >
If you need to refer to the same item of data twice,
you can give that item an alias. The alias is a plain
string, starting with an ampersand. The item may then
be referred to by the alias throughout your document
by using an asterisk before the name of the alias.
This is called an anchor.
yaml: |
- &showell Steve
- Clark
- Brian
- Oren
- *showell
php: |
array('Steve', 'Clark', 'Brian', 'Oren', 'Steve')
---
test: Alias of a Mapping
brief: >
An alias can be used on any item of data, including
sequences, mappings, and other complex data types.
yaml: |
- &hello
Meat: pork
Starch: potato
- banana
- *hello
php: |
array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato'))
--- %YAML:1.0
test: Simple In Place Substitution
brief: >
If you want to reuse an entire alias, only overwriting what is different
you can use a << in place substitution. This is not part of the official
YAML spec, but a widely implemented extension. See the following URL for
details: http://yaml.org/type/merge.html
yaml: |
foo: &foo
a: Steve
b: Clark
c: Brian
bar: &bar
<<: *foo
x: Oren
foo2: &foo2
a: Ballmer
ding: &dong [ fi, fei, fo, fam]
check:
<<:
- *foo
- *dong
isit: tested
head:
<<: [ *foo , *dong , *foo2 ]
php: |
array('foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'), 'bar' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'x' => 'Oren'), 'foo2' => array('a' => 'Ballmer'), 'ding' => array('fi', 'fei', 'fo', 'fam'), 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'), 'head' => array('a' => 'Ballmer', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam'))
--- %YAML:1.0
test: Trailing Document Separator
todo: true
brief: >
You can separate YAML documents
with a string of three dashes.
yaml: |
- foo: 1
bar: 2
---
more: stuff
python: |
[
[ { 'foo': 1, 'bar': 2 } ],
{ 'more': 'stuff' }
]
ruby: |
[ { 'foo' => 1, 'bar' => 2 } ]
---
test: Leading Document Separator
todo: true
brief: >
You can explicity give an opening
document separator to your YAML stream.
yaml: |
---
- foo: 1
bar: 2
---
more: stuff
python: |
[
[ {'foo': 1, 'bar': 2}],
{'more': 'stuff'}
]
ruby: |
[ { 'foo' => 1, 'bar' => 2 } ]
---
test: YAML Header
todo: true
brief: >
The opening separator can contain directives
to the YAML parser, such as the version
number.
yaml: |
--- %YAML:1.0
foo: 1
bar: 2
php: |
array('foo' => 1, 'bar' => 2)
documents: 1
---
test: Red Herring Document Separator
brief: >
Separators included in blocks or strings
are treated as blocks or strings, as the
document separator should have no indentation
preceding it.
yaml: |
foo: |
---
php: |
array('foo' => "---\n")
---
test: Multiple Document Separators in Block
brief: >
This technique allows you to embed other YAML
documents within literal blocks.
yaml: |
foo: |
---
foo: bar
---
yo: baz
bar: |
fooness
php: |
array(
'foo' => "---\nfoo: bar\n---\nyo: baz\n",
'bar' => "fooness\n"
)
--- %YAML:1.0
test: Some characters at the beginning of a string must be escaped
brief: >
Some characters at the beginning of a string must be escaped
yaml: |
foo: | bar
php: |
array('foo' => '| bar')
---
test: A key can be a quoted string
brief: >
A key can be a quoted string
yaml: |
"foo1": bar
'foo2': bar
"foo \" bar": bar
'foo '' bar': bar
'foo3: ': bar
"foo4: ": bar
foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar }
php: |
array(
'foo1' => 'bar',
'foo2' => 'bar',
'foo " bar' => 'bar',
'foo \' bar' => 'bar',
'foo3: ' => 'bar',
'foo4: ' => 'bar',
'foo5' => array(
'foo " bar: ' => 'bar',
'foo \' bar: ' => 'bar',
),
)
- escapedCharacters
- sfComments
- sfCompact
- sfTests
- sfObjects
- sfMergeKey
- sfQuotes
- YtsAnchorAlias
- YtsBasicTests
- YtsBlockMapping
- YtsDocumentSeparator
- YtsErrorTests
- YtsFlowCollections
- YtsFoldedScalars
- YtsNullsAndEmpties
- YtsSpecificationExamples
- YtsTypeTransfers
- unindentedCollections
--- %YAML:1.0
test: Single ending newline
brief: >
A pipe character, followed by an indented
block of text is treated as a literal
block, in which newlines are preserved
throughout the block, including the final
newline.
yaml: |
---
this: |
Foo
Bar
php: |
array('this' => "Foo\nBar\n")
---
test: The '+' indicator
brief: >
The '+' indicator says to keep newlines at the end of text
blocks.
yaml: |
normal: |
extra new lines not kept
preserving: |+
extra new lines are kept
dummy: value
php: |
array(
'normal' => "extra new lines not kept\n",
'preserving' => "extra new lines are kept\n\n\n",
'dummy' => 'value'
)
---
test: Three trailing newlines in literals
brief: >
To give you more control over how space
is preserved in text blocks, YAML has
the keep '+' and chomp '-' indicators.
The keep indicator will preserve all
ending newlines, while the chomp indicator
will strip all ending newlines.
yaml: |
clipped: |
This has one newline.
same as "clipped" above: "This has one newline.\n"
stripped: |-
This has no newline.
same as "stripped" above: "This has no newline."
kept: |+
This has four newlines.
same as "kept" above: "This has four newlines.\n\n\n\n"
php: |
array(
'clipped' => "This has one newline.\n",
'same as "clipped" above' => "This has one newline.\n",
'stripped' => 'This has no newline.',
'same as "stripped" above' => 'This has no newline.',
'kept' => "This has four newlines.\n\n\n\n",
'same as "kept" above' => "This has four newlines.\n\n\n\n"
)
---
test: Extra trailing newlines with spaces
todo: true
brief: >
Normally, only a single newline is kept
from the end of a literal block, unless the
keep '+' character is used in combination
with the pipe. The following example
will preserve all ending whitespace
since the last line of both literal blocks
contains spaces which extend past the indentation
level.
yaml: |
---
this: |
Foo
kept: |+
Foo
php: |
array('this' => "Foo\n\n \n",
'kept' => "Foo\n\n \n" )
---
test: Folded Block in a Sequence
brief: >
A greater-then character, followed by an indented
block of text is treated as a folded block, in
which lines of text separated by a single newline
are concatenated as a single line.
yaml: |
---
- apple
- banana
- >
can't you see
the beauty of yaml?
hmm
- dog
php: |
array(
'apple',
'banana',
"can't you see the beauty of yaml? hmm\n",
'dog'
)
---
test: Folded Block as a Mapping Value
brief: >
Both literal and folded blocks can be
used in collections, as values in a
sequence or a mapping.
yaml: |
---
quote: >
Mark McGwire's
year was crippled
by a knee injury.
source: espn
php: |
array(
'quote' => "Mark McGwire's year was crippled by a knee injury.\n",
'source' => 'espn'
)
---
test: Three trailing newlines in folded blocks
brief: >
The keep and chomp indicators can also
be applied to folded blocks.
yaml: |
clipped: >
This has one newline.
same as "clipped" above: "This has one newline.\n"
stripped: >-
This has no newline.
same as "stripped" above: "This has no newline."
kept: >+
This has four newlines.
same as "kept" above: "This has four newlines.\n\n\n\n"
php: |
array(
'clipped' => "This has one newline.\n",
'same as "clipped" above' => "This has one newline.\n",
'stripped' => 'This has no newline.',
'same as "stripped" above' => 'This has no newline.',
'kept' => "This has four newlines.\n\n\n\n",
'same as "kept" above' => "This has four newlines.\n\n\n\n"
)
--- %YAML:1.0
test: Unindented collection
brief: >
Unindented collection
yaml: |
collection:
- item1
- item2
- item3
php: |
array('collection' => array('item1', 'item2', 'item3'))
---
test: Nested unindented collection (two levels)
brief: >
Nested unindented collection
yaml: |
collection:
key:
- a
- b
- c
php: |
array('collection' => array('key' => array('a', 'b', 'c')))
---
test: Nested unindented collection (three levels)
brief: >
Nested unindented collection
yaml: |
collection:
key:
subkey:
- one
- two
- three
php: |
array('collection' => array('key' => array('subkey' => array('one', 'two', 'three'))))
---
test: Key/value after unindented collection (1)
brief: >
Key/value after unindented collection (1)
yaml: |
collection:
key:
- a
- b
- c
foo: bar
php: |
array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar')
---
test: Key/value after unindented collection (at the same level)
brief: >
Key/value after unindented collection
yaml: |
collection:
key:
- a
- b
- c
foo: bar
php: |
array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar'))
{
"name": "symfony/yaml",
"type": "library",
"description": "Symfony Yaml Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"autoload": {
"psr-0": { "Symfony\\Component\\Yaml\\": "" }
},
"target-dir": "Symfony/Component/Yaml",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
}
}
}
vendor/
composer.lock
phpunit.xml
Copyright (c) 2004-2013 Fabien Potencier
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.
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
/**
* Dumper dumps PHP variables to YAML strings.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Dumper
{
/**
* The amount of spaces to use for indentation of nested nodes.
*
* @var integer
*/
protected $indentation = 4;
/**
* Sets the indentation.
*
* @param integer $num The amount of spaces to use for indentation of nested nodes.
*/
public function setIndentation($num)
{
$this->indentation = (int) $num;
}
/**
* Dumps a PHP value to YAML.
*
* @param mixed $input The PHP value
* @param integer $inline The level where you switch to inline YAML
* @param integer $indent The level of indentation (used internally)
* @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param Boolean $objectSupport true if object support is enabled, false otherwise
*
* @return string The YAML representation of the PHP value
*/
public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false)
{
$output = '';
$prefix = $indent ? str_repeat(' ', $indent) : '';
if ($inline <= 0 || !is_array($input) || empty($input)) {
$output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
} else {
$isAHash = array_keys($input) !== range(0, count($input) - 1);
foreach ($input as $key => $value) {
$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
$output .= sprintf('%s%s%s%s',
$prefix,
$isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-',
$willBeInlined ? ' ' : "\n",
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
).($willBeInlined ? "\n" : '');
}
}
return $output;
}
}
<?php
spl_autoload_register(function ($class) {
if ('\\' == $class[0]) {
$class = substr($class, 1);
}
if (file_exists($file = __DIR__.'/../../../'.str_replace('\\', '/', $class).'.php')) {
require_once $file;
}
});
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Symfony Yaml Component Test Suite">
<directory>./Tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./</directory>
<exclude>
<directory>./vendor</directory>
<directory>./Tests</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Exception;
/**
* Exception class thrown when an error occurs during parsing.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
*/
class ParseException extends RuntimeException
{
private $parsedFile;
private $parsedLine;
private $snippet;
private $rawMessage;
/**
* Constructor.
*
* @param string $message The error message
* @param integer $parsedLine The line where the error occurred
* @param integer $snippet The snippet of code near the problem
* @param string $parsedFile The file name where the error occurred
* @param Exception $previous The previous exception
*/
public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, Exception $previous = null)
{
$this->parsedFile = $parsedFile;
$this->parsedLine = $parsedLine;
$this->snippet = $snippet;
$this->rawMessage = $message;
$this->updateRepr();
parent::__construct($this->message, 0, $previous);
}
/**
* Gets the snippet of code near the error.
*
* @return string The snippet of code
*/
public function getSnippet()
{
return $this->snippet;
}
/**
* Sets the snippet of code near the error.
*
* @param string $snippet The code snippet
*/
public function setSnippet($snippet)
{
$this->snippet = $snippet;
$this->updateRepr();
}
/**
* Gets the filename where the error occurred.
*
* This method returns null if a string is parsed.
*
* @return string The filename
*/
public function getParsedFile()
{
return $this->parsedFile;
}
/**
* Sets the filename where the error occurred.
*
* @param string $parsedFile The filename
*/
public function setParsedFile($parsedFile)
{
$this->parsedFile = $parsedFile;
$this->updateRepr();
}
/**
* Gets the line where the error occurred.
*
* @return integer The file line
*/
public function getParsedLine()
{
return $this->parsedLine;
}
/**
* Sets the line where the error occurred.
*
* @param integer $parsedLine The file line
*/
public function setParsedLine($parsedLine)
{
$this->parsedLine = $parsedLine;
$this->updateRepr();
}
private function updateRepr()
{
$this->message = $this->rawMessage;
$dot = false;
if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$dot = true;
}
if (null !== $this->parsedFile) {
$this->message .= sprintf(' in %s', json_encode($this->parsedFile));
}
if ($this->parsedLine >= 0) {
$this->message .= sprintf(' at line %d', $this->parsedLine);
}
if ($this->snippet) {
$this->message .= sprintf(' (near "%s")', $this->snippet);
}
if ($dot) {
$this->message .= '.';
}
}
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Exception;
/**
* Exception interface for all exceptions thrown by the component.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
*/
interface ExceptionInterface
{
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Exception;
/**
* Exception class thrown when an error occurs during parsing.
*
* @author Romain Neutron <imprec@gmail.com>
*
* @api
*/
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml\Exception;
/**
* Exception class thrown when an error occurs during dumping.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
*/
class DumpException extends RuntimeException
{
}
<?php
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
use Symfony\Component\Yaml\Exception\ParseException;
/**
* Parser parses YAML strings to convert them to PHP arrays.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Parser
{
private $offset = 0;
private $lines = array();
private $currentLineNb = -1;
private $currentLine = '';
private $refs = array();
/**
* Constructor
*
* @param integer $offset The offset of YAML document (used for line numbers in error messages)
*/
public function __construct($offset = 0)
{
$this->offset = $offset;
}
/**
* Parses a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param Boolean $objectSupport true if object support is enabled, false otherwise
*
* @return mixed A PHP value
*
* @throws ParseException If the YAML is not valid
*/
public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false)
{
$this->currentLineNb = -1;
$this->currentLine = '';
$this->lines = explode("\n", $this->cleanup($value));
if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) {
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
}
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}
$data = array();
$context = null;
while ($this->moveToNextLine()) {
if ($this->isCurrentLineEmpty()) {
continue;
}
// tab?
if ("\t" === $this->currentLine[0]) {
throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
$isRef = $isInPlace = $isProcessed = false;
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
if ($context && 'mapping' == $context) {
throw new ParseException('You cannot define a sequence item when in a mapping');
}
$context = 'sequence';
if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}
// array
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
$c = $this->getRealCurrentLineNb() + 1;
$parser = new Parser($c);
$parser->refs =& $this->refs;
$data[] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
} else {
if (isset($values['leadspaces'])
&& ' ' == $values['leadspaces']
&& preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
) {
// this is a compact notation element, add to next block and parse
$c = $this->getRealCurrentLineNb();
$parser = new Parser($c);
$parser->refs =& $this->refs;
$block = $values['value'];
if (!$this->isNextLineIndented()) {
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2);
}
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport);
} else {
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
}
}
} elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
if ($context && 'sequence' == $context) {
throw new ParseException('You cannot define a mapping item when in a sequence');
}
$context = 'mapping';
// force correct settings
Inline::parse(null, $exceptionOnInvalidType, $objectSupport);
try {
$key = Inline::parseScalar($values['key']);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
throw $e;
}
if ('<<' === $key) {
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
$isInPlace = substr($values['value'], 1);
if (!array_key_exists($isInPlace, $this->refs)) {
throw new ParseException(sprintf('Reference "%s" does not exist.', $isInPlace), $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
} else {
if (isset($values['value']) && $values['value'] !== '') {
$value = $values['value'];
} else {
$value = $this->getNextEmbedBlock();
}
$c = $this->getRealCurrentLineNb() + 1;
$parser = new Parser($c);
$parser->refs =& $this->refs;
$parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport);
$merged = array();
if (!is_array($parsed)) {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
} elseif (isset($parsed[0])) {
// Numeric array, merge individual elements
foreach (array_reverse($parsed) as $parsedItem) {
if (!is_array($parsedItem)) {
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
}
$merged = array_merge($parsedItem, $merged);
}
} else {
// Associative array, merge
$merged = array_merge($merged, $parsed);
}
$isProcessed = $merged;
}
} elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}
if ($isProcessed) {
// Merge keys
$data = $isProcessed;
// hash
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
// if next line is less indented or equal, then it means that the current value is null
if ($this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
$data[$key] = null;
} else {
$c = $this->getRealCurrentLineNb() + 1;
$parser = new Parser($c);
$parser->refs =& $this->refs;
$data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
}
} else {
if ($isInPlace) {
$data = $this->refs[$isInPlace];
} else {
$data[$key] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
}
}
} else {
// 1-liner optionally followed by newline
$lineCount = count($this->lines);
if (1 === $lineCount || (2 === $lineCount && empty($this->lines[1]))) {
try {
$value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
throw $e;
}
if (is_array($value)) {
$first = reset($value);
if (is_string($first) && 0 === strpos($first, '*')) {
$data = array();
foreach ($value as $alias) {
$data[] = $this->refs[substr($alias, 1)];
}
$value = $data;
}
}
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
return $value;
}
switch (preg_last_error()) {
case PREG_INTERNAL_ERROR:
$error = 'Internal PCRE error.';
break;
case PREG_BACKTRACK_LIMIT_ERROR:
$error = 'pcre.backtrack_limit reached.';
break;
case PREG_RECURSION_LIMIT_ERROR:
$error = 'pcre.recursion_limit reached.';
break;
case PREG_BAD_UTF8_ERROR:
$error = 'Malformed UTF-8 data.';
break;
case PREG_BAD_UTF8_OFFSET_ERROR:
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
break;
default:
$error = 'Unable to parse.';
}
throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
if ($isRef) {
$this->refs[$isRef] = end($data);
}
}
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
return empty($data) ? null : $data;
}
/**
* Returns the current line number (takes the offset into account).
*
* @return integer The current line number
*/
private function getRealCurrentLineNb()
{
return $this->currentLineNb + $this->offset;
}
/**
* Returns the current line indentation.
*
* @return integer The current line indentation
*/
private function getCurrentLineIndentation()
{
return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
}
/**
* Returns the next embed block of YAML.
*
* @param integer $indentation The indent level at which the block is to be read, or null for default
*
* @return string A YAML string
*
* @throws ParseException When indentation problem are detected
*/
private function getNextEmbedBlock($indentation = null)
{
$this->moveToNextLine();
if (null === $indentation) {
$newIndent = $this->getCurrentLineIndentation();
$unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem($this->currentLine);
if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
} else {
$newIndent = $indentation;
}
$data = array(substr($this->currentLine, $newIndent));
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
while ($this->moveToNextLine()) {
if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem($this->currentLine)) {
$this->moveToPreviousLine();
break;
}
if ($this->isCurrentLineEmpty()) {
if ($this->isCurrentLineBlank()) {
$data[] = substr($this->currentLine, $newIndent);
}
continue;
}
$indent = $this->getCurrentLineIndentation();
if (preg_match('#^(?P<text> *)$#', $this->currentLine, $match)) {
// empty line
$data[] = $match['text'];
} elseif ($indent >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent);
} elseif (0 == $indent) {
$this->moveToPreviousLine();
break;
} else {
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
}
return implode("\n", $data);
}
/**
* Moves the parser to the next line.
*
* @return Boolean
*/
private function moveToNextLine()
{
if ($this->currentLineNb >= count($this->lines) - 1) {
return false;
}
$this->currentLine = $this->lines[++$this->currentLineNb];
return true;
}
/**
* Moves the parser to the previous line.
*/
private function moveToPreviousLine()
{
$this->currentLine = $this->lines[--$this->currentLineNb];
}
/**
* Parses a YAML value.
*
* @param string $value A YAML value
*
* @return mixed A PHP value
*
* @throws ParseException When reference does not exist
*/
private function parseValue($value, $exceptionOnInvalidType, $objectSupport)
{
if (0 === strpos($value, '*')) {
if (false !== $pos = strpos($value, '#')) {
$value = substr($value, 1, $pos - 2);
} else {
$value = substr($value, 1);
}
if (!array_key_exists($value, $this->refs)) {
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
}
return $this->refs[$value];
}
if (preg_match('/^(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?$/', $value, $matches)) {
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers)));
}
try {
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
throw $e;
}
}
/**
* Parses a folded scalar.
*
* @param string $separator The separator that was used to begin this folded scalar (| or >)
* @param string $indicator The indicator that was used to begin this folded scalar (+ or -)
* @param integer $indentation The indentation that was used to begin this folded scalar
*
* @return string The text value
*/
private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
{
$separator = '|' == $separator ? "\n" : ' ';
$text = '';
$notEOF = $this->moveToNextLine();
while ($notEOF && $this->isCurrentLineBlank()) {
$text .= "\n";
$notEOF = $this->moveToNextLine();
}
if (!$notEOF) {
return '';
}
if (!preg_match('#^(?P<indent>'.($indentation ? str_repeat(' ', $indentation) : ' +').')(?P<text>.*)$#u', $this->currentLine, $matches)) {
$this->moveToPreviousLine();
return '';
}
$textIndent = $matches['indent'];
$previousIndent = 0;
$text .= $matches['text'].$separator;
while ($this->currentLineNb + 1 < count($this->lines)) {
$this->moveToNextLine();
if (preg_match('#^(?P<indent> {'.strlen($textIndent).',})(?P<text>.+)$#u', $this->currentLine, $matches)) {
if (' ' == $separator && $previousIndent != $matches['indent']) {
$text = substr($text, 0, -1)."\n";
}
$previousIndent = $matches['indent'];
$text .= str_repeat(' ', $diff = strlen($matches['indent']) - strlen($textIndent)).$matches['text'].($diff ? "\n" : $separator);
} elseif (preg_match('#^(?P<text> *)$#', $this->currentLine, $matches)) {
$text .= preg_replace('#^ {1,'.strlen($textIndent).'}#', '', $matches['text'])."\n";
} else {
$this->moveToPreviousLine();
break;
}
}
if (' ' == $separator) {
// replace last separator by a newline
$text = preg_replace('/ (\n*)$/', "\n$1", $text);
}
switch ($indicator) {
case '':
$text = preg_replace('#\n+$#s', "\n", $text);
break;
case '+':
break;
case '-':
$text = preg_replace('#\n+$#s', '', $text);
break;
}
return $text;
}
/**
* Returns true if the next line is indented.
*
* @return Boolean Returns true if the next line is indented, false otherwise
*/
private function isNextLineIndented()
{
$currentIndentation = $this->getCurrentLineIndentation();
$notEOF = $this->moveToNextLine();
while ($notEOF && $this->isCurrentLineEmpty()) {
$notEOF = $this->moveToNextLine();
}
if (false === $notEOF) {
return false;
}
$ret = false;
if ($this->getCurrentLineIndentation() <= $currentIndentation) {
$ret = true;
}
$this->moveToPreviousLine();
return $ret;
}
/**
* Returns true if the current line is blank or if it is a comment line.
*
* @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise
*/
private function isCurrentLineEmpty()
{
return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
}
/**
* Returns true if the current line is blank.
*
* @return Boolean Returns true if the current line is blank, false otherwise
*/
private function isCurrentLineBlank()
{
return '' == trim($this->currentLine, ' ');
}
/**
* Returns true if the current line is a comment line.
*
* @return Boolean Returns true if the current line is a comment line, false otherwise
*/
private function isCurrentLineComment()
{
//checking explicitly the first char of the trim is faster than loops or strpos
$ltrimmedLine = ltrim($this->currentLine, ' ');
return $ltrimmedLine[0] === '#';
}
/**
* Cleanups a YAML string to be parsed.
*
* @param string $value The input YAML string
*
* @return string A cleaned up YAML string
*/
private function cleanup($value)
{
$value = str_replace(array("\r\n", "\r"), "\n", $value);
// strip YAML header
$count = 0;
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $value, -1, $count);
$this->offset += $count;
// remove leading comments
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
if ($count == 1) {
// items have been removed, update the offset
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;
}
// remove start of the document marker (---)
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
if ($count == 1) {
// items have been removed, update the offset
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;
// remove end of the document marker (...)
$value = preg_replace('#\.\.\.\s*$#s', '', $value);
}
return $value;
}
/**
* Returns true if the next line starts unindented collection
*
* @return Boolean Returns true if the next line starts unindented collection, false otherwise
*/
private function isNextLineUnIndentedCollection()
{
$currentIndentation = $this->getCurrentLineIndentation();
$notEOF = $this->moveToNextLine();
while ($notEOF && $this->isCurrentLineEmpty()) {
$notEOF = $this->moveToNextLine();
}
if (false === $notEOF) {
return false;
}
$ret = false;
if (
$this->getCurrentLineIndentation() == $currentIndentation
&&
$this->isStringUnIndentedCollectionItem($this->currentLine)
) {
$ret = true;
}
$this->moveToPreviousLine();
return $ret;
}
/**
* Returns true if the string is un-indented collection item
*
* @return Boolean Returns true if the string is un-indented collection item, false otherwise
*/
private function isStringUnIndentedCollectionItem()
{
return (0 === strpos($this->currentLine, '- '));
}
}
<?php
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
/**
* Unescaper encapsulates unescaping rules for single and double-quoted
* YAML strings.
*
* @author Matthew Lewinski <matthew@lewinski.org>
*/
class Unescaper
{
// Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
// must be converted to that encoding.
const ENCODING = 'UTF-8';
// Regex fragment that matches an escaped character in a double quoted
// string.
const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
/**
* Unescapes a single quoted string.
*
* @param string $value A single quoted string.
*
* @return string The unescaped string.
*/
public function unescapeSingleQuotedString($value)
{
return str_replace('\'\'', '\'', $value);
}
/**
* Unescapes a double quoted string.
*
* @param string $value A double quoted string.
*
* @return string The unescaped string.
*/
public function unescapeDoubleQuotedString($value)
{
$self = $this;
$callback = function($match) use ($self) {
return $self->unescapeCharacter($match[0]);
};
// evaluate the string
return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
}
/**
* Unescapes a character that was found in a double-quoted string
*
* @param string $value An escaped character
*
* @return string The unescaped character
*/
public function unescapeCharacter($value)
{
switch ($value{1}) {
case '0':
return "\x0";
case 'a':
return "\x7";
case 'b':
return "\x8";
case 't':
return "\t";
case "\t":
return "\t";
case 'n':
return "\n";
case 'v':
return "\xb";
case 'f':
return "\xc";
case 'r':
return "\xd";
case 'e':
return "\x1b";
case ' ':
return ' ';
case '"':
return '"';
case '/':
return '/';
case '\\':
return '\\';
case 'N':
// U+0085 NEXT LINE
return $this->convertEncoding("\x00\x85", self::ENCODING, 'UCS-2BE');
case '_':
// U+00A0 NO-BREAK SPACE
return $this->convertEncoding("\x00\xA0", self::ENCODING, 'UCS-2BE');
case 'L':
// U+2028 LINE SEPARATOR
return $this->convertEncoding("\x20\x28", self::ENCODING, 'UCS-2BE');
case 'P':
// U+2029 PARAGRAPH SEPARATOR
return $this->convertEncoding("\x20\x29", self::ENCODING, 'UCS-2BE');
case 'x':
$char = pack('n', hexdec(substr($value, 2, 2)));
return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
case 'u':
$char = pack('n', hexdec(substr($value, 2, 4)));
return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
case 'U':
$char = pack('N', hexdec(substr($value, 2, 8)));
return $this->convertEncoding($char, self::ENCODING, 'UCS-4BE');
}
}
/**
* Convert a string from one encoding to another.
*
* @param string $value The string to convert
* @param string $to The input encoding
* @param string $from The output encoding
*
* @return string The string with the new encoding
*
* @throws RuntimeException if no suitable encoding function is found (iconv or mbstring)
*/
private function convertEncoding($value, $to, $from)
{
if (function_exists('mb_convert_encoding')) {
return mb_convert_encoding($value, $to, $from);
} elseif (function_exists('iconv')) {
return iconv($from, $to, $value);
}
throw new RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).');
}
}
Yaml Component
==============
YAML implements most of the YAML 1.2 specification.
use Symfony\Component\Yaml\Yaml;
$array = Yaml::parse($file);
print Yaml::dump($array);
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Yaml/
$ composer.phar install --dev
$ phpunit
<?php
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Exception\DumpException;
/**
* Inline implements a YAML parser/dumper for the YAML inline syntax.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Inline
{
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
private static $exceptionOnInvalidType = false;
private static $objectSupport = false;
/**
* Converts a YAML string to a PHP array.
*
* @param string $value A YAML string
* @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param Boolean $objectSupport true if object support is enabled, false otherwise
*
* @return array A PHP array representing the YAML string
*
* @throws ParseException
*/
public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false)
{
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
self::$objectSupport = $objectSupport;
$value = trim($value);
if (0 == strlen($value)) {
return '';
}
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}
$i = 0;
switch ($value[0]) {
case '[':
$result = self::parseSequence($value, $i);
++$i;
break;
case '{':
$result = self::parseMapping($value, $i);
++$i;
break;
default:
$result = self::parseScalar($value, null, array('"', "'"), $i);
}
// some comments are allowed at the end
if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
}
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
return $result;
}
/**
* Dumps a given PHP variable to a YAML string.
*
* @param mixed $value The PHP variable to convert
* @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param Boolean $objectSupport true if object support is enabled, false otherwise
*
* @return string The YAML string representing the PHP array
*
* @throws DumpException When trying to dump PHP resource
*/
public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
{
switch (true) {
case is_resource($value):
if ($exceptionOnInvalidType) {
throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
}
return 'null';
case is_object($value):
if ($objectSupport) {
return '!!php/object:'.serialize($value);
}
if ($exceptionOnInvalidType) {
throw new DumpException('Object support when dumping a YAML file has been disabled.');
}
return 'null';
case is_array($value):
return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
case null === $value:
return 'null';
case true === $value:
return 'true';
case false === $value:
return 'false';
case ctype_digit($value):
return is_string($value) ? "'$value'" : (int) $value;
case is_numeric($value):
$locale = setlocale(LC_NUMERIC, 0);
if (false !== $locale) {
setlocale(LC_NUMERIC, 'C');
}
$repr = is_string($value) ? "'$value'" : (is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : strval($value));
if (false !== $locale) {
setlocale(LC_NUMERIC, $locale);
}
return $repr;
case Escaper::requiresDoubleQuoting($value):
return Escaper::escapeWithDoubleQuotes($value);
case Escaper::requiresSingleQuoting($value):
return Escaper::escapeWithSingleQuotes($value);
case '' == $value:
return "''";
case preg_match(self::getTimestampRegex(), $value):
case in_array(strtolower($value), array('null', '~', 'true', 'false')):
return "'$value'";
default:
return $value;
}
}
/**
* Dumps a PHP array to a YAML string.
*
* @param array $value The PHP array to dump
* @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param Boolean $objectSupport true if object support is enabled, false otherwise
*
* @return string The YAML string representing the PHP array
*/
private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
{
// array
$keys = array_keys($value);
if ((1 == count($keys) && '0' == $keys[0])
|| (count($keys) > 1 && array_reduce($keys, function ($v, $w) { return (integer) $v + $w; }, 0) == count($keys) * (count($keys) - 1) / 2)
) {
$output = array();
foreach ($value as $val) {
$output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
}
return sprintf('[%s]', implode(', ', $output));
}
// mapping
$output = array();
foreach ($value as $key => $val) {
$output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
}
return sprintf('{ %s }', implode(', ', $output));
}
/**
* Parses a scalar to a YAML string.
*
* @param scalar $scalar
* @param string $delimiters
* @param array $stringDelimiters
* @param integer &$i
* @param Boolean $evaluate
*
* @return string A YAML string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
{
if (in_array($scalar[$i], $stringDelimiters)) {
// quoted scalar
$output = self::parseQuotedScalar($scalar, $i);
if (null !== $delimiters) {
$tmp = ltrim(substr($scalar, $i), ' ');
if (!in_array($tmp[0], $delimiters)) {
throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
}
}
} else {
// "normal" string
if (!$delimiters) {
$output = substr($scalar, $i);
$i += strlen($output);
// remove comments
if (false !== $strpos = strpos($output, ' #')) {
$output = rtrim(substr($output, 0, $strpos));
}
} elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
$output = $match[1];
$i += strlen($output);
} else {
throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
}
$output = $evaluate ? self::evaluateScalar($output) : $output;
}
return $output;
}
/**
* Parses a quoted scalar to YAML.
*
* @param string $scalar
* @param integer &$i
*
* @return string A YAML string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseQuotedScalar($scalar, &$i)
{
// Only check the current item we're dealing with (for sequences)
$subject = substr($scalar, $i);
$items = preg_split('/[\'"]\s*(?:[,:]|[}\]]\s*,)/', $subject);
$subject = substr($subject, 0, strlen($items[0]) + 1);
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
}
$output = substr($match[0], 1, strlen($match[0]) - 2);
$unescaper = new Unescaper();
if ('"' == $scalar[$i]) {
$output = $unescaper->unescapeDoubleQuotedString($output);
} else {
$output = $unescaper->unescapeSingleQuotedString($output);
}
$i += strlen($match[0]);
return $output;
}
/**
* Parses a sequence to a YAML string.
*
* @param string $sequence
* @param integer &$i
*
* @return string A YAML string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseSequence($sequence, &$i = 0)
{
$output = array();
$len = strlen($sequence);
$i += 1;
// [foo, bar, ...]
while ($i < $len) {
switch ($sequence[$i]) {
case '[':
// nested sequence
$output[] = self::parseSequence($sequence, $i);
break;
case '{':
// nested mapping
$output[] = self::parseMapping($sequence, $i);
break;
case ']':
return $output;
case ',':
case ' ':
break;
default:
$isQuoted = in_array($sequence[$i], array('"', "'"));
$value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i);
if (!$isQuoted && false !== strpos($value, ': ')) {
// embedded mapping?
try {
$value = self::parseMapping('{'.$value.'}');
} catch (\InvalidArgumentException $e) {
// no, it's not
}
}
$output[] = $value;
--$i;
}
++$i;
}
throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
}
/**
* Parses a mapping to a YAML string.
*
* @param string $mapping
* @param integer &$i
*
* @return string A YAML string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseMapping($mapping, &$i = 0)
{
$output = array();
$len = strlen($mapping);
$i += 1;
// {foo: bar, bar:foo, ...}
while ($i < $len) {
switch ($mapping[$i]) {
case ' ':
case ',':
++$i;
continue 2;
case '}':
return $output;
}
// key
$key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
// value
$done = false;
while ($i < $len) {
switch ($mapping[$i]) {
case '[':
// nested sequence
$output[$key] = self::parseSequence($mapping, $i);
$done = true;
break;
case '{':
// nested mapping
$output[$key] = self::parseMapping($mapping, $i);
$done = true;
break;
case ':':
case ' ':
break;
default:
$output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
$done = true;
--$i;
}
++$i;
if ($done) {
continue 2;
}
}
}
throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
}
/**
* Evaluates scalars and replaces magic values.
*
* @param string $scalar
*
* @return string A YAML string
*/
private static function evaluateScalar($scalar)
{
$scalar = trim($scalar);
switch (true) {
case 'null' == strtolower($scalar):
case '' == $scalar:
case '~' == $scalar:
return null;
case 0 === strpos($scalar, '!str'):
return (string) substr($scalar, 5);
case 0 === strpos($scalar, '! '):
return intval(self::parseScalar(substr($scalar, 2)));
case 0 === strpos($scalar, '!!php/object:'):
if (self::$objectSupport) {
return unserialize(substr($scalar, 13));
}
if (self::$exceptionOnInvalidType) {
throw new ParseException('Object support when parsing a YAML file has been disabled.');
}
return null;
case ctype_digit($scalar):
$raw = $scalar;
$cast = intval($scalar);
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
$raw = $scalar;
$cast = intval($scalar);
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
case 'true' === strtolower($scalar):
return true;
case 'false' === strtolower($scalar):
return false;
case is_numeric($scalar):
return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
case 0 == strcasecmp($scalar, '.inf'):
case 0 == strcasecmp($scalar, '.NaN'):
return -log(0);
case 0 == strcasecmp($scalar, '-.inf'):
return log(0);
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
return floatval(str_replace(',', '', $scalar));
case preg_match(self::getTimestampRegex(), $scalar):
return strtotime($scalar);
default:
return (string) $scalar;
}
}
/**
* Gets a regex that matches a YAML date.
*
* @return string The regular expression
*
* @see http://www.yaml.org/spec/1.2/spec.html#id2761573
*/
private static function getTimestampRegex()
{
return <<<EOF
~^
(?P<year>[0-9][0-9][0-9][0-9])
-(?P<month>[0-9][0-9]?)
-(?P<day>[0-9][0-9]?)
(?:(?:[Tt]|[ \t]+)
(?P<hour>[0-9][0-9]?)
:(?P<minute>[0-9][0-9])
:(?P<second>[0-9][0-9])
(?:\.(?P<fraction>[0-9]*))?
(?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
(?::(?P<tz_minute>[0-9][0-9]))?))?)?
$~x
EOF;
}
}
<?php
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Yaml;
/**
* Escaper encapsulates escaping rules for single and double-quoted
* YAML strings.
*
* @author Matthew Lewinski <matthew@lewinski.org>
*/
class Escaper
{
// Characters that would cause a dumped string to require double quoting.
const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
// Mapping arrays for escaping a double quoted string. The backslash is
// first to ensure proper escaping because str_replace operates iteratively
// on the input arrays. This ordering of the characters avoids the use of strtr,
// which performs more slowly.
private static $escapees = array('\\\\', '\\"', '"',
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
"\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9");
private static $escaped = array('\\"', '\\\\', '\\"',
"\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
"\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f",
"\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
"\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f",
"\\N", "\\_", "\\L", "\\P");
/**
* Determines if a PHP value would require double quoting in YAML.
*
* @param string $value A PHP value
*
* @return Boolean True if the value would require double quotes.
*/
public static function requiresDoubleQuoting($value)
{
return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
}
/**
* Escapes and surrounds a PHP value with double quotes.
*
* @param string $value A PHP value
*
* @return string The quoted, escaped string
*/
public static function escapeWithDoubleQuotes($value)
{
return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
}
/**
* Determines if a PHP value would require single quoting in YAML.
*
* @param string $value A PHP value
*
* @return Boolean True if the value would require single quotes.
*/
public static function requiresSingleQuoting($value)
{
return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value);
}
/**
* Escapes and surrounds a PHP value with single quotes.
*
* @param string $value A PHP value
*
* @return string The quoted, escaped string
*/
public static function escapeWithSingleQuotes($value)
{
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
}
}
CHANGELOG
=========
2.1.0
-----
* Yaml::parse() does not evaluate loaded files as PHP files by default
anymore (call Yaml::enablePhpParsing() to get back the old behavior)
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A TestFailure collects a failed test together with the caught exception.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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->toString(),
$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) {
$buffer = $e->toString();
if ($e instanceof PHPUnit_Framework_ExpectationFailedException && $e->getComparisonFailure()) {
$buffer = $buffer . "\n" . $e->getComparisonFailure()->getDiff();
}
if (!empty($buffer)) {
$buffer = trim($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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Factory for comparators which compare values for equality.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_ComparatorFactory
{
/**
* @var array
*/
protected $comparators = array();
/**
* @var PHPUnit_Framework_ComparatorFactory
*/
private static $defaultInstance = NULL;
/**
* Constructs a new factory.
*/
public function __construct()
{
$this->register(new PHPUnit_Framework_Comparator_Type);
$this->register(new PHPUnit_Framework_Comparator_Scalar);
$this->register(new PHPUnit_Framework_Comparator_Numeric);
$this->register(new PHPUnit_Framework_Comparator_Double);
$this->register(new PHPUnit_Framework_Comparator_Array);
$this->register(new PHPUnit_Framework_Comparator_Resource);
$this->register(new PHPUnit_Framework_Comparator_Object);
$this->register(new PHPUnit_Framework_Comparator_Exception);
$this->register(new PHPUnit_Framework_Comparator_SplObjectStorage);
$this->register(new PHPUnit_Framework_Comparator_DOMDocument);
$this->register(new PHPUnit_Framework_Comparator_MockObject);
}
/**
* Returns the default instance.
*
* @return PHPUnit_Framework_ComparatorFactory
*/
public static function getDefaultInstance()
{
if (self::$defaultInstance === NULL) {
self::$defaultInstance = new PHPUnit_Framework_ComparatorFactory;
}
return self::$defaultInstance;
}
/**
* Returns the correct comparator for comparing two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return PHPUnit_Framework_Comparator
* @throws PHPUnit_Framework_Exception
*/
public function getComparatorFor($expected, $actual)
{
foreach ($this->comparators as $comparator) {
if ($comparator->accepts($expected, $actual)) {
return $comparator;
}
}
throw new PHPUnit_Framework_Exception(
sprintf(
'No comparator is registered for comparing the types "%s" and "%s"',
gettype($expected), gettype($actual)
)
);
}
/**
* Registers a new comparator.
*
* This comparator will be returned by getInstance() if its accept() method
* returns TRUE for the compared values. It has higher priority than the
* existing comparators, meaning that its accept() method will be tested
* before those of the other comparators.
*
* @param PHPUnit_Framework_Comparator $comparator The registered comparator
*/
public function register(PHPUnit_Framework_Comparator $comparator)
{
array_unshift($this->comparators, $comparator);
$comparator->setFactory($this);
}
/**
* Unregisters a comparator.
*
* This comparator will no longer be returned by getInstance().
*
* @param PHPUnit_Framework_Comparator $comparator The unregistered comparator
*/
public function unregister(PHPUnit_Framework_Comparator $comparator)
{
foreach ($this->comparators as $key => $_comparator) {
if ($comparator === $_comparator) {
unset($this->comparators[$key]);
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of a skipped test suite.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A set of assert methods.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
abstract class PHPUnit_Framework_Assert
{
/**
* @var integer
*/
private static $count = 0;
/**
* Asserts that an array has a specified key.
*
* @param mixed $key
* @param array|ArrayAccess $array
* @param string $message
* @since Method available since Release 3.0.0
*/
public static function assertArrayHasKey($key, $array, $message = '')
{
if (!(is_integer($key) || is_string($key))) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'integer or string'
);
}
if (!(is_array($array) || $array instanceof ArrayAccess)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
2, 'array or ArrayAccess'
);
}
$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|ArrayAccess $array
* @param string $message
* @since Method available since Release 3.0.0
*/
public static function assertArrayNotHasKey($key, $array, $message = '')
{
if (!(is_integer($key) || is_string($key))) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'integer or string'
);
}
if (!(is_array($array) || $array instanceof ArrayAccess)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
2, 'array or ArrayAccess'
);
}
$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
* @param boolean $checkForObjectIdentity
* @since Method available since Release 2.1.0
*/
public static function assertContains($needle, $haystack, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
if (is_array($haystack) ||
is_object($haystack) && $haystack instanceof Traversable) {
$constraint = new PHPUnit_Framework_Constraint_TraversableContains(
$needle, $checkForObjectIdentity
);
}
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
* @param boolean $checkForObjectIdentity
* @since Method available since Release 3.0.0
*/
public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
self::assertContains(
$needle,
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message,
$ignoreCase,
$checkForObjectIdentity
);
}
/**
* Asserts that a haystack does not contain a needle.
*
* @param mixed $needle
* @param mixed $haystack
* @param string $message
* @param boolean $ignoreCase
* @param boolean $checkForObjectIdentity
* @since Method available since Release 2.1.0
*/
public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
if (is_array($haystack) ||
is_object($haystack) && $haystack instanceof Traversable) {
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_TraversableContains(
$needle, $checkForObjectIdentity
)
);
}
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
* @param boolean $checkForObjectIdentity
* @since Method available since Release 3.0.0
*/
public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
self::assertNotContains(
$needle,
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message,
$ignoreCase,
$checkForObjectIdentity
);
}
/**
* 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 contains only instances of a given classname
*
* @param string $classname
* @param array|Traversable $haystack
* @param string $message
*/
public static function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
{
if (!(is_array($haystack) ||
is_object($haystack) && $haystack instanceof Traversable)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
2, 'array or iterator'
);
}
self::assertThat(
$haystack,
new PHPUnit_Framework_Constraint_TraversableContainsOnly(
$classname, FALSE
),
$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 the number of elements of an array, Countable or Iterator.
*
* @param integer $expectedCount
* @param mixed $haystack
* @param string $message
*/
public static function assertCount($expectedCount, $haystack, $message = '')
{
if (!is_int($expectedCount)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
if (!$haystack instanceof Countable &&
!$haystack instanceof Iterator &&
!is_array($haystack)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable');
}
self::assertThat(
$haystack,
new PHPUnit_Framework_Constraint_Count($expectedCount),
$message
);
}
/**
* Asserts the number of elements of an array, Countable or Iterator
* that is stored in an attribute.
*
* @param integer $expectedCount
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.6.0
*/
public static function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
{
self::assertCount(
$expectedCount,
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message
);
}
/**
* Asserts the number of elements of an array, Countable or Iterator.
*
* @param integer $expectedCount
* @param mixed $haystack
* @param string $message
*/
public static function assertNotCount($expectedCount, $haystack, $message = '')
{
if (!is_int($expectedCount)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
if (!$haystack instanceof Countable &&
!$haystack instanceof Iterator &&
!is_array($haystack)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable');
}
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_Count($expectedCount)
);
self::assertThat($haystack, $constraint, $message);
}
/**
* Asserts the number of elements of an array, Countable or Iterator
* that is stored in an attribute.
*
* @param integer $expectedCount
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.6.0
*/
public static function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
{
self::assertNotCount(
$expectedCount,
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message
);
}
/**
* Asserts that two variables are equal.
*
* @param mixed $expected
* @param mixed $actual
* @param string $message
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
*/
public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
$constraint = new PHPUnit_Framework_Constraint_IsEqual(
$expected, $delta, $maxDepth, $canonicalize, $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 $canonicalize
* @param boolean $ignoreCase
*/
public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
self::assertEquals(
$expected,
self::readAttribute($actualClassOrObject, $actualAttributeName),
$message,
$delta,
$maxDepth,
$canonicalize,
$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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 2.3.0
*/
public static function assertNotEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_IsEqual(
$expected, $delta, $maxDepth, $canonicalize, $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 $canonicalize
* @param boolean $ignoreCase
*/
public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
self::assertNotEquals(
$expected,
self::readAttribute($actualClassOrObject, $actualAttributeName),
$message,
$delta,
$maxDepth,
$canonicalize,
$ignoreCase
);
}
/**
* Asserts that a variable is empty.
*
* @param mixed $actual
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
public static function assertEmpty($actual, $message = '')
{
self::assertThat($actual, self::isEmpty(), $message);
}
/**
* Asserts that a static attribute of a class or an attribute of an object
* is empty.
*
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
{
self::assertEmpty(
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message
);
}
/**
* Asserts that a variable is not empty.
*
* @param mixed $actual
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
public static function assertNotEmpty($actual, $message = '')
{
self::assertThat($actual, self::logicalNot(self::isEmpty()), $message);
}
/**
* Asserts that a static attribute of a class or an attribute of an object
* is not empty.
*
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
{
self::assertNotEmpty(
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.2.14
*/
public static function assertFileEquals($expected, $actual, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
self::assertFileExists($expected, $message);
self::assertFileExists($actual, $message);
self::assertEquals(
file_get_contents($expected),
file_get_contents($actual),
$message,
0,
10,
$canonicalize,
$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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.2.14
*/
public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
self::assertFileExists($expected, $message);
self::assertFileExists($actual, $message);
self::assertNotEquals(
file_get_contents($expected),
file_get_contents($actual),
$message,
0,
10,
$canonicalize,
$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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.3.0
*/
public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
self::assertFileExists($expectedFile, $message);
self::assertEquals(
file_get_contents($expectedFile),
$actualString,
$message,
0,
10,
$canonicalize,
$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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.3.0
*/
public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
self::assertFileExists($expectedFile, $message);
self::assertNotEquals(
file_get_contents($expectedFile),
$actualString,
$message,
0,
10,
$canonicalize,
$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
* @since Method available since Release 3.5.0
*/
public static function assertInstanceOf($expected, $actual, $message = '')
{
if (is_string($expected)) {
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.5.0
*/
public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
self::assertInstanceOf(
$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 3.5.0
*/
public static function assertNotInstanceOf($expected, $actual, $message = '')
{
if (is_string($expected)) {
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.5.0
*/
public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
self::assertNotInstanceOf(
$expected,
self::readAttribute($classOrObject, $attributeName),
$message
);
}
/**
* Asserts that a variable is of a given type.
*
* @param string $expected
* @param mixed $actual
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertInternalType($expected, $actual, $message = '')
{
if (is_string($expected)) {
$constraint = new PHPUnit_Framework_Constraint_IsType(
$expected
);
} 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.5.0
*/
public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
{
self::assertInternalType(
$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 3.5.0
*/
public static function assertNotInternalType($expected, $actual, $message = '')
{
if (is_string($expected)) {
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_IsType($expected)
);
} 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.5.0
*/
public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
{
self::assertNotInternalType(
$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);
}
/**
* Assert that the size of two arrays (or `Countable` or `Iterator` objects)
* is the same.
*
* @param array|Countable|Iterator $expected
* @param array|Countable|Iterator $actual
* @param string $message
*/
public static function assertSameSize($expected, $actual, $message = '')
{
if (!$expected instanceof Countable &&
!$expected instanceof Iterator &&
!is_array($expected)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable');
}
if (!$actual instanceof Countable &&
!$actual instanceof Iterator &&
!is_array($actual)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable');
}
self::assertThat(
$actual,
new PHPUnit_Framework_Constraint_SameSize($expected),
$message
);
}
/**
* Assert that the size of two arrays (or `Countable` or `Iterator` objects)
* is not the same.
*
* @param array|Countable|Iterator $expected
* @param array|Countable|Iterator $actual
* @param string $message
*/
public static function assertNotSameSize($expected, $actual, $message = '')
{
if (!$expected instanceof Countable &&
!$expected instanceof Iterator &&
!is_array($expected)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable');
}
if (!$actual instanceof Countable &&
!$actual instanceof Iterator &&
!is_array($actual)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable');
}
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_SameSize($expected)
);
self::assertThat($actual, $constraint, $message);
}
/**
* Asserts that a string matches a given format string.
*
* @param string $format
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertStringMatchesFormat($format, $string, $message = '')
{
if (!is_string($format)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
if (!is_string($string)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
}
$constraint = new PHPUnit_Framework_Constraint_StringMatches($format);
self::assertThat($string, $constraint, $message);
}
/**
* Asserts that a string does not match a given format string.
*
* @param string $format
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertStringNotMatchesFormat($format, $string, $message = '')
{
if (!is_string($format)) {
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_StringMatches($format)
);
self::assertThat($string, $constraint, $message);
}
/**
* Asserts that a string matches a given format file.
*
* @param string $formatFile
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertStringMatchesFormatFile($formatFile, $string, $message = '')
{
self::assertFileExists($formatFile, $message);
if (!is_string($string)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
}
$constraint = new PHPUnit_Framework_Constraint_StringMatches(
file_get_contents($formatFile)
);
self::assertThat($string, $constraint, $message);
}
/**
* Asserts that a string does not match a given format string.
*
* @param string $formatFile
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
public static function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
{
self::assertFileExists($formatFile, $message);
if (!is_string($string)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
}
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_StringMatches(
file_get_contents($formatFile)
)
);
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 suffix.
*
* @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 suffix.
*
* @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 DOMElements matches.
*
* @param DOMElement $expectedElement
* @param DOMElement $actualElement
* @param boolean $checkAttributes
* @param string $message
* @author Mattis Stordalen Flister <mattis@xait.no>
* @since Method available since Release 3.3.0
*/
public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = FALSE, $message = '')
{
self::assertEquals(
$expectedElement->tagName,
$actualElement->tagName,
$message
);
if ($checkAttributes) {
self::assertEquals(
$expectedElement->attributes->length,
$actualElement->attributes->length,
sprintf(
'%s%sNumber of attributes on node "%s" does not match',
$message,
!empty($message) ? "\n" : '',
$expectedElement->tagName
)
);
for ($i = 0 ; $i < $expectedElement->attributes->length; $i++) {
$expectedAttribute = $expectedElement->attributes->item($i);
$actualAttribute = $actualElement->attributes->getNamedItem(
$expectedAttribute->name
);
if (!$actualAttribute) {
self::fail(
sprintf(
'%s%sCould not find attribute "%s" on node "%s"',
$message,
!empty($message) ? "\n" : '',
$expectedAttribute->name,
$expectedElement->tagName
)
);
}
}
}
PHPUnit_Util_XML::removeCharacterDataNodes($expectedElement);
PHPUnit_Util_XML::removeCharacterDataNodes($actualElement);
self::assertEquals(
$expectedElement->childNodes->length,
$actualElement->childNodes->length,
sprintf(
'%s%sNumber of child nodes of "%s" differs',
$message,
!empty($message) ? "\n" : '',
$expectedElement->tagName
)
);
for ($i = 0; $i < $expectedElement->childNodes->length; $i++) {
self::assertEqualXMLStructure(
$expectedElement->childNodes->item($i),
$actualElement->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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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, $message);
}
// 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 PHPUnit_Framework_Exception;
}
}
/**
* 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
*
* <code>
* // 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' => 'regexp:/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);
* </code>
*
* 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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);
$constraint->evaluate($value, $message);
}
/**
* Asserts that a string is a valid JSON string.
*
* @param string $filename
* @param string $message
* @since Method available since Release 3.7.20
*/
public static function assertJson($expectedJson, $message = '')
{
if (!is_string($expectedJson)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
self::assertThat($expectedJson, self::isJson(), $message);
}
/**
* Asserts that two given JSON encoded objects or arrays are equal.
*
* @param string $expectedJson
* @param string $actualJson
* @param string $message
*/
public static function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
{
self::assertJson($expectedJson, $message);
self::assertJson($actualJson, $message);
$expected = json_decode($expectedJson);
$actual = json_decode($actualJson);
self::assertEquals($expected, $actual, $message);
}
/**
* Asserts that two given JSON encoded objects or arrays are not equal.
*
* @param string $expectedJson
* @param string $actualJson
* @param string $message
*/
public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
{
self::assertJson($expectedJson, $message);
self::assertJson($actualJson, $message);
$expected = json_decode($expectedJson);
$actual = json_decode($actualJson);
self::assertNotEquals($expected, $actual, $message);
}
/**
* Asserts that the generated JSON encoded object and the content of the given file are equal.
*
* @param string $expectedFile
* @param string $actualJson
* @param string $message
*/
public static function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
{
self::assertFileExists($expectedFile, $message);
$expectedJson = file_get_contents($expectedFile);
self::assertJson($expectedJson, $message);
self::assertJson($actualJson, $message);
// call constraint
$constraint = new PHPUnit_Framework_Constraint_JsonMatches(
$expectedJson
);
self::assertThat($actualJson, $constraint, $message);
}
/**
* Asserts that the generated JSON encoded object and the content of the given file are not equal.
*
* @param string $expectedFile
* @param string $actualJson
* @param string $message
*/
public static function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
{
self::assertFileExists($expectedFile, $message);
$expectedJson = file_get_contents($expectedFile);
self::assertJson($expectedJson, $message);
self::assertJson($actualJson, $message);
// call constraint
$constraint = new PHPUnit_Framework_Constraint_JsonMatches(
$expectedJson
);
self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraint), $message);
}
/**
* Asserts that two JSON files are not equal.
*
* @param string $expectedFile
* @param string $actualFile
* @param string $message
*/
public static function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
{
self::assertFileExists($expectedFile, $message);
self::assertFileExists($actualFile, $message);
$actualJson = file_get_contents($actualFile);
$expectedJson = file_get_contents($expectedFile);
self::assertJson($expectedJson, $message);
self::assertJson($actualJson, $message);
// call constraint
$constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
$expectedJson
);
$constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
self::assertThat($expectedJson, new PHPUnit_Framework_Constraint_Not($constraintActual), $message);
self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraintExpected), $message);
}
/**
* Asserts that two JSON files are equal.
*
* @param string $expectedFile
* @param string $actualFile
* @param string $message
*/
public static function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
{
self::assertFileExists($expectedFile, $message);
self::assertFileExists($actualFile, $message);
$actualJson = file_get_contents($actualFile);
$expectedJson = file_get_contents($expectedFile);
self::assertJson($expectedJson, $message);
self::assertJson($actualJson, $message);
// call constraint
$constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
$expectedJson
);
$constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
self::assertThat($expectedJson, $constraintActual, $message);
self::assertThat($actualJson, $constraintExpected, $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_Callback matcher object.
*
* @param callable $callback
* @return PHPUnit_Framework_Constraint_Callback
*/
public static function callback($callback)
{
return new PHPUnit_Framework_Constraint_Callback($callback);
}
/**
* 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_IsJson matcher object.
*
* @return PHPUnit_Framework_Constraint_IsJson
* @since Method available since Release 3.7.20
*/
public static function isJson()
{
return new PHPUnit_Framework_Constraint_IsJson;
}
/**
* 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
* @param boolean $checkForObjectIdentity
* @return PHPUnit_Framework_Constraint_TraversableContains
* @since Method available since Release 3.0.0
*/
public static function contains($value, $checkForObjectIdentity = TRUE)
{
return new PHPUnit_Framework_Constraint_TraversableContains($value, $checkForObjectIdentity);
}
/**
* 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_TraversableContainsOnly matcher
* object.
*
* @param string $classname
* @return PHPUnit_Framework_Constraint_TraversableContainsOnly
*/
public static function containsOnlyInstancesOf($classname)
{
return new PHPUnit_Framework_Constraint_TraversableContainsOnly($classname, FALSE);
}
/**
* 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 $canonicalize
* @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, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return new PHPUnit_Framework_Constraint_IsEqual(
$value, $delta, $maxDepth, $canonicalize, $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 $canonicalize
* @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, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return self::attribute(
self::equalTo(
$value, $delta, $maxDepth, $canonicalize, $ignoreCase
),
$attributeName
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
*
* @return PHPUnit_Framework_Constraint_IsEmpty
* @since Method available since Release 3.5.0
*/
public static function isEmpty()
{
return new PHPUnit_Framework_Constraint_IsEmpty;
}
/**
* 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_StringMatches matcher object.
*
* @param string $string
* @return PHPUnit_Framework_Constraint_StringMatches
* @since Method available since Release 3.5.0
*/
public static function matches($string)
{
return new PHPUnit_Framework_Constraint_StringMatches($string);
}
/**
* 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 PHPUnit_Framework_Exception
*/
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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* 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:
*
* <code>
* <?php
* class MathTest extends PHPUnit_Framework_TestCase
* {
* public $value1;
* public $value2;
*
* protected function setUp()
* {
* $this->value1 = 2;
* $this->value2 = 3;
* }
* }
* ?>
* </code>
*
* For each test implement a method which interacts with the fixture.
* Verify the expected results with assertions specified by calling
* assert with a boolean.
*
* <code>
* <?php
* public function testPass()
* {
* $this->assertTrue($this->value1 + $this->value2 == 5);
* }
* ?>
* </code>
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
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
*/
private $inIsolation = FALSE;
/**
* @var array
*/
private $data = array();
/**
* @var string
*/
private $dataName = '';
/**
* @var boolean
*/
private $useErrorHandler = NULL;
/**
* @var boolean
*/
private $useOutputBuffering = NULL;
/**
* The name of the expected Exception.
*
* @var mixed
*/
private $expectedException = NULL;
/**
* The message of the expected Exception.
*
* @var string
*/
private $expectedExceptionMessage = '';
/**
* The code of the expected Exception.
*
* @var integer
*/
private $expectedExceptionCode;
/**
* The required preconditions for a test.
*
* @var array
*/
private $required = array(
'PHP' => NULL,
'PHPUnit' => NULL,
'functions' => array(),
'extensions' => array()
);
/**
* The name of the test case.
*
* @var string
*/
private $name = NULL;
/**
* @var array
*/
private $dependencies = array();
/**
* @var array
*/
private $dependencyInput = array();
/**
* @var array
*/
private $iniSettings = array();
/**
* @var array
*/
private $locale = array();
/**
* @var array
*/
private $mockObjects = array();
/**
* @var integer
*/
private $status;
/**
* @var string
*/
private $statusMessage = '';
/**
* @var integer
*/
private $numAssertions = 0;
/**
* @var PHPUnit_Framework_TestResult
*/
private $result;
/**
* @var mixed
*/
private $testResult;
/**
* @var string
*/
private $output = '';
/**
* @var string
*/
private $outputExpectedRegex = NULL;
/**
* @var string
*/
private $outputExpectedString = NULL;
/**
* @var bool
*/
private $hasPerformedExpectationsOnOutput = FALSE;
/**
* @var mixed
*/
private $outputCallback = FALSE;
/**
* @var boolean
*/
private $outputBufferingActive = FALSE;
/**
* 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;
}
}
/**
* Returns the size of the test.
*
* @return integer
* @since Method available since Release 3.6.0
*/
public function getSize()
{
return PHPUnit_Util_Test::getSize(
get_class($this), $this->getName(FALSE)
);
}
/**
* @return string
* @since Method available since Release 3.6.0
*/
public function getActualOutput()
{
if (!$this->outputBufferingActive) {
return $this->output;
} else {
return ob_get_contents();
}
}
/**
* @return string
* @since Method available since Release 3.6.0
*/
public function hasOutput()
{
if (strlen($this->output) === 0) {
return FALSE;
}
if ($this->outputExpectedString !== NULL ||
$this->outputExpectedRegex !== NULL ||
$this->hasPerformedExpectationsOnOutput) {
return FALSE;
}
return TRUE;
}
/**
* @param string $expectedRegex
* @since Method available since Release 3.6.0
*/
public function expectOutputRegex($expectedRegex)
{
if ($this->outputExpectedString !== NULL) {
throw new PHPUnit_Framework_Exception;
}
if (is_string($expectedRegex) || is_null($expectedRegex)) {
$this->outputExpectedRegex = $expectedRegex;
}
}
/**
* @param string $expectedString
* @since Method available since Release 3.6.0
*/
public function expectOutputString($expectedString)
{
if ($this->outputExpectedRegex !== NULL) {
throw new PHPUnit_Framework_Exception;
}
if (is_string($expectedString) || is_null($expectedString)) {
$this->outputExpectedString = $expectedString;
}
}
/**
* @return bool
* @since Method available since Release 3.6.5
*/
public function hasPerformedExpectationsOnOutput()
{
return $this->hasPerformedExpectationsOnOutput;
}
/**
* @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 = NULL)
{
$this->expectedException = $exceptionName;
$this->expectedExceptionMessage = $exceptionMessage;
$this->expectedExceptionCode = $exceptionCode;
}
/**
* @since Method available since Release 3.4.0
*/
protected function setExpectedExceptionFromAnnotation()
{
try {
$expectedException = PHPUnit_Util_Test::getExpectedException(
get_class($this), $this->name
);
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) {
}
}
/**
* @since Method available since Release 3.6.0
*/
protected function setRequirementsFromAnnotation()
{
try {
$requirements = PHPUnit_Util_Test::getRequirements(
get_class($this), $this->name
);
if (isset($requirements['PHP'])) {
$this->required['PHP'] = $requirements['PHP'];
}
if (isset($requirements['PHPUnit'])) {
$this->required['PHPUnit'] = $requirements['PHPUnit'];
}
if (isset($requirements['extensions'])) {
$this->required['extensions'] = $requirements['extensions'];
}
if (isset($requirements['functions'])) {
$this->required['functions'] = $requirements['functions'];
}
}
catch (ReflectionException $e) {
}
}
/**
* @since Method available since Release 3.6.0
*/
protected function checkRequirements()
{
$this->setRequirementsFromAnnotation();
$missingRequirements = array();
if ($this->required['PHP'] &&
version_compare(PHP_VERSION, $this->required['PHP'], '<')) {
$missingRequirements[] = sprintf(
'PHP %s (or later) is required.',
$this->required['PHP']
);
}
$phpunitVersion = PHPUnit_Runner_Version::id();
if ($this->required['PHPUnit'] &&
version_compare($phpunitVersion, $this->required['PHPUnit'], '<')) {
$missingRequirements[] = sprintf(
'PHPUnit %s (or later) is required.',
$this->required['PHPUnit']
);
}
foreach ($this->required['functions'] as $requiredFunction) {
if (!function_exists($requiredFunction)) {
$missingRequirements[] = sprintf(
'Function %s is required.',
$requiredFunction
);
}
}
foreach ($this->required['extensions'] as $requiredExtension) {
if (!extension_loaded($requiredExtension)) {
$missingRequirements[] = sprintf(
'Extension %s is required.',
$requiredExtension
);
}
}
if ($missingRequirements) {
$this->markTestSkipped(
implode(
PHP_EOL,
$missingRequirements
)
);
}
}
/**
* 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 PHPUnit_Framework_Exception
*/
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
if ($result === NULL) {
$result = $this->createResult();
}
if (!$this instanceof PHPUnit_Framework_Warning) {
$this->setTestResultObject($result);
$this->setUseErrorHandlerFromAnnotation();
$this->setUseOutputBufferingFromAnnotation();
}
if ($this->useErrorHandler !== NULL) {
$oldErrorHandlerSetting = $result->getConvertErrorsToExceptions();
$result->convertErrorsToExceptions($this->useErrorHandler);
}
if (!$this instanceof PHPUnit_Framework_Warning && !$this->handleDependencies()) {
return;
}
if ($this->runTestInSeparateProcess === TRUE &&
$this->inIsolation !== TRUE &&
!$this instanceof PHPUnit_Extensions_SeleniumTestCase &&
!$this instanceof PHPUnit_Extensions_PhptTestCase) {
$class = new ReflectionClass($this);
$template = new Text_Template(
sprintf(
'%s%sProcess%sTestCaseMethod.tpl',
__DIR__,
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR
)
);
if ($this->preserveGlobalState) {
$constants = PHPUnit_Util_GlobalState::getConstantsAsString();
$globals = PHPUnit_Util_GlobalState::getGlobalsAsString();
$includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString();
} else {
$constants = '';
$globals = '';
$includedFiles = '';
}
if ($result->getCollectCodeCoverageInformation()) {
$coverage = 'TRUE';
} else {
$coverage = 'FALSE';
}
if ($result->isStrict()) {
$strict = 'TRUE';
} else {
$strict = 'FALSE';
}
if (defined('PHPUNIT_COMPOSER_INSTALL')) {
$composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, TRUE);
} else {
$composerAutoload = '\'\'';
}
$data = var_export(serialize($this->data), TRUE);
$dependencyInput = var_export(serialize($this->dependencyInput), TRUE);
$includePath = var_export(get_include_path(), TRUE);
// must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
// the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
$data = "'." . $data . ".'";
$dependencyInput = "'." . $dependencyInput . ".'";
$includePath = "'." . $includePath . ".'";
$template->setVar(
array(
'composerAutoload' => $composerAutoload,
'filename' => $class->getFileName(),
'className' => $class->getName(),
'methodName' => $this->name,
'collectCodeCoverageInformation' => $coverage,
'data' => $data,
'dataName' => $this->dataName,
'dependencyInput' => $dependencyInput,
'constants' => $constants,
'globals' => $globals,
'include_path' => $includePath,
'included_files' => $includedFiles,
'strict' => $strict
)
);
$this->prepareTemplate($template);
$php = PHPUnit_Util_PHP::factory();
$php->runJob($template->render(), $this, $result);
} 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 ($this->backupStaticAttributes === TRUE) {
PHPUnit_Util_GlobalState::backupStaticAttributes(
$this->backupStaticAttributesBlacklist
);
}
}
// Start output buffering.
ob_start();
$this->outputBufferingActive = TRUE;
// Clean up stat cache.
clearstatcache();
// Backup the cwd
$currentWorkingDirectory = getcwd();
try {
if ($this->inIsolation) {
$this->setUpBeforeClass();
}
$this->setExpectedExceptionFromAnnotation();
$this->setUp();
$this->checkRequirements();
$this->assertPreConditions();
$this->testResult = $this->runTest();
$this->verifyMockObjects();
$this->assertPostConditions();
$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();
}
// Clean up the mock objects.
$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();
if ($this->inIsolation) {
$this->tearDownAfterClass();
}
}
catch (Exception $_e) {
if (!isset($e)) {
$e = $_e;
}
}
// Stop output buffering.
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->outputBufferingActive = FALSE;
// Clean up stat cache.
clearstatcache();
// Restore the cwd if it was changed by the test
if ($currentWorkingDirectory != getcwd()) {
chdir($currentWorkingDirectory);
}
// 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 ($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);
}
// Perform assertion on output.
if (!isset($e)) {
try {
if ($this->outputExpectedRegex !== NULL) {
$this->hasPerformedExpectationsOnOutput = TRUE;
$this->assertRegExp($this->outputExpectedRegex, $this->output);
$this->outputExpectedRegex = NULL;
}
else if ($this->outputExpectedString !== NULL) {
$this->hasPerformedExpectationsOnOutput = TRUE;
$this->assertEquals($this->outputExpectedString, $this->output);
$this->outputExpectedString = NULL;
}
}
catch (Exception $_e) {
$e = $_e;
}
}
// Workaround for missing "finally".
if (isset($e)) {
$this->onNotSuccessfulTest($e);
}
}
/**
* Override to run the test and assert its state.
*
* @return mixed
* @throws PHPUnit_Framework_Exception
*/
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) {
$checkException = FALSE;
if (is_string($this->expectedException)) {
$checkException = TRUE;
if ($e instanceof PHPUnit_Framework_Exception) {
$checkException = FALSE;
}
$reflector = new ReflectionClass($this->expectedException);
if ($this->expectedException == 'PHPUnit_Framework_Exception' ||
$reflector->isSubclassOf('PHPUnit_Framework_Exception')) {
$checkException = TRUE;
}
}
if ($checkException) {
$this->assertThat(
$e,
new PHPUnit_Framework_Constraint_Exception(
$this->expectedException
)
);
if (is_string($this->expectedExceptionMessage) &&
!empty($this->expectedExceptionMessage)) {
$this->assertThat(
$e,
new PHPUnit_Framework_Constraint_ExceptionMessage(
$this->expectedExceptionMessage
)
);
}
if ($this->expectedExceptionCode !== NULL) {
$this->assertThat(
$e,
new PHPUnit_Framework_Constraint_ExceptionCode(
$this->expectedExceptionCode
)
);
}
return;
} else {
throw $e;
}
}
if ($this->expectedException !== NULL) {
$this->assertThat(
NULL,
new PHPUnit_Framework_Constraint_Exception(
$this->expectedException
)
);
}
return $testResult;
}
/**
* Verifies the mock object expectations.
*
* @since Method available since Release 3.5.0
*/
protected function verifyMockObjects()
{
foreach ($this->mockObjects as $mockObject) {
if ($mockObject->__phpunit_hasMatchers()) {
$this->numAssertions++;
}
$mockObject->__phpunit_verify();
$mockObject->__phpunit_cleanup();
}
}
/**
* 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 PHPUnit_Framework_Exception
* @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 PHPUnit_Framework_Exception
* @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 PHPUnit_Framework_Exception
* @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');
}
}
/**
* @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;
}
/**
* @param callable $callback
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.6.0
*/
public function setOutputCallback($callback)
{
if (!is_callable($callback)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback');
}
$this->outputCallback = $callback;
}
/**
* @return PHPUnit_Framework_TestResult
* @since Method available since Release 3.5.7
*/
public function getTestResultObject()
{
return $this->result;
}
/**
* @param PHPUnit_Framework_TestResult $result
* @since Method available since Release 3.6.0
*/
public function setTestResultObject(PHPUnit_Framework_TestResult $result)
{
$this->result = $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 PHPUnit_Framework_Exception
* @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 PHPUnit_Framework_Exception
* @since Method available since Release 3.1.0
*/
protected function setLocale()
{
$args = func_get_args();
if (count($args) < 2) {
throw new PHPUnit_Framework_Exception;
}
$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 PHPUnit_Framework_Exception;
}
if (!is_array($locale) && !is_string($locale)) {
throw new PHPUnit_Framework_Exception;
}
$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
* @param boolean $cloneArguments
* @return PHPUnit_Framework_MockObject_MockObject
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.0.0
*/
public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE)
{
$mockObject = PHPUnit_Framework_MockObject_Generator::getMock(
$originalClassName,
$methods,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
$this->mockObjects[] = $mockObject;
return $mockObject;
}
/**
* Returns a builder object to create mock objects using a fluent interface.
*
* @param string $className
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 3.5.0
*/
public function getMockBuilder($className)
{
return new PHPUnit_Framework_MockObject_MockBuilder(
$this, $className
);
}
/**
* Mocks the specified class and returns the name of the mocked class.
*
* @param string $originalClassName
* @param array $methods
* @param array $arguments
* @param string $mockClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @return string
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.5.0
*/
protected function getMockClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = FALSE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE)
{
$mock = $this->getMock(
$originalClassName,
$methods,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
return get_class($mock);
}
/**
* Returns a mock object for the specified abstract class with all abstract
* methods of the class mocked. Concrete methods to mock can be specified with
* the last parameter
*
* @param string $originalClassName
* @param array $arguments
* @param string $mockClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param array $mockedMethods
* @param boolean $cloneArguments
* @return PHPUnit_Framework_MockObject_MockObject
* @since Method available since Release 3.4.0
* @throws PHPUnit_Framework_Exception
*/
public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $mockedMethods = array(), $cloneArguments = FALSE)
{
$mockObject = PHPUnit_Framework_MockObject_Generator::getMockForAbstractClass(
$originalClassName,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$mockedMethods,
$cloneArguments
);
$this->mockObjects[] = $mockObject;
return $mockObject;
}
/**
* 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 PHPUnit_Framework_MockObject_MockObject
* @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)
);
}
if (!class_exists($originalClassName)) {
eval(
PHPUnit_Framework_MockObject_Generator::generateClassFromWsdl(
$wsdlFile, $originalClassName, $methods
)
);
}
return $this->getMock(
$originalClassName,
$methods,
array('', array()),
$mockClassName,
$callOriginalConstructor,
FALSE,
FALSE
);
}
/**
* Returns an object for the specified trait.
*
* @param string $traitName
* @param array $arguments
* @param string $traitClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @return object
* @since Method available since Release 3.6.0
* @throws PHPUnit_Framework_Exception
*/
protected function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE)
{
return PHPUnit_Framework_MockObject_Generator::getObjectForTrait(
$traitName,
$arguments,
$traitClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
}
/**
* 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
*/
public static 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
*/
public static 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
*/
public static 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
*/
public static 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
*/
public static 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
*/
public static 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
*/
public static function returnValue($value)
{
return new PHPUnit_Framework_MockObject_Stub_Return($value);
}
/**
*
*
* @param array $valueMap
* @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
* @since Method available since Release 3.6.0
*/
public static function returnValueMap(array $valueMap)
{
return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap);
}
/**
*
*
* @param integer $argumentIndex
* @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
* @since Method available since Release 3.3.0
*/
public static 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
*/
public static function returnCallback($callback)
{
return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback);
}
/**
* Returns the current object.
*
* This method is useful when mocking a fluent interface.
*
* @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
* @since Method available since Release 3.6.0
*/
public static function returnSelf()
{
return new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
}
/**
*
*
* @param Exception $exception
* @return PHPUnit_Framework_MockObject_Stub_Exception
* @since Method available since Release 3.1.0
*/
public static 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
*/
public static 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();
// There seems to be no other way to check arrays for recursion
// http://www.php.net/manual/en/language.types.array.php#73936
preg_match_all('/\n \[(\w+)\] => Array\s+\*RECURSION\*/', print_r($data, TRUE), $matches);
$recursiveKeys = array_unique($matches[1]);
// Convert to valid array keys
// Numeric integer strings are automatically converted to integers
// by PHP
foreach ($recursiveKeys as $key => $recursiveKey) {
if ((string)(integer)$recursiveKey === $recursiveKey) {
$recursiveKeys[$key] = (integer)$recursiveKey;
}
}
foreach ($data as $key => $_data) {
if (in_array($key, $recursiveKeys, TRUE)) {
$result[] = '*RECURSION*';
}
else 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[] = '<resource>';
}
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;
}
/**
* @since Method available since Release 3.5.4
*/
protected function handleDependencies()
{
if (!empty($this->dependencies) && !$this->inIsolation) {
$className = get_class($this);
$passed = $this->result->passed();
$passedKeys = array_keys($passed);
$numKeys = count($passedKeys);
for ($i = 0; $i < $numKeys; $i++) {
$pos = strpos($passedKeys[$i], ' with data set');
if ($pos !== FALSE) {
$passedKeys[$i] = substr($passedKeys[$i], 0, $pos);
}
}
$passedKeys = array_flip(array_unique($passedKeys));
foreach ($this->dependencies as $dependency) {
if (strpos($dependency, '::') === FALSE) {
$dependency = $className . '::' . $dependency;
}
if (!isset($passedKeys[$dependency])) {
$this->result->addError(
$this,
new PHPUnit_Framework_SkippedTestError(
sprintf(
'This test depends on "%s" to pass.', $dependency
)
),
0
);
return FALSE;
}
if (isset($passed[$dependency])) {
if ($passed[$dependency]['size'] > $this->getSize()) {
$this->result->addError(
$this,
new PHPUnit_Framework_SkippedTestError(
'This test depends on a test that is larger than itself.'
),
0
);
return FALSE;
}
$this->dependencyInput[] = $passed[$dependency]['result'];
} else {
$this->dependencyInput[] = NULL;
}
}
}
return TRUE;
}
/**
* 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 Text_Template $template
* @since Method available since Release 3.4.0
*/
protected function prepareTemplate(Text_Template $template)
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.0
*/
/**
* 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
*/
function any()
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::any',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
*
* @return PHPUnit_Framework_Constraint_IsAnything
* @since Method available since Release 3.0.0
*/
function anything()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::anything',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
*
* @param mixed $key
* @return PHPUnit_Framework_Constraint_ArrayHasKey
* @since Method available since Release 3.0.0
*/
function arrayHasKey($key)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::arrayHasKey',
func_get_args()
);
}
/**
* Asserts that an array has a specified key.
*
* @param mixed $key
* @param array|ArrayAccess $array
* @param string $message
* @since Method available since Release 3.0.0
*/
function assertArrayHasKey($key, $array, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertArrayHasKey',
func_get_args()
);
}
/**
* Asserts that an array does not have a specified key.
*
* @param mixed $key
* @param array|ArrayAccess $array
* @param string $message
* @since Method available since Release 3.0.0
*/
function assertArrayNotHasKey($key, $array, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertArrayNotHasKey',
func_get_args()
);
}
/**
* 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
* @param boolean $checkForObjectIdentity
* @since Method available since Release 3.0.0
*/
function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeContains',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = NULL, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeContainsOnly',
func_get_args()
);
}
/**
* Asserts the number of elements of an array, Countable or Iterator
* that is stored in an attribute.
*
* @param integer $expectedCount
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.6.0
*/
function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeCount',
func_get_args()
);
}
/**
* Asserts that a static attribute of a class or an attribute of an object
* is empty.
*
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeEmpty',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
*/
function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeEquals',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeGreaterThan',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeGreaterThanOrEqual',
func_get_args()
);
}
/**
* 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.5.0
*/
function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeInstanceOf',
func_get_args()
);
}
/**
* 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.5.0
*/
function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeInternalType',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeLessThan',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeLessThanOrEqual',
func_get_args()
);
}
/**
* 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
* @param boolean $checkForObjectIdentity
* @since Method available since Release 3.0.0
*/
function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotContains',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = NULL, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotContainsOnly',
func_get_args()
);
}
/**
* Asserts the number of elements of an array, Countable or Iterator
* that is stored in an attribute.
*
* @param integer $expectedCount
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.6.0
*/
function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotCount',
func_get_args()
);
}
/**
* Asserts that a static attribute of a class or an attribute of an object
* is not empty.
*
* @param string $haystackAttributeName
* @param mixed $haystackClassOrObject
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotEmpty',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
*/
function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotEquals',
func_get_args()
);
}
/**
* 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.5.0
*/
function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotInstanceOf',
func_get_args()
);
}
/**
* 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.5.0
*/
function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotInternalType',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeNotSame',
func_get_args()
);
}
/**
* 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
*/
function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertAttributeSame',
func_get_args()
);
}
/**
* 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
*/
function assertClassHasAttribute($attributeName, $className, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertClassHasAttribute',
func_get_args()
);
}
/**
* 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
*/
function assertClassHasStaticAttribute($attributeName, $className, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertClassHasStaticAttribute',
func_get_args()
);
}
/**
* 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
*/
function assertClassNotHasAttribute($attributeName, $className, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertClassNotHasAttribute',
func_get_args()
);
}
/**
* 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
*/
function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute',
func_get_args()
);
}
/**
* Asserts that a haystack contains a needle.
*
* @param mixed $needle
* @param mixed $haystack
* @param string $message
* @param boolean $ignoreCase
* @param boolean $checkForObjectIdentity
* @since Method available since Release 2.1.0
*/
function assertContains($needle, $haystack, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertContains',
func_get_args()
);
}
/**
* 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
*/
function assertContainsOnly($type, $haystack, $isNativeType = NULL, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertContainsOnly',
func_get_args()
);
}
/**
* Asserts that a haystack contains only instances of a given classname
*
* @param string $classname
* @param array|Traversable $haystack
* @param string $message
*/
function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf',
func_get_args()
);
}
/**
* Asserts the number of elements of an array, Countable or Iterator.
*
* @param integer $expectedCount
* @param mixed $haystack
* @param string $message
*/
function assertCount($expectedCount, $haystack, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertCount',
func_get_args()
);
}
/**
* Asserts that a variable is empty.
*
* @param mixed $actual
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
function assertEmpty($actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertEmpty',
func_get_args()
);
}
/**
* Asserts that a hierarchy of DOMElements matches.
*
* @param DOMElement $expectedElement
* @param DOMElement $actualElement
* @param boolean $checkAttributes
* @param string $message
* @author Mattis Stordalen Flister <mattis@xait.no>
* @since Method available since Release 3.3.0
*/
function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = FALSE, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertEqualXMLStructure',
func_get_args()
);
}
/**
* Asserts that two variables are equal.
*
* @param mixed $expected
* @param mixed $actual
* @param string $message
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
*/
function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertEquals',
func_get_args()
);
}
/**
* Asserts that a condition is false.
*
* @param boolean $condition
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
function assertFalse($condition, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertFalse',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.2.14
*/
function assertFileEquals($expected, $actual, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertFileEquals',
func_get_args()
);
}
/**
* Asserts that a file exists.
*
* @param string $filename
* @param string $message
* @since Method available since Release 3.0.0
*/
function assertFileExists($filename, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertFileExists',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.2.14
*/
function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertFileNotEquals',
func_get_args()
);
}
/**
* Asserts that a file does not exist.
*
* @param string $filename
* @param string $message
* @since Method available since Release 3.0.0
*/
function assertFileNotExists($filename, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertFileNotExists',
func_get_args()
);
}
/**
* 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
*/
function assertGreaterThan($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertGreaterThan',
func_get_args()
);
}
/**
* 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
*/
function assertGreaterThanOrEqual($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertGreaterThanOrEqual',
func_get_args()
);
}
/**
* Asserts that a variable is of a given type.
*
* @param string $expected
* @param mixed $actual
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertInstanceOf($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertInstanceOf',
func_get_args()
);
}
/**
* Asserts that a variable is of a given type.
*
* @param string $expected
* @param mixed $actual
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertInternalType($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertInternalType',
func_get_args()
);
}
/**
* Asserts that a string is a valid JSON string.
*
* @param string $filename
* @param string $message
* @since Method available since Release 3.7.20
*/
function assertJson($expectedJson, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJson',
func_get_args()
);
}
/**
* Asserts that two JSON files are equal.
*
* @param string $expectedFile
* @param string $actualFile
* @param string $message
*/
function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJsonFileEqualsJsonFile',
func_get_args()
);
}
/**
* Asserts that two JSON files are not equal.
*
* @param string $expectedFile
* @param string $actualFile
* @param string $message
*/
function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJsonFileNotEqualsJsonFile',
func_get_args()
);
}
/**
* Asserts that the generated JSON encoded object and the content of the given file are equal.
*
* @param string $expectedFile
* @param string $actualJson
* @param string $message
*/
function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile',
func_get_args()
);
}
/**
* Asserts that two given JSON encoded objects or arrays are equal.
*
* @param string $expectedJson
* @param string $actualJson
* @param string $message
*/
function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString',
func_get_args()
);
}
/**
* Asserts that the generated JSON encoded object and the content of the given file are not equal.
*
* @param string $expectedFile
* @param string $actualJson
* @param string $message
*/
function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile',
func_get_args()
);
}
/**
* Asserts that two given JSON encoded objects or arrays are not equal.
*
* @param string $expectedJson
* @param string $actualJson
* @param string $message
*/
function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString',
func_get_args()
);
}
/**
* 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
*/
function assertLessThan($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertLessThan',
func_get_args()
);
}
/**
* 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
*/
function assertLessThanOrEqual($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertLessThanOrEqual',
func_get_args()
);
}
/**
* Asserts that a haystack does not contain a needle.
*
* @param mixed $needle
* @param mixed $haystack
* @param string $message
* @param boolean $ignoreCase
* @param boolean $checkForObjectIdentity
* @since Method available since Release 2.1.0
*/
function assertNotContains($needle, $haystack, $message = '', $ignoreCase = FALSE, $checkForObjectIdentity = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotContains',
func_get_args()
);
}
/**
* 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
*/
function assertNotContainsOnly($type, $haystack, $isNativeType = NULL, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotContainsOnly',
func_get_args()
);
}
/**
* Asserts the number of elements of an array, Countable or Iterator.
*
* @param integer $expectedCount
* @param mixed $haystack
* @param string $message
*/
function assertNotCount($expectedCount, $haystack, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotCount',
func_get_args()
);
}
/**
* Asserts that a variable is not empty.
*
* @param mixed $actual
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
function assertNotEmpty($actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotEmpty',
func_get_args()
);
}
/**
* Asserts that two variables are not equal.
*
* @param mixed $expected
* @param mixed $actual
* @param string $message
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 2.3.0
*/
function assertNotEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotEquals',
func_get_args()
);
}
/**
* Asserts that a variable is not of a given type.
*
* @param string $expected
* @param mixed $actual
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertNotInstanceOf($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotInstanceOf',
func_get_args()
);
}
/**
* Asserts that a variable is not of a given type.
*
* @param string $expected
* @param mixed $actual
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertNotInternalType($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotInternalType',
func_get_args()
);
}
/**
* Asserts that a variable is not NULL.
*
* @param mixed $actual
* @param string $message
*/
function assertNotNull($actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotNull',
func_get_args()
);
}
/**
* 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
*/
function assertNotRegExp($pattern, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotRegExp',
func_get_args()
);
}
/**
* 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
*/
function assertNotSame($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotSame',
func_get_args()
);
}
/**
* Assert that the size of two arrays (or `Countable` or `Iterator` objects)
* is not the same.
*
* @param array|Countable|Iterator $expected
* @param array|Countable|Iterator $actual
* @param string $message
*/
function assertNotSameSize($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotSameSize',
func_get_args()
);
}
/**
* 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
function assertNotTag($matcher, $actual, $message = '', $isHtml = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotTag',
func_get_args()
);
}
/**
* Asserts that a variable is NULL.
*
* @param mixed $actual
* @param string $message
*/
function assertNull($actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNull',
func_get_args()
);
}
/**
* 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
*/
function assertObjectHasAttribute($attributeName, $object, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertObjectHasAttribute',
func_get_args()
);
}
/**
* 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
*/
function assertObjectNotHasAttribute($attributeName, $object, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertObjectNotHasAttribute',
func_get_args()
);
}
/**
* Asserts that a string matches a given regular expression.
*
* @param string $pattern
* @param string $string
* @param string $message
*/
function assertRegExp($pattern, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertRegExp',
func_get_args()
);
}
/**
* 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
*/
function assertSame($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertSame',
func_get_args()
);
}
/**
* Assert that the size of two arrays (or `Countable` or `Iterator` objects)
* is the same.
*
* @param array|Countable|Iterator $expected
* @param array|Countable|Iterator $actual
* @param string $message
*/
function assertSameSize($expected, $actual, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertSameSize',
func_get_args()
);
}
/**
* 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertSelectCount',
func_get_args()
);
}
/**
* 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertSelectEquals',
func_get_args()
);
}
/**
* 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertSelectRegExp',
func_get_args()
);
}
/**
* 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
*/
function assertStringEndsNotWith($suffix, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringEndsNotWith',
func_get_args()
);
}
/**
* 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
*/
function assertStringEndsWith($suffix, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringEndsWith',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.3.0
*/
function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringEqualsFile',
func_get_args()
);
}
/**
* Asserts that a string matches a given format string.
*
* @param string $format
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertStringMatchesFormat($format, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringMatchesFormat',
func_get_args()
);
}
/**
* Asserts that a string matches a given format file.
*
* @param string $formatFile
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertStringMatchesFormatFile($formatFile, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringMatchesFormatFile',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
* @since Method available since Release 3.3.0
*/
function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringNotEqualsFile',
func_get_args()
);
}
/**
* Asserts that a string does not match a given format string.
*
* @param string $format
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertStringNotMatchesFormat($format, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringNotMatchesFormat',
func_get_args()
);
}
/**
* Asserts that a string does not match a given format string.
*
* @param string $formatFile
* @param string $string
* @param string $message
* @since Method available since Release 3.5.0
*/
function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile',
func_get_args()
);
}
/**
* 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
*/
function assertStringStartsNotWith($prefix, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringStartsNotWith',
func_get_args()
);
}
/**
* 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
*/
function assertStringStartsWith($prefix, $string, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertStringStartsWith',
func_get_args()
);
}
/**
* 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
*
* <code>
* // 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' => 'regexp:/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);
* </code>
*
* 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
function assertTag($matcher, $actual, $message = '', $isHtml = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertTag',
func_get_args()
);
}
/**
* 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
*/
function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertThat',
func_get_args()
);
}
/**
* Asserts that a condition is true.
*
* @param boolean $condition
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
function assertTrue($condition, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertTrue',
func_get_args()
);
}
/**
* Asserts that two XML files are equal.
*
* @param string $expectedFile
* @param string $actualFile
* @param string $message
* @since Method available since Release 3.1.0
*/
function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile',
func_get_args()
);
}
/**
* 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
*/
function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile',
func_get_args()
);
}
/**
* Asserts that two XML documents are equal.
*
* @param string $expectedFile
* @param string $actualXml
* @param string $message
* @since Method available since Release 3.3.0
*/
function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile',
func_get_args()
);
}
/**
* Asserts that two XML documents are equal.
*
* @param string $expectedXml
* @param string $actualXml
* @param string $message
* @since Method available since Release 3.1.0
*/
function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString',
func_get_args()
);
}
/**
* 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
*/
function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile',
func_get_args()
);
}
/**
* 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
*/
function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString',
func_get_args()
);
}
/**
* 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
*/
function at($index)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::at',
func_get_args()
);
}
/**
* 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
*/
function atLeastOnce()
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::atLeastOnce',
func_get_args()
);
}
/**
* 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
*/
function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::attribute',
func_get_args()
);
}
/**
* 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 $canonicalize
* @param boolean $ignoreCase
* @return PHPUnit_Framework_Constraint_Attribute
* @since Method available since Release 3.1.0
*/
function attributeEqualTo($attributeName, $value, $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::attributeEqualTo',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_Callback matcher object.
*
* @param callable $callback
* @return PHPUnit_Framework_Constraint_Callback
*/
function callback($callback)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::callback',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
*
* @param string $attributeName
* @return PHPUnit_Framework_Constraint_ClassHasAttribute
* @since Method available since Release 3.1.0
*/
function classHasAttribute($attributeName)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::classHasAttribute',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
* object.
*
* @param string $attributeName
* @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
* @since Method available since Release 3.1.0
*/
function classHasStaticAttribute($attributeName)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::classHasStaticAttribute',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
* object.
*
* @param mixed $value
* @param boolean $checkForObjectIdentity
* @return PHPUnit_Framework_Constraint_TraversableContains
* @since Method available since Release 3.0.0
*/
function contains($value, $checkForObjectIdentity = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::contains',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
* object.
*
* @param string $type
* @return PHPUnit_Framework_Constraint_TraversableContainsOnly
* @since Method available since Release 3.1.4
*/
function containsOnly($type)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::containsOnly',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
* object.
*
* @param string $classname
* @return PHPUnit_Framework_Constraint_TraversableContainsOnly
*/
function containsOnlyInstancesOf($classname)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::containsOnlyInstancesOf',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
*
* @param mixed $value
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
* @return PHPUnit_Framework_Constraint_IsEqual
* @since Method available since Release 3.0.0
*/
function equalTo($value, $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::equalTo',
func_get_args()
);
}
/**
* 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
*/
function exactly($count)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::exactly',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
*
* @return PHPUnit_Framework_Constraint_FileExists
* @since Method available since Release 3.0.0
*/
function fileExists()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::fileExists',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
*
* @param mixed $value
* @return PHPUnit_Framework_Constraint_GreaterThan
* @since Method available since Release 3.0.0
*/
function greaterThan($value)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::greaterThan',
func_get_args()
);
}
/**
* 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
*/
function greaterThanOrEqual($value)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::greaterThanOrEqual',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
*
* @param mixed $value
* @return PHPUnit_Framework_Constraint_IsIdentical
* @since Method available since Release 3.0.0
*/
function identicalTo($value)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::identicalTo',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
*
* @return PHPUnit_Framework_Constraint_IsEmpty
* @since Method available since Release 3.5.0
*/
function isEmpty()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isEmpty',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
*
* @return PHPUnit_Framework_Constraint_IsFalse
* @since Method available since Release 3.3.0
*/
function isFalse()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isFalse',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
*
* @param string $className
* @return PHPUnit_Framework_Constraint_IsInstanceOf
* @since Method available since Release 3.0.0
*/
function isInstanceOf($className)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isInstanceOf',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
*
* @return PHPUnit_Framework_Constraint_IsJson
* @since Method available since Release 3.7.20
*/
function isJson()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isJson',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
*
* @return PHPUnit_Framework_Constraint_IsNull
* @since Method available since Release 3.3.0
*/
function isNull()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isNull',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
*
* @return PHPUnit_Framework_Constraint_IsTrue
* @since Method available since Release 3.3.0
*/
function isTrue()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isTrue',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_IsType matcher object.
*
* @param string $type
* @return PHPUnit_Framework_Constraint_IsType
* @since Method available since Release 3.0.0
*/
function isType($type)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::isType',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
*
* @param mixed $value
* @return PHPUnit_Framework_Constraint_LessThan
* @since Method available since Release 3.0.0
*/
function lessThan($value)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::lessThan',
func_get_args()
);
}
/**
* 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
*/
function lessThanOrEqual($value)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::lessThanOrEqual',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_And matcher object.
*
* @return PHPUnit_Framework_Constraint_And
* @since Method available since Release 3.0.0
*/
function logicalAnd()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::logicalAnd',
func_get_args()
);
}
/**
* 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
*/
function logicalNot(PHPUnit_Framework_Constraint $constraint)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::logicalNot',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_Or matcher object.
*
* @return PHPUnit_Framework_Constraint_Or
* @since Method available since Release 3.0.0
*/
function logicalOr()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::logicalOr',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_Xor matcher object.
*
* @return PHPUnit_Framework_Constraint_Xor
* @since Method available since Release 3.0.0
*/
function logicalXor()
{
return call_user_func_array(
'PHPUnit_Framework_Assert::logicalXor',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
*
* @param string $string
* @return PHPUnit_Framework_Constraint_StringMatches
* @since Method available since Release 3.5.0
*/
function matches($string)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::matches',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
*
* @param string $pattern
* @return PHPUnit_Framework_Constraint_PCREMatch
* @since Method available since Release 3.0.0
*/
function matchesRegularExpression($pattern)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::matchesRegularExpression',
func_get_args()
);
}
/**
* 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
*/
function never()
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::never',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
*
* @param string $attributeName
* @return PHPUnit_Framework_Constraint_ObjectHasAttribute
* @since Method available since Release 3.0.0
*/
function objectHasAttribute($attributeName)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::objectHasAttribute',
func_get_args()
);
}
/**
*
*
* @param mixed $value, ...
* @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
* @since Method available since Release 3.0.0
*/
function onConsecutiveCalls()
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::onConsecutiveCalls',
func_get_args()
);
}
/**
* 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
*/
function once()
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::once',
func_get_args()
);
}
/**
*
*
* @param integer $argumentIndex
* @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
* @since Method available since Release 3.3.0
*/
function returnArgument($argumentIndex)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::returnArgument',
func_get_args()
);
}
/**
*
*
* @param mixed $callback
* @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
* @since Method available since Release 3.3.0
*/
function returnCallback($callback)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::returnCallback',
func_get_args()
);
}
/**
* Returns the current object.
*
* This method is useful when mocking a fluent interface.
*
* @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
* @since Method available since Release 3.6.0
*/
function returnSelf()
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::returnSelf',
func_get_args()
);
}
/**
*
*
* @param mixed $value
* @return PHPUnit_Framework_MockObject_Stub_Return
* @since Method available since Release 3.0.0
*/
function returnValue($value)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::returnValue',
func_get_args()
);
}
/**
*
*
* @param array $valueMap
* @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
* @since Method available since Release 3.6.0
*/
function returnValueMap(array $valueMap)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::returnValueMap',
func_get_args()
);
}
/**
* 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
*/
function stringContains($string, $case = TRUE)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::stringContains',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
*
* @param mixed $suffix
* @return PHPUnit_Framework_Constraint_StringEndsWith
* @since Method available since Release 3.4.0
*/
function stringEndsWith($suffix)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::stringEndsWith',
func_get_args()
);
}
/**
* Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
*
* @param mixed $prefix
* @return PHPUnit_Framework_Constraint_StringStartsWith
* @since Method available since Release 3.4.0
*/
function stringStartsWith($prefix)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::stringStartsWith',
func_get_args()
);
}
/**
*
*
* @param Exception $exception
* @return PHPUnit_Framework_MockObject_Stub_Exception
* @since Method available since Release 3.1.0
*/
function throwException(Exception $exception)
{
return call_user_func_array(
'PHPUnit_Framework_TestCase::throwException',
func_get_args()
);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.0
*/{functions}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of an incomplete test.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of a test that printed output.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_OutputError extends PHPUnit_Framework_AssertionFailedError
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Exception for PHPUnit runtime errors.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.4.0
*/
class PHPUnit_Framework_Exception extends RuntimeException
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A warning.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 = '';
/**
* @var boolean
*/
protected $backupGlobals = FALSE;
/**
* @var boolean
*/
protected $backupStaticAttributes = FALSE;
/**
* @var boolean
*/
protected $runTestInSeparateProcess = FALSE;
/**
* @var boolean
*/
protected $useErrorHandler = FALSE;
/**
* @var boolean
*/
protected $useOutputBuffering = FALSE;
/**
* @param string $message
*/
public function __construct($message = '')
{
$this->message = $message;
parent::__construct('Warning');
}
/**
* @throws PHPUnit_Framework_Exception
*/
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';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Thrown when an assertion for string equality failed.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
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;
/**
* The string representation of the expected value
* @var string
*/
protected $expectedAsString;
/**
* The string representation of the actual value
* @var string
*/
protected $actualAsString;
/**
* @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 string $expectedAsString
* @param string $actualAsString
* @param boolean $identical
* @param string $message A string which is prefixed on all returned lines
* in the difference output.
*/
public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = FALSE, $message = '')
{
$this->expected = $expected;
$this->actual = $actual;
$this->expectedAsString = $expectedAsString;
$this->actualAsString = $actualAsString;
$this->message = $message;
}
/**
* @return mixed
*/
public function getActual()
{
return $this->actual;
}
/**
* @return mixed
*/
public function getExpected()
{
return $this->expected;
}
/**
* @return string
*/
public function getActualAsString()
{
return $this->actualAsString;
}
/**
* @return string
*/
public function getExpectedAsString()
{
return $this->expectedAsString;
}
/**
* @return string
*/
public function getDiff()
{
return $this->actualAsString || $this->expectedAsString
? PHPUnit_Util_Diff::diff($this->expectedAsString, $this->actualAsString)
: '';
}
/**
* @return string
*/
public function toString()
{
return $this->message . $this->getDiff();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of a skipped test.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that asserts that the object it is evaluated for has a given
* attribute.
*
* The attribute name is passed in the constructor.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
$object = new ReflectionObject($other);
return $object->hasProperty($this->attributeName);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($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
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.6
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.6
*/
class PHPUnit_Framework_Constraint_ExceptionCode extends PHPUnit_Framework_Constraint
{
/**
* @var integer
*/
protected $expectedCode;
/**
* @param integer $expected
*/
public function __construct($expected)
{
$this->expectedCode = $expected;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* @param Exception $other
* @return boolean
*/
protected function matches($other)
{
return (string)$other->getCode() == (string)$this->expectedCode;
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
'%s is equal to expected exception code %s',
PHPUnit_Util_Type::export($other->getCode()),
PHPUnit_Util_Type::export($this->expectedCode)
);
}
/**
* @return string
*/
public function toString()
{
return 'exception code is ';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return ($other instanceof $this->className);
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
'%s is an instance of class "%s"',
PHPUnit_Util_Type::shortenedExport($other),
$this->className
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf(
'is instance of class "%s"',
$this->className
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Constraint_SameSize extends PHPUnit_Framework_Constraint_Count
{
/**
* @var integer
*/
protected $expectedCount;
/**
* @param integer $expected
*/
public function __construct($expected)
{
parent::__construct($this->getCountOf($expected));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Kore Nordmann <kn@ez.no>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Kore Nordmann <kn@ez.no>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 $canonicalize = FALSE;
/**
* @var boolean
*/
protected $ignoreCase = FALSE;
/**
* @var PHPUnit_Framework_ComparisonFailure
*/
protected $lastFailure;
/**
* @param mixed $value
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
*/
public function __construct($value, $delta = 0, $maxDepth = 10, $canonicalize = 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($canonicalize)) {
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->canonicalize = $canonicalize;
$this->ignoreCase = $ignoreCase;
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$comparatorFactory = PHPUnit_Framework_ComparatorFactory::getDefaultInstance();
try {
$comparator = $comparatorFactory->getComparatorFor(
$other, $this->value
);
$comparator->assertEquals(
$this->value,
$other,
$this->delta,
$this->canonicalize,
$this->ignoreCase
);
}
catch (PHPUnit_Framework_ComparisonFailure $f) {
if ($returnResult) {
return FALSE;
}
throw new PHPUnit_Framework_ExpectationFailedException(
trim($description . "\n" . $f->getMessage()),
$f
);
}
return TRUE;
}
/**
* 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 <text>';
} else {
return sprintf(
'is equal to <string:%s>',
$this->value
);
}
} else {
if ($this->delta != 0) {
$delta = sprintf(
' with delta <%F>',
$this->delta
);
}
return sprintf(
'is equal to %s%s',
PHPUnit_Util_Type::export($this->value),
$delta
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* Constraint that accepts NULL.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return $other === NULL;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is null';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.7.20
*/
/**
* Constraint that asserts that a string is valid JSON.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.7.20
*/
class PHPUnit_Framework_Constraint_IsJson 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
*/
protected function matches($other)
{
json_decode($other);
if (json_last_error()) {
return FALSE;
}
return TRUE;
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
json_decode($other);
$error = PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError(
json_last_error()
);
return sprintf(
'%s is valid JSON (%s)',
PHPUnit_Util_Type::shortenedExport($other),
$error
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is valid JSON';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* Constraint that accepts TRUE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return $other === TRUE;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is true';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($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::export($this->key);
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return 'an array ' . $this->toString();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.0.0
*/
class PHPUnit_Framework_Constraint_IsIdentical extends PHPUnit_Framework_Constraint
{
/**
* @var double
*/
const EPSILON = 0.0000000001;
/**
* @var mixed
*/
protected $value;
/**
* @param mixed $value
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
if (is_double($this->value) && is_double($other) &&
!is_infinite($this->value) && !is_infinite($other) &&
!is_nan($this->value) && !is_nan($other)) {
$success = abs($this->value - $other) < self::EPSILON;
}
else {
$success = $this->value === $other;
}
if ($returnResult) {
return $success;
}
if (!$success) {
$f = NULL;
// if both values are strings, make sure a diff is generated
if (is_string($this->value) && is_string($other)) {
$f = new PHPUnit_Framework_ComparisonFailure(
$this->value,
$other,
$this->value,
$other
);
}
$this->fail($other, $description, $f);
}
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
if (is_object($this->value) && is_object($other)) {
return 'two variables reference the same object';
}
if (is_string($this->value) && is_string($other)) {
return 'two strings are identical';
}
return parent::failureDescription($other);
}
/**
* 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::export($this->value);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.6
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.6
*/
class PHPUnit_Framework_Constraint_Exception 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
*/
protected function matches($other)
{
return $other instanceof $this->className;
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
if ($other !== NULL) {
$message = '';
if ($other instanceof Exception && $other->getMessage()) {
$message = '. Message was: "' . $other->getMessage() . '"';
}
return sprintf(
'exception of type "%s" matches expected exception "%s"%s',
get_class($other),
$this->className,
$message
);
}
return sprintf(
'exception of type "%s" is thrown',
$this->className
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf(
'exception of type "%s"',
$this->className
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Logical AND.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
* @throws PHPUnit_Framework_Exception
*/
public function setConstraints(array $constraints)
{
$this->constraints = array();
foreach ($constraints as $key => $constraint) {
if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
throw new PHPUnit_Framework_Exception(
'All parameters to ' . __CLASS__ .
' must be a constraint object.'
);
}
$this->constraints[] = $constraint;
}
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$success = TRUE;
$constraint = NULL;
foreach ($this->constraints as $constraint) {
if (!$constraint->evaluate($other, $description, TRUE)) {
$success = FALSE;
break;
}
}
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
}
/**
* 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 = 0;
foreach ($this->constraints as $constraint) {
$count += count($constraint);
}
return $count;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.4
*/
/**
* Constraint that asserts that the Traversable it is applied to contains
* only values of a given type.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$success = TRUE;
$constraint = NULL;
foreach ($other as $item) {
if (!$this->constraint->evaluate($item, '', TRUE)) {
$success = FALSE;
break;
}
}
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'contains only values of type "' . $this->type . '"';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
*/
/**
* Constraint that evaluates against a specified closure.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Timon Rapp <timon@zaeda.net>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
*/
class PHPUnit_Framework_Constraint_Callback extends PHPUnit_Framework_Constraint
{
private $callback;
/**
* @param callable $callback
* @throws InvalidArgumentException
*/
public function __construct($callback)
{
if (!is_callable($callback)) {
throw new InvalidArgumentException(
sprintf(
'Specified callback <%s> is not callable.',
$this->callbackToString($callback)
)
);
}
$this->callback = $callback;
}
/**
* Evaluates the constraint for parameter $value. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* @param mixed $value Value or object to evaluate.
* @return bool
*/
protected function matches($other)
{
return call_user_func($this->callback, $other);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is accepted by specified callback';
}
private function callbackToString($callback)
{
if (!is_array($callback)) {
return $callback;
}
if (empty($callback)) {
return "empty array";
}
if (!isset($callback[0]) || !isset($callback[1])) {
return "array without indexes 0 and 1 set";
}
if (is_object($callback[0])) {
$callback[0] = get_class($callback[0]);
}
return $callback[0] . '::' . $callback[1];
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Logical NOT.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
}
/**
* @param string $string
* @return string
*/
public static function negate($string)
{
return str_replace(
array(
'contains ',
'exists',
'has ',
'is ',
'are ',
'matches ',
'starts with ',
'ends with ',
'reference ',
'not not '
),
array(
'does not contain ',
'does not exist',
'does not have ',
'is not ',
'are not ',
'does not match ',
'starts not with ',
'ends not with ',
'don\'t reference ',
'not '
),
$string
);
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$success = !$this->constraint->evaluate($other, $description, TRUE);
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
switch (get_class($this->constraint)) {
case 'PHPUnit_Framework_Constraint_And':
case 'PHPUnit_Framework_Constraint_Not':
case 'PHPUnit_Framework_Constraint_Or': {
return 'not( ' . $this->constraint->failureDescription($other) . ' )';
}
break;
default: {
return self::negate(
$this->constraint->failureDescription($other)
);
}
}
}
/**
* 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 self::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);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.0
*/
/**
* Constraint that asserts that the class it is evaluated for has a given
* attribute.
*
* The attribute name is passed in the constructor.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($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
);
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
'%sclass "%s" %s',
is_object($other) ? 'object of ' : '',
is_object($other) ? get_class($other) : $other,
$this->toString()
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Bastian Feder <php@bastian-feder.de>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause
* @link http://www.phpunit.de/
* @since File available since Release 3.7.0
*/
/**
* Provides human readable messages for each JSON error.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Bastian Feder <php@bastian-feder.de>
* @copyright 2011 Bastian Feder <php@bastian-feder.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause
* @link http://www.phpunit.de/
* @since Class available since Release 3.7.0
*/
class PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider
{
/**
* Translates JSON error to a human readable string.
*
* @param string $error
* @return string
*/
public static function determineJsonError($error, $prefix = '')
{
switch ($error) {
case JSON_ERROR_NONE:
return;
case JSON_ERROR_DEPTH:
return $prefix . 'Maximum stack depth exceeded';
case JSON_ERROR_STATE_MISMATCH:
return $prefix . 'Underflow or the modes mismatch';
case JSON_ERROR_CTRL_CHAR:
return $prefix . 'Unexpected control character found';
case JSON_ERROR_SYNTAX:
return $prefix . 'Syntax error, malformed JSON';
case JSON_ERROR_UTF8:
return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded';
default:
return $prefix . 'Unknown error';
}
}
/**
* Translates a given type to a human readable message prefix.
*
* @param string $type
* @return string
*/
public static function translateTypeToPrefix($type)
{
switch (strtolower($type)) {
case 'expected':
$prefix = 'Expected value JSON decode error - ';
break;
case 'actual':
$prefix = 'Actual value JSON decode error - ';
break;
default:
$prefix = '';
break;
}
return $prefix;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that asserts that the value it is evaluated for is greater
* than a given value.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return $this->value < $other;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is greater than ' . PHPUnit_Util_Type::export($this->value);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that accepts any input value.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
return $returnResult ? TRUE : NULL;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is anything';
}
/**
* Counts the number of constraint elements.
*
* @return integer
* @since Method available since Release 3.5.0
*/
public function count()
{
return 0;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($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
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that asserts that the Traversable it is applied to contains
* a given value.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.0.0
*/
class PHPUnit_Framework_Constraint_TraversableContains extends PHPUnit_Framework_Constraint
{
/**
* @var boolean
*/
protected $checkForObjectIdentity;
/**
* @var mixed
*/
protected $value;
/**
* @param boolean $value
* @param mixed $checkForObjectIdentity
* @throws PHPUnit_Framework_Exception
*/
public function __construct($value, $checkForObjectIdentity = TRUE)
{
if (!is_bool($checkForObjectIdentity)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
}
$this->checkForObjectIdentity = $checkForObjectIdentity;
$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
*/
protected function matches($other)
{
if ($other instanceof SplObjectStorage) {
return $other->contains($this->value);
}
if (is_object($this->value)) {
foreach ($other as $element) {
if (($this->checkForObjectIdentity &&
$element === $this->value) ||
(!$this->checkForObjectIdentity &&
$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::export($this->value);
}
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
'an %s %s',
is_array($other) ? 'array' : 'iterator',
$this->toString()
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that asserts that the value it is evaluated for is less than
* a given value.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return $this->value > $other;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is less than ' . PHPUnit_Util_Type::export($this->value);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.0
*/
/**
* ...
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.5.0
*/
class PHPUnit_Framework_Constraint_StringMatches extends PHPUnit_Framework_Constraint_PCREMatch
{
/**
* @var string
*/
protected $string;
/**
* @param string $string
*/
public function __construct($string)
{
$this->pattern = $this->createPatternFromFormat(
preg_replace('/\r\n/', "\n", $string)
);
$this->string = $string;
}
protected function failureDescription($other)
{
return "format description matches text";
}
protected function additionalFailureDescription($other)
{
$from = preg_split('(\r\n|\r|\n)', $this->string);
$to = preg_split('(\r\n|\r|\n)', $other);
foreach ($from as $index => $line) {
if (isset($to[$index]) && $line !== $to[$index]) {
$line = $this->createPatternFromFormat($line);
if (preg_match($line, $to[$index]) > 0) {
$from[$index] = $to[$index];
}
}
}
$this->string = join("\n", $from);
$other = join("\n", $to);
return PHPUnit_Util_Diff::diff($this->string, $other);
}
protected function createPatternFromFormat($string)
{
$string = str_replace(
array(
'%e',
'%s',
'%S',
'%a',
'%A',
'%w',
'%i',
'%d',
'%x',
'%f',
'%c'
),
array(
'\\' . DIRECTORY_SEPARATOR,
'[^\r\n]+',
'[^\r\n]*',
'.+',
'.*',
'\s*',
'[+-]?\d+',
'\d+',
'[0-9a-fA-F]+',
'[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?',
'.'
),
preg_quote($string, '/')
);
return '/^' . $string . '$/s';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
abstract class PHPUnit_Framework_Constraint_Composite extends PHPUnit_Framework_Constraint
{
/**
* @var PHPUnit_Framework_Constraint
*/
protected $innerConstraint;
/**
* @param PHPUnit_Framework_Constraint $innerConstraint
* @param string $attributeName
*/
public function __construct(PHPUnit_Framework_Constraint $innerConstraint)
{
$this->innerConstraint = $innerConstraint;
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
try {
return $this->innerConstraint->evaluate(
$other,
$description,
$returnResult
);
}
catch (PHPUnit_Framework_ExpectationFailedException $e) {
$this->fail($other, $description);
}
}
/**
* Counts the number of constraint elements.
*
* @return integer
*/
public function count()
{
return count($this->innerConstraint);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.6
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.6
*/
class PHPUnit_Framework_Constraint_ExceptionMessage extends PHPUnit_Framework_Constraint
{
/**
* @var integer
*/
protected $expectedMessage;
/**
* @param string $expected
*/
public function __construct($expected)
{
$this->expectedMessage = $expected;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* @param Exception $other
* @return boolean
*/
protected function matches($other)
{
return strpos($other->getMessage(), $this->expectedMessage) !== FALSE;
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
"exception message '%s' contains '%s'",
$other->getMessage(),
$this->expectedMessage
);
}
/**
* @return string
*/
public function toString()
{
return 'exception message contains ';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that checks if the file(name) that it is evaluated for exists.
*
* The file path to check is passed as $other in evaluate().
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return file_exists($other);
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
'file "%s" exists',
$other
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'file exists';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.0
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.1.0
*/
class PHPUnit_Framework_Constraint_Attribute extends PHPUnit_Framework_Constraint_Composite
{
/**
* @var string
*/
protected $attributeName;
/**
* @param PHPUnit_Framework_Constraint $constraint
* @param string $attributeName
*/
public function __construct(PHPUnit_Framework_Constraint $constraint, $attributeName)
{
parent::__construct($constraint);
$this->attributeName = $attributeName;
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
return parent::evaluate(
PHPUnit_Framework_Assert::readAttribute(
$other, $this->attributeName
),
$description,
$returnResult
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'attribute "' . $this->attributeName . '" ' .
$this->innerConstraint->toString();
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return $this->toString();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Logical OR.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$success = FALSE;
$constraint = NULL;
foreach ($this->constraints as $constraint) {
if ($constraint->evaluate($other, $description, TRUE)) {
$success = TRUE;
break;
}
}
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
}
/**
* 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 = 0;
foreach ($this->constraints as $constraint) {
$count += count($constraint);
}
return $count;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Constraint that asserts that the string it is evaluated for ends with a given
* suffix.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($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 . '"';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.0
*/
/**
* Constraint that asserts that the class it is evaluated for has a given
* static attribute.
*
* The attribute name is passed in the constructor.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($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
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* Constraint that accepts FALSE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return $other === FALSE;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is false';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Constraint that asserts that the string it is evaluated for begins with a
* given prefix.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
protected function matches($other)
{
return strpos($other, $this->prefix) === 0;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'starts with "' . $this->prefix . '"';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Bastian Feder <php@bastian-feder.de>
* @copyright 2002-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause
* @link http://www.phpunit.de/
* @since File available since Release 3.7.0
*/
/**
* Asserts whether or not two JSON objects are equal.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Bastian Feder <php@bastian-feder.de>
* @copyright 2011 Bastian Feder <php@bastian-feder.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause
* @link http://www.phpunit.de/
* @since Class available since Release 3.7.0
*/
class PHPUnit_Framework_Constraint_JsonMatches extends PHPUnit_Framework_Constraint
{
/**
* @var string
*/
protected $value;
/**
* Creates a new constraint.
*
* @param string $value
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* This method can be overridden to implement the evaluation algorithm.
*
* @param mixed $other Value or object to evaluate.
* @return bool
*/
protected function matches($other)
{
$decodedOther = json_decode($other);
if (json_last_error()) {
return FALSE;
}
$decodedValue = json_decode($this->value);
if (json_last_error()) {
return FALSE;
}
return $decodedOther == $decodedValue;
}
/**
* Returns a string representation of the object.
*
* @return string
*/
public function toString()
{
return sprintf(
'matches JSON string "%s"',
$this->value
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.0
*/
/**
* Constraint that checks whether a variable is empty().
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.5.0
*/
class PHPUnit_Framework_Constraint_IsEmpty 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
*/
protected function matches($other)
{
return empty($other);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is empty';
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
$type = gettype($other);
return sprintf(
'%s %s %s',
$type[0] == 'a' || $type[0] == 'o' ? 'an' : 'a',
$type,
$this->toString()
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Constraint_Count extends PHPUnit_Framework_Constraint
{
/**
* @var integer
*/
protected $expectedCount = 0;
/**
* @param integer $expected
*/
public function __construct($expected)
{
$this->expectedCount = $expected;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* @param mixed $other
* @return boolean
*/
protected function matches($other)
{
return $this->expectedCount === $this->getCountOf($other);
}
/**
* @param mixed $other
* @return boolean
*/
protected function getCountOf($other)
{
if ($other instanceof Countable || is_array($other)) {
return count($other);
}
else if ($other instanceof Iterator) {
return iterator_count($other);
}
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return sprintf(
'actual size %d matches expected size %d',
$this->getCountOf($other),
$this->expectedCount
);
}
/**
* @return string
*/
public function toString()
{
return 'count matches ';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Logical XOR.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$success = TRUE;
$lastResult = NULL;
$constraint = NULL;
foreach ($this->constraints as $constraint) {
$result = $constraint->evaluate($other, $description, TRUE);
if ($result === $lastResult) {
$success = FALSE;
break;
}
$lastResult = $result;
}
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
}
/**
* 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 = 0;
foreach ($this->constraints as $constraint) {
$count += count($constraint);
}
return $count;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Constraint that asserts that the value it is evaluated for is of a
* specified type.
*
* The expected value is passed in the constructor.
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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';
const TYPE_CALLABLE = 'callable';
/**
* @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,
'callable' => TRUE
);
/**
* @var string
*/
protected $type;
/**
* @param string $type
* @throws PHPUnit_Framework_Exception
*/
public function __construct($type)
{
if (!isset($this->types[$type])) {
throw new PHPUnit_Framework_Exception(
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
*/
protected function matches($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);
}
case 'callable': {
return is_callable($other);
}
}
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf(
'is of type "%s"',
$this->type
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Abstract base class for constraints. which are placed upon any value.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Interface available since Release 3.0.0
*/
abstract class PHPUnit_Framework_Constraint implements Countable, PHPUnit_Framework_SelfDescribing
{
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to FALSE (the default), an exception is thrown
* in case of a failure. NULL is returned otherwise.
*
* If $returnResult is TRUE, the result of the evaluation is returned as
* a boolean value instead: TRUE in case of success, FALSE in case of a
* failure.
*
* @param mixed $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
* @return mixed
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = FALSE)
{
$success = FALSE;
if ($this->matches($other)) {
$success = TRUE;
}
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* This method can be overridden to implement the evaluation algorithm.
*
* @param mixed $other Value or object to evaluate.
* @return bool
*/
protected function matches($other)
{
return FALSE;
}
/**
* Counts the number of constraint elements.
*
* @return integer
* @since Method available since Release 3.4.0
*/
public function count()
{
return 1;
}
/**
* Throws an exception for the given compared value and test description
*
* @param mixed $other Evaluated value or object.
* @param string $description Additional information about the test
* @param PHPUnit_Framework_ComparisonFailure $comparisonFailure
* @throws PHPUnit_Framework_ExpectationFailedException
*/
protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL)
{
$failureDescription = sprintf(
'Failed asserting that %s.',
$this->failureDescription($other)
);
$additionalFailureDescription = $this->additionalFailureDescription($other);
if ($additionalFailureDescription) {
$failureDescription .= "\n" . $additionalFailureDescription;
}
if (!empty($description)) {
$failureDescription = $description . "\n" . $failureDescription;
}
throw new PHPUnit_Framework_ExpectationFailedException(
$failureDescription,
$comparisonFailure
);
}
/**
* Return additional failure description where needed
*
* The function can be overridden to provide additional failure
* information like a diff
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function additionalFailureDescription($other)
{
return "";
}
/**
* Returns the description of the failure
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* To provide additional failure information additionalFailureDescription
* can be used.
*
* @param mixed $other Evaluated value or object.
* @return string
*/
protected function failureDescription($other)
{
return PHPUnit_Util_Type::export($other) . ' ' . $this->toString();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.0
*/
/**
* Creates a synthetic failed assertion.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.5.0
*/
class PHPUnit_Framework_SyntheticError extends PHPUnit_Framework_AssertionFailedError
{
/**
* The synthetic file.
*
* @var string
*/
protected $syntheticFile = '';
/**
* The synthetic line number.
*
* @var integer
*/
protected $syntheticLine = 0;
/**
* The synthetic trace.
*
* @var array
*/
protected $syntheticTrace = array();
/**
* 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->syntheticFile = $file;
$this->syntheticLine = $line;
$this->syntheticTrace = $trace;
}
/**
* @return string
*/
public function getSyntheticFile()
{
return $this->syntheticFile;
}
/**
* @return integer
*/
public function getSyntheticLine()
{
return $this->syntheticLine;
}
/**
* @return array
*/
public function getSyntheticTrace()
{
return $this->syntheticTrace;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Interface for classes that can return a description of itself.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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();
}
<?php
ini_set('display_errors', 'stderr');
set_include_path('{include_path}');
if ({composerAutoload}) {
require_once {composerAutoload};
define('PHPUNIT_COMPOSER_INSTALL', {composerAutoload});
} else {
require 'PHPUnit/Autoload.php';
}
ob_start();
function __phpunit_run_isolated_test()
{
if (!class_exists('{className}')) {
require_once '{filename}';
}
$result = new PHPUnit_Framework_TestResult;
if ({collectCodeCoverageInformation}) {
$result->setCodeCoverage(new PHP_CodeCoverage);
}
$result->strictMode({strict});
$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_clean();
print serialize(
array(
'testResult' => $test->getResult(),
'numAssertions' => $test->getNumAssertions(),
'result' => $result,
'output' => $output
)
);
ob_start();
}
{constants}
{included_files}
{globals}
if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
require_once $GLOBALS['__PHPUNIT_BOOTSTRAP'];
unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
}
__phpunit_run_isolated_test();
ob_end_clean();
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_TestSuite
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
*
*
* @package PHPUnit
* @subpackage Framework_TestSuite
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Abstract base class for comparators which compare values for equality.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
abstract class PHPUnit_Framework_Comparator
{
/**
* @var PHPUnit_Framework_ComparatorFactory
*/
protected $factory;
/**
* @param PHPUnit_Framework_ComparatorFactory $factory
*/
public function setFactory(PHPUnit_Framework_ComparatorFactory $factory)
{
$this->factory = $factory;
}
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
abstract public function accepts($expected, $actual);
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
abstract public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A TestSuite is a composite of Tests. It runs a collection of test cases.
*
* Here is an example using the dynamic test definition.
*
* <code>
* <?php
* $suite = new PHPUnit_Framework_TestSuite;
* $suite->addTest(new MathTest('testPass'));
* ?>
* </code>
*
* 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.
*
* <code>
* <?php
* $suite = new PHPUnit_Framework_TestSuite(
* new ReflectionClass('MathTest')
* );
* ?>
* </code>
*
* This constructor creates a suite with all the methods starting with
* "test" that take no arguments.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
/**
* 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 boolean
*/
protected $testCase = FALSE;
/**
* 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 PHPUnit_Framework_Exception
*/
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 PHPUnit_Framework_Exception;
}
if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) {
throw new PHPUnit_Framework_Exception(
'Class "' . $theClass->name . '" does not extend PHPUnit_Framework_TestCase.'
);
}
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;
}
foreach ($theClass->getMethods() as $method) {
$this->addTestMethod($theClass, $method);
}
if (empty($this->tests)) {
$this->addTest(
self::warning(
sprintf(
'No tests found in class "%s".',
$theClass->getName()
)
)
);
}
$this->testCase = TRUE;
}
/**
* 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 PHPUnit_Framework_Exception
*/
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 PHPUnit_Framework_Exception;
}
}
/**
* Wraps both <code>addTest()</code> and <code>addTestSuite</code>
* 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 <code>PHPUnit_Framework_Warning</code> will be created instead,
* leaving the current test run untouched.
*
* @param string $filename
* @param array $phptOptions Array with ini settings for the php instance
* run, key being the name if the setting,
* value the ini value.
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 2.3.0
* @author Stefano F. Rausch <stefano@rausch-e.net>
*/
public function addTestFile($filename, $phptOptions = array())
{
if (!is_string($filename)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
if (file_exists($filename) && substr($filename, -5) == '.phpt') {
$this->addTest(
new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)
);
return;
}
PHPUnit_Util_Class::collectStart();
$filename = PHPUnit_Util_Fileloader::checkAndLoad($filename);
$newClasses = PHPUnit_Util_Class::collectEnd();
$baseName = str_replace('.php', '', basename($filename));
foreach ($newClasses as $className) {
if (substr($className, 0 - strlen($baseName)) == $baseName) {
$class = new ReflectionClass($className);
if ($class->getFileName() == $filename) {
$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 PHPUnit_Framework_Exception
* @since Method available since Release 2.3.0
*/
public function addTestFiles($filenames)
{
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);
}
}
/**
* 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
* @return PHPUnit_Framework_Test
* @throws PHPUnit_Framework_Exception
*/
public static function createTest(ReflectionClass $theClass, $name)
{
$className = $theClass->getName();
if (!$theClass->isInstantiable()) {
return self::warning(
sprintf('Cannot instantiate class "%s".', $className)
);
}
$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 {
try {
$data = PHPUnit_Util_Test::getProvidedData(
$className, $name
);
}
catch (Exception $e) {
$message = sprintf(
'The data provider specified for %s::%s is invalid.',
$className,
$name
);
$_message = $e->getMessage();
if (!empty($_message)) {
$message .= "\n" . $_message;
}
$data = self::warning($message);
}
// Test method with @dataProvider.
if (isset($data)) {
$test = new PHPUnit_Framework_TestSuite_DataProvider(
$className . '::' . $name
);
if (empty($data)) {
$data = self::warning(
sprintf(
'No tests found in suite "%s".',
$test->getName()
)
);
}
$groups = PHPUnit_Util_Test::getGroups($className, $name);
if ($data instanceof PHPUnit_Framework_Warning) {
$test->addTest($data, $groups);
}
else {
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 (!isset($test)) {
throw new PHPUnit_Framework_Exception('No valid test provided.');
}
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 PHPUnit_Framework_Exception
*/
public function run(PHPUnit_Framework_TestResult $result = NULL, $filter = FALSE, array $groups = array(), array $excludeGroups = array(), $processIsolation = FALSE)
{
if ($result === NULL) {
$result = $this->createResult();
}
$result->startTestSuite($this);
$doSetup = TRUE;
if (!empty($excludeGroups)) {
foreach ($this->groups as $_group => $_tests) {
if (in_array($_group, $excludeGroups) &&
count($_tests) == count($this->tests)) {
$doSetup = FALSE;
}
}
}
if ($doSetup) {
try {
$this->setUp();
if ($this->testCase &&
// Some extensions use test names that are not classes;
// The method_exists() triggers an autoload call that causes issues with die()ing autoloaders.
class_exists($this->name, false) &&
method_exists($this->name, 'setUpBeforeClass')) {
call_user_func(array($this->name, 'setUpBeforeClass'));
}
}
catch (PHPUnit_Framework_SkippedTestSuiteError $e) {
$numTests = count($this);
for ($i = 0; $i < $numTests; $i++) {
$result->addFailure($this, $e, 0);
}
return $result;
}
catch (Exception $e) {
$numTests = count($this);
for ($i = 0; $i < $numTests; $i++) {
$result->addError($this, $e, 0);
}
return $result;
}
}
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);
}
}
}
}
foreach ($tests as $test) {
if ($result->shouldStop()) {
break;
}
if ($test instanceof PHPUnit_Framework_TestSuite) {
$test->setBackupGlobals($this->backupGlobals);
$test->setBackupStaticAttributes($this->backupStaticAttributes);
$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->setRunTestInSeparateProcess($processIsolation);
}
$this->runTest($test, $result);
}
}
}
if ($doSetup) {
if ($this->testCase &&
// Some extensions use test names that are not classes;
// The method_exists() triggers an autoload call that causes issues with die()ing autoloaders.
class_exists($this->name, false) &&
method_exists($this->name, 'tearDownAfterClass')) {
call_user_func(array($this->name, 'tearDownAfterClass'));
}
$this->tearDown();
}
$result->endTestSuite($this);
return $result;
}
/**
* Runs a test.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_TestResult $result
*/
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
*/
protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
{
$name = $method->getName();
if ($this->isPublicTestMethod($method)) {
$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" in test class "%s" is not public.',
$name,
$class->getName()
)
)
);
}
}
/**
* @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;
}
}
/**
* 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()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares arrays for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Array extends PHPUnit_Framework_Comparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return is_array($expected) && is_array($actual);
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE, array &$processed = array())
{
if ($canonicalize) {
sort($expected);
sort($actual);
}
$remaining = $actual;
$expString = $actString = "Array (\n";
$equal = TRUE;
foreach ($expected as $key => $value) {
unset($remaining[$key]);
if (!array_key_exists($key, $actual)) {
$expString .= sprintf(
" %s => %s\n",
PHPUnit_Util_Type::export($key),
PHPUnit_Util_Type::shortenedExport($value)
);
$equal = FALSE;
continue;
}
try {
$this->factory->getComparatorFor($value, $actual[$key])->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
$expString .= sprintf(
" %s => %s\n",
PHPUnit_Util_Type::export($key),
PHPUnit_Util_Type::shortenedExport($value)
);
$actString .= sprintf(
" %s => %s\n",
PHPUnit_Util_Type::export($key),
PHPUnit_Util_Type::shortenedExport($actual[$key])
);
}
catch (PHPUnit_Framework_ComparisonFailure $e) {
$expString .= sprintf(
" %s => %s\n",
PHPUnit_Util_Type::export($key),
$e->getExpectedAsString()
? $this->indent($e->getExpectedAsString())
: PHPUnit_Util_Type::shortenedExport($e->getExpected())
);
$actString .= sprintf(
" %s => %s\n",
PHPUnit_Util_Type::export($key),
$e->getActualAsString()
? $this->indent($e->getActualAsString())
: PHPUnit_Util_Type::shortenedExport($e->getActual())
);
$equal = FALSE;
}
}
foreach ($remaining as $key => $value) {
$actString .= sprintf(
" %s => %s\n",
PHPUnit_Util_Type::export($key),
PHPUnit_Util_Type::shortenedExport($value)
);
$equal = FALSE;
}
$expString .= ')';
$actString .= ')';
if (!$equal) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
$expString,
$actString,
FALSE,
'Failed asserting that two arrays are equal.'
);
}
}
protected function indent($lines)
{
return trim(str_replace("\n", "\n ", $lines));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares scalar or NULL values for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Scalar extends PHPUnit_Framework_Comparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
* @since Method available since Release 3.6.0
*/
public function accepts($expected, $actual)
{
return ((is_scalar($expected) XOR NULL === $expected) &&
(is_scalar($actual) XOR NULL === $actual))
// allow comparison between strings and objects featuring __toString()
|| (is_string($expected) && is_object($actual) && method_exists($actual, '__toString'))
|| (is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
$expectedToCompare = $expected;
$actualToCompare = $actual;
// always compare as strings to avoid strange behaviour
// otherwise 0 == 'Foobar'
if (is_string($expected) || is_string($actual)) {
$expectedToCompare = (string)$expectedToCompare;
$actualToCompare = (string)$actualToCompare;
if ($ignoreCase) {
$expectedToCompare = strtolower($expectedToCompare);
$actualToCompare = strtolower($actualToCompare);
}
}
if ($expectedToCompare != $actualToCompare) {
if (is_string($expected) && is_string($actual)) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
PHPUnit_Util_Type::export($expected),
PHPUnit_Util_Type::export($actual),
FALSE,
'Failed asserting that two strings are equal.'
);
}
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
// no diff is required
'',
'',
FALSE,
sprintf(
'Failed asserting that %s matches expected %s.',
PHPUnit_Util_Type::export($actual),
PHPUnit_Util_Type::export($expected)
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares Exception instances for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Exception extends PHPUnit_Framework_Comparator_Object
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return $expected instanceof Exception && $actual instanceof Exception;
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
protected function toArray($object)
{
$array = parent::toArray($object);
unset(
$array['file'],
$array['line'],
$array['trace'],
$array['string'], // some internal property of Exception
$array['xdebug_message'] // some internal property added by XDebug
);
return $array;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares numerical values for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @author Alexander <iam.asm89@gmail.com>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Numeric extends PHPUnit_Framework_Comparator_Scalar
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
// all numerical values, but not if one of them is a double
return is_numeric($expected) && is_numeric($actual) && !(is_double($expected) || is_double($actual));
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
if (is_infinite($actual) && is_infinite($expected)) {
return;
}
if ((is_infinite($actual) XOR is_infinite($expected)) ||
(is_nan($actual) OR is_nan($expected)) ||
abs($actual - $expected) > $delta) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
'',
'',
FALSE,
sprintf(
'Failed asserting that %s matches expected %s.',
PHPUnit_Util_Type::export($actual),
PHPUnit_Util_Type::export($expected)
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares doubles for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Double extends PHPUnit_Framework_Comparator_Numeric
{
/**
* Smallest value available in PHP.
*
* @var float
*/
const EPSILON = 0.0000000001;
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return (is_double($expected) || is_double($actual)) && is_numeric($expected) && is_numeric($actual);
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
if ($delta == 0) {
$delta = self::EPSILON;
}
parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares values for type equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Type extends PHPUnit_Framework_Comparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return TRUE;
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
if (gettype($expected) != gettype($actual)) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
// we don't need a diff
'',
'',
FALSE,
sprintf(
'%s does not match expected type "%s".',
PHPUnit_Util_Type::shortenedExport($actual),
gettype($expected)
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares objects for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Object extends PHPUnit_Framework_Comparator_Array
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return is_object($expected) && is_object($actual);
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE, array &$processed = array())
{
if (get_class($actual) !== get_class($expected)) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
PHPUnit_Util_Type::export($expected),
PHPUnit_Util_Type::export($actual),
FALSE,
sprintf(
'%s is not instance of expected class "%s".',
PHPUnit_Util_Type::export($actual),
get_class($expected)
)
);
}
// don't compare twice to allow for cyclic dependencies
if (in_array(array($actual, $expected), $processed, TRUE) ||
in_array(array($expected, $actual), $processed, TRUE)) {
return;
}
$processed[] = array($actual, $expected);
// don't compare objects if they are identical
// this helps to avoid the error "maximum function nesting level reached"
// CAUTION: this conditional clause is not tested
if ($actual !== $expected) {
try {
parent::assertEquals($this->toArray($expected), $this->toArray($actual), $delta, $canonicalize, $ignoreCase, $processed);
}
catch (PHPUnit_Framework_ComparisonFailure $e) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
// replace "Array" with "MyClass object"
substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5),
substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5),
FALSE,
'Failed asserting that two objects are equal.'
);
}
}
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
protected function toArray($object)
{
return PHPUnit_Util_Type::toArray($object);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares resources for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_Resource extends PHPUnit_Framework_Comparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return is_resource($expected) && is_resource($actual);
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
if ($actual != $expected) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
PHPUnit_Util_Type::export($expected),
PHPUnit_Util_Type::export($actual)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares DOMDocument instances for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_DOMDocument extends PHPUnit_Framework_Comparator_Object
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return $expected instanceof DOMDocument && $actual instanceof DOMDocument;
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
if ($expected->C14N() !== $actual->C14N()) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
$this->domToText($expected),
$this->domToText($actual),
FALSE,
'Failed asserting that two DOM documents are equal.'
);
}
}
/**
* 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();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares SplObjectStorage instances for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_SplObjectStorage extends PHPUnit_Framework_Comparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage;
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
foreach ($actual as $object) {
if (!$expected->contains($object)) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
PHPUnit_Util_Type::export($expected),
PHPUnit_Util_Type::export($actual),
FALSE,
'Failed asserting that two objects are equal.'
);
}
}
foreach ($expected as $object) {
if (!$actual->contains($object)) {
throw new PHPUnit_Framework_ComparisonFailure(
$expected,
$actual,
PHPUnit_Util_Type::export($expected),
PHPUnit_Util_Type::export($actual),
FALSE,
'Failed asserting that two objects are equal.'
);
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* Compares PHPUnit_Framework_MockObject_MockObject instances for equality.
*
* @package PHPUnit
* @subpackage Framework_Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Framework_Comparator_MockObject extends PHPUnit_Framework_Comparator_Object
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return boolean
*/
public function accepts($expected, $actual)
{
return $expected instanceof PHPUnit_Framework_MockObject_MockObject && $actual instanceof PHPUnit_Framework_MockObject_MockObject;
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
protected function toArray($object)
{
$array = parent::toArray($object);
unset($array['__phpunit_invocationMocker']);
return $array;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Error
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* Wrapper for PHP warnings.
* You can disable notice-to-exception conversion by setting
*
* <code>
* PHPUnit_Framework_Error_Warning::$enabled = FALSE;
* </code>
*
* @package PHPUnit
* @subpackage Framework_Error
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Error
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* Wrapper for PHP notices.
* You can disable notice-to-exception conversion by setting
*
* <code>
* PHPUnit_Framework_Error_Notice::$enabled = FALSE;
* </code>
*
* @package PHPUnit
* @subpackage Framework_Error
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework_Error
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* Wrapper for PHP deprecated errors.
* You can disable deprecated-to-exception conversion by setting
*
* <code>
* PHPUnit_Framework_Error_Deprecated::$enabled = FALSE;
* </code>
*
* @package PHPUnit
* @subpackage Framework_Error
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.3.0
*/
class PHPUnit_Framework_Error_Deprecated extends PHPUnit_Framework_Error
{
public static $enabled = TRUE;
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.2.0
*/
/**
* Wrapper for PHP errors.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 Exception $previous
*/
public function __construct($message, $code, $file, $line, Exception $previous = NULL)
{
parent::__construct($message, $code, $previous);
$this->file = $file;
$this->line = $line;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A TestResult collects the results of executing a test case.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 $deprecatedFeatures = 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.
*
* @var PHP_CodeCoverage
*/
protected $codeCoverage;
/**
* @var boolean
*/
protected $convertErrorsToExceptions = TRUE;
/**
* @var boolean
*/
protected $stop = FALSE;
/**
* @var boolean
*/
protected $stopOnError = FALSE;
/**
* @var boolean
*/
protected $stopOnFailure = FALSE;
/**
* @var boolean
*/
protected $strictMode = FALSE;
/**
* @var boolean
*/
protected $stopOnIncomplete = FALSE;
/**
* @var boolean
*/
protected $stopOnSkipped = FALSE;
/**
* @var boolean
*/
protected $lastTestFailed = FALSE;
/**
* @var integer
*/
protected $timeoutForSmallTests = 1;
/**
* @var integer
*/
protected $timeoutForMediumTests = 10;
/**
* @var integer
*/
protected $timeoutForLargeTests = 60;
/**
* 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';
if ($this->stopOnIncomplete) {
$this->stop();
}
}
else if ($e instanceof PHPUnit_Framework_SkippedTest) {
$this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
$notifyMethod = 'addSkippedTest';
if ($this->stopOnSkipped) {
$this->stop();
}
}
else {
$this->errors[] = new PHPUnit_Framework_TestFailure($test, $e);
$notifyMethod = 'addError';
if ($this->stopOnError || $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';
if ($this->stopOnIncomplete) {
$this->stop();
}
}
else if ($e instanceof PHPUnit_Framework_SkippedTest) {
$this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
$notifyMethod = 'addSkippedTest';
if ($this->stopOnSkipped) {
$this->stop();
}
}
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;
}
/**
* Adds a deprecated feature notice to the list of deprecated features used during run
*
* @param PHPUnit_Util_DeprecatedFeature $deprecatedFeature
*/
public function addDeprecatedFeature(PHPUnit_Util_DeprecatedFeature $deprecatedFeature)
{
$this->deprecatedFeatures[] = $deprecatedFeature;
}
/**
* 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) {
$class = get_class($test);
$key = $class . '::' . $test->getName();
$this->passed[$key] = array(
'result' => $test->getResult(),
'size' => PHPUnit_Util_Test::getSize(
$class, $test->getName(FALSE)
)
);
$this->time += $time;
}
}
/**
* Returns TRUE if no incomplete test occured.
*
* @return boolean
*/
public function allCompletelyImplemented()
{
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;
}
/**
* Returns an Enumeration for the deprecated features used.
*
* @return array
* @since Method available since Release 3.5.7
*/
public function deprecatedFeatures()
{
return $this->deprecatedFeatures;
}
/**
* Returns an Enumeration for the deprecated features used.
*
* @return array
* @since Method available since Release 3.5.7
*/
public function deprecatedFeaturesCount()
{
return count($this->deprecatedFeatures);
}
/**
* 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;
}
/**
* 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->codeCoverage !== NULL;
}
/**
* Returns the strict mode configuration option
*
* @return boolean
*/
public function isStrict()
{
return $this->strictMode;
}
/**
* Runs a TestCase.
*
* @param PHPUnit_Framework_Test $test
*/
public function run(PHPUnit_Framework_Test $test)
{
PHPUnit_Framework_Assert::resetCount();
$error = FALSE;
$failure = FALSE;
$incomplete = FALSE;
$skipped = 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->codeCoverage !== NULL &&
!$test instanceof PHPUnit_Extensions_SeleniumTestCase &&
!$test instanceof PHPUnit_Framework_Warning;
if ($useXdebug) {
// We need to blacklist test source files when no whitelist is used.
if (!$this->codeCoverage->filter()->hasWhitelist()) {
$classes = PHPUnit_Util_Class::getHierarchy(
get_class($test), TRUE
);
foreach ($classes as $class) {
$this->codeCoverage->filter()->addFileToBlacklist(
$class->getFileName()
);
}
}
$this->codeCoverage->start($test);
}
PHP_Timer::start();
try {
if (!$test instanceof PHPUnit_Framework_Warning &&
$this->strictMode &&
extension_loaded('pcntl') && class_exists('PHP_Invoker')) {
switch ($test->getSize()) {
case PHPUnit_Util_Test::SMALL: {
$_timeout = $this->timeoutForSmallTests;
}
break;
case PHPUnit_Util_Test::MEDIUM: {
$_timeout = $this->timeoutForMediumTests;
}
break;
case PHPUnit_Util_Test::LARGE: {
$_timeout = $this->timeoutForLargeTests;
}
break;
}
$invoker = new PHP_Invoker;
$invoker->invoke(array($test, 'runBare'), array(), $_timeout);
} else {
$test->runBare();
}
}
catch (PHPUnit_Framework_AssertionFailedError $e) {
$failure = TRUE;
if ($e instanceof PHPUnit_Framework_IncompleteTestError) {
$incomplete = TRUE;
}
else if ($e instanceof PHPUnit_Framework_SkippedTestError) {
$skipped = TRUE;
}
}
catch (Exception $e) {
$error = TRUE;
}
$time = PHP_Timer::stop();
$test->addToAssertionCount(PHPUnit_Framework_Assert::getCount());
if ($this->strictMode && $test->getNumAssertions() == 0) {
$incomplete = TRUE;
}
if ($useXdebug) {
try {
$this->codeCoverage->stop(!$incomplete && !$skipped);
}
catch (PHP_CodeCoverage_Exception $cce) {
$error = TRUE;
if (!isset($e)) {
$e = $cce;
}
}
}
if ($errorHandlerSet === TRUE) {
restore_error_handler();
}
if ($error === TRUE) {
$this->addError($test, $e, $time);
}
else if ($failure === TRUE) {
$this->addFailure($test, $e, $time);
}
else if ($this->strictMode && $test->getNumAssertions() == 0) {
$this->addFailure(
$test,
new PHPUnit_Framework_IncompleteTestError(
'This test did not perform any assertions'
),
$time
);
}
else if ($this->strictMode && $test->hasOutput()) {
$this->addFailure(
$test,
new PHPUnit_Framework_OutputError(
sprintf(
'This test printed output: %s',
$test->getActualOutput()
)
),
$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;
}
/**
* Returns the PHP_CodeCoverage object.
*
* @return PHP_CodeCoverage
* @since Method available since Release 3.5.0
*/
public function getCodeCoverage()
{
return $this->codeCoverage;
}
/**
* Returns the PHP_CodeCoverage object.
*
* @return PHP_CodeCoverage
* @since Method available since Release 3.6.0
*/
public function setCodeCoverage(PHP_CodeCoverage $codeCoverage)
{
$this->codeCoverage = $codeCoverage;
}
/**
* Enables or disables the error-to-exception conversion.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @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 an error occurs.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.5.0
*/
public function stopOnError($flag)
{
if (is_bool($flag)) {
$this->stopOnError = $flag;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
}
/**
* Enables or disables the stopping when a failure occurs.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @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');
}
}
/**
* Enables or disables the strict mode.
*
* When active
* * Tests that do not assert anything will be marked as incomplete.
* * Tests that are incomplete or skipped yield no code coverage.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.5.2
*/
public function strictMode($flag)
{
if (is_bool($flag)) {
$this->strictMode = $flag;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
}
/**
* Enables or disables the stopping for incomplete tests.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.5.0
*/
public function stopOnIncomplete($flag)
{
if (is_bool($flag)) {
$this->stopOnIncomplete = $flag;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
}
/**
* Enables or disables the stopping for skipped tests.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.1.0
*/
public function stopOnSkipped($flag)
{
if (is_bool($flag)) {
$this->stopOnSkipped = $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);
}
/**
* Sets the timeout for small tests.
*
* @param integer $timeout
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.6.0
*/
public function setTimeoutForSmallTests($timeout)
{
if (is_integer($timeout)) {
$this->timeoutForSmallTests = $timeout;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
}
/**
* Sets the timeout for medium tests.
*
* @param integer $timeout
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.6.0
*/
public function setTimeoutForMediumTests($timeout)
{
if (is_integer($timeout)) {
$this->timeoutForMediumTests = $timeout;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
}
/**
* Sets the timeout for large tests.
*
* @param integer $timeout
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.6.0
*/
public function setTimeoutForLargeTests($timeout)
{
if (is_integer($timeout)) {
$this->timeoutForLargeTests = $timeout;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A marker interface for marking any exception/error as result of an unit
* test as incomplete implementation or currently not implemented.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Interface available since Release 2.0.0
*/
interface PHPUnit_Framework_IncompleteTest
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A Listener for test progress.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
public function __construct($message, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL, Exception $previous = NULL)
{
$this->comparisonFailure = $comparisonFailure;
parent::__construct($message, 0, $previous);
}
/**
* @return PHPUnit_Framework_ComparisonFailure
*/
public function getComparisonFailure()
{
return $this->comparisonFailure;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Thrown when an assertion failed.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
class PHPUnit_Framework_AssertionFailedError extends PHPUnit_Framework_Exception implements PHPUnit_Framework_SelfDescribing
{
/**
* Wrapper for getMessage() which is declared as final.
*
* @return string
*/
public function toString()
{
return $this->getMessage();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* A marker interface for marking a unit test as being skipped.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Interface available since Release 3.0.0
*/
interface PHPUnit_Framework_SkippedTest
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A Test can be run and collect its results.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* The standard test suite loader.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
* @return ReflectionClass
* @throws PHPUnit_Framework_Exception
*/
public function load($suiteClassName, $suiteClassFile = '')
{
$suiteClassName = str_replace('.php', '', $suiteClassName);
if (empty($suiteClassFile)) {
$suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename(
$suiteClassName
);
}
if (!class_exists($suiteClassName, FALSE)) {
PHPUnit_Util_Class::collectStart();
$filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile);
$loadedClasses = PHPUnit_Util_Class::collectEnd();
}
if (!class_exists($suiteClassName, FALSE) && !empty($loadedClasses)) {
$offset = 0 - strlen($suiteClassName);
foreach ($loadedClasses as $loadedClass) {
$class = new ReflectionClass($loadedClass);
if (substr($loadedClass, $offset) === $suiteClassName &&
$class->getFileName() == $filename) {
$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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* An interface to define how a test suite should be loaded.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* This class defines the current version of PHPUnit.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
class PHPUnit_Runner_Version
{
const VERSION = '3.7.22';
protected static $version;
/**
* Returns the current version of PHPUnit.
*
* @return string
*/
public static function id()
{
if (self::$version === NULL) {
self::$version = self::VERSION;
if (is_dir(dirname(dirname(__DIR__)) . '/.git')) {
$dir = getcwd();
chdir(__DIR__);
$version = exec('git describe --tags 2>&1', $output, $returnCode);
chdir($dir);
if ($version && $returnCode === 0) {
if (count(explode('.', self::VERSION)) == 3) {
self::$version = $version;
} else {
$version = explode('-', $version);
self::$version = self::VERSION . '-' . $version[2];
}
} else {
self::$version = self::VERSION . '-dev';
}
}
}
return self::$version;
}
/**
* @return string
*/
public static function getVersionString()
{
return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann.';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Base class for all test runners.
*
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
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 mixed $suffixes
* @return PHPUnit_Framework_Test
*/
public function getTest($suiteClassName, $suiteClassFile = '', $suffixes = '')
{
if (is_dir($suiteClassName) &&
!is_file($suiteClassName . '.php') && empty($suiteClassFile)) {
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray(
$suiteClassName, $suffixes
);
$suite = new PHPUnit_Framework_TestSuite($suiteClassName);
$suite->addTestFiles($files);
return $suite;
}
try {
$testClass = $this->loadSuiteClass(
$suiteClassName, $suiteClassFile
);
}
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) {
try {
$test = new PHPUnit_Framework_TestSuite($testClass);
}
catch (PHPUnit_Framework_Exception $e) {
$test = new PHPUnit_Framework_TestSuite;
$test->setName($suiteClassName);
}
}
$this->clearStatus();
return $test;
}
/**
* Returns the loaded ReflectionClass for a suite name.
*
* @param string $suiteClassName
* @param string $suiteClassFile
* @return ReflectionClass
*/
protected function loadSuiteClass($suiteClassName, $suiteClassFile = '')
{
$loader = $this->getLoader();
if ($loader instanceof PHPUnit_Runner_StandardTestSuiteLoader) {
return $loader->load($suiteClassName, $suiteClassFile);
} 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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
/**
* Prettifies class and method names for use in TestDox documentation.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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, -1, $count);
if (in_array($string, $this->strings)) {
$name = $string;
} else if ($count == 0) {
$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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
/**
* Prints TestDox documentation in HTML format.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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('<html><body>');
}
/**
* Handler for 'start class' event.
*
* @param string $name
*/
protected function startClass($name)
{
$this->write(
'<h2 id="' . $name . '">' . $this->currentTestClassPrettified .
'</h2><ul>'
);
}
/**
* Handler for 'on test' event.
*
* @param string $name
* @param boolean $success
*/
protected function onTest($name, $success = TRUE)
{
if (!$success) {
$strikeOpen = '<strike>';
$strikeClose = '</strike>';
} else {
$strikeOpen = '';
$strikeClose = '';
}
$this->write('<li>' . $strikeOpen . $name . $strikeClose . '</li>');
}
/**
* Handler for 'end class' event.
*
* @param string $name
*/
protected function endClass($name)
{
$this->write('</ul>');
}
/**
* Handler for 'end run' event.
*
*/
protected function endRun()
{
$this->write('</body></html>');
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
/**
* Prints TestDox documentation in text format.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
/**
* Base class for printers of TestDox documentation.
*
* @package PHPUnit
* @subpackage Util_TestDox
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.1.0
*/
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();
/**
* @var integer
*/
protected $successful = 0;
/**
* @var integer
*/
protected $failed = 0;
/**
* @var integer
*/
protected $skipped = 0;
/**
* @var integer
*/
protected $incomplete = 0;
/**
* @var string
*/
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()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Utility class that can print to STDOUT or write to a file.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
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 PHPUnit_Framework_Exception
*/
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 PHPUnit_Framework_Exception;
}
$this->out = fsockopen($out[0], $out[1]);
} else {
if (strpos($out, 'php://') === FALSE &&
!is_dir(dirname($out))) {
mkdir(dirname($out), 0777, TRUE);
}
$this->out = fopen($out, 'wt');
}
$this->outTarget = $out;
} else {
$this->out = $out;
}
}
}
/**
* Flush buffer, optionally tidy up HTML, and close output if it's not to a php stream
*/
public function flush()
{
if ($this->out && strncmp($this->outTarget, 'php://', 6) !== 0) {
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) {
fflush($this->out);
} else {
flush();
}
}
/**
* @param string $buffer
*/
public function write($buffer)
{
if ($this->out) {
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');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Diff implementation.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 as string.
*
* @param array|string $from
* @param array|string $to
* @return string
*/
public static function diff($from, $to)
{
$buffer= "--- Expected\n+++ Actual\n";
$diff = self::diffToArray($from,$to);
$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) {
$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;
}
/**
* Returns the diff between two arrays or strings as array.
*
* every array-entry containts two elements:
* - [0] => string $token
* - [1] => 2|1|0
*
* - 2: REMOVED: $token was removed from $from
* - 1: ADDED: $token was added to $from
* - 0: OLD: $token is not changed in $to
*
* @param array|string $from
* @param array|string $to
* @return array
*/
public static function diffToArray($from, $to)
{
preg_match_all('(\r\n|\r|\n)', $from, $fromMatches);
preg_match_all('(\r\n|\r|\n)', $to, $toMatches);
if (is_string($from)) {
$from = preg_split('(\r\n|\r|\n)', $from);
}
if (is_string($to)) {
$to = preg_split('(\r\n|\r|\n)', $to);
}
$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;
if (isset($fromMatches[0]) && $toMatches[0] &&
count($fromMatches[0]) === count($toMatches[0]) &&
$fromMatches[0] !== $toMatches[0]) {
$diff[] = array(
'#Warning: Strings contain different line endings!', 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 */);
}
return $diff;
}
/**
* 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();
$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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.12
*/
/**
* Windows utility for PHP sub-processes.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.5.12
*/
class PHPUnit_Util_PHP_Windows extends PHPUnit_Util_PHP
{
/**
* @var string
*/
protected $tempFile;
/**
* @param resource $pipe
* @since Method available since Release 3.5.12
*/
protected function process($pipe, $job)
{
if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) ||
file_put_contents($this->tempFile, $job) === FALSE) {
throw new PHPUnit_Framework_Exception(
'Unable to write temporary files for process isolation.'
);
}
fwrite(
$pipe,
"<?php require_once " . var_export($this->tempFile, TRUE) . "; ?>"
);
}
/**
* @since Method available since Release 3.5.12
*/
protected function cleanup()
{
unlink($this->tempFile);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.12
*/
/**
* Default utility for PHP sub-processes.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.5.12
*/
class PHPUnit_Util_PHP_Default extends PHPUnit_Util_PHP
{
/**
* @param resource $pipe
* @since Method available since Release 3.5.12
*/
protected function process($pipe, $job)
{
fwrite($pipe, $job);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.0
*/
/**
* Iterator for test suites.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
*
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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'
);
/**
* @var array
*/
protected static $phpunitFiles;
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) &&
!$GLOBALS[$key] instanceof Closure) {
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]) &&
is_array($GLOBALS[$superGlobalArray])) {
foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
self::$globals[$superGlobalArray][$key] = serialize($value);
}
}
}
protected static function restoreSuperGlobalArray($superGlobalArray)
{
if (isset($GLOBALS[$superGlobalArray]) &&
is_array($GLOBALS[$superGlobalArray]) &&
isset(self::$globals[$superGlobalArray])) {
$keys = array_keys(
array_merge(
$GLOBALS[$superGlobalArray], self::$globals[$superGlobalArray]
)
);
foreach ($keys as $key) {
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 = self::phpunitFiles();
$files = get_included_files();
$prefix = FALSE;
$result = '';
if (defined('__PHPUNIT_PHAR__')) {
$prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
}
for ($i = count($files) - 1; $i > 0; $i--) {
$file = $files[$i];
if ($prefix !== FALSE) {
$file = str_replace($prefix, '', $file);
}
if (!isset($blacklist[$file]) && is_file($file)) {
$result = 'require_once \'' . $file . "';\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]) &&
is_array($GLOBALS[$superGlobalArray])) {
foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) {
if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) {
continue;
}
$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) && !$GLOBALS[$key] instanceof Closure) {
$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 &&
strpos($declaredClasses[$i], 'File_Iterator') !== 0 &&
strpos($declaredClasses[$i], 'PHP_CodeCoverage') !== 0 &&
strpos($declaredClasses[$i], 'PHP_Invoker') !== 0 &&
strpos($declaredClasses[$i], 'PHP_Timer') !== 0 &&
strpos($declaredClasses[$i], 'PHP_TokenStream') !== 0 &&
strpos($declaredClasses[$i], 'Symfony') !== 0 &&
strpos($declaredClasses[$i], 'Text_Template') !== 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);
$value = $attribute->getValue();
if (!$value instanceof Closure) {
$backup[$name] = serialize($value);
}
}
}
}
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(\'' .
str_replace("'", "\'", 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;
}
/**
* @return array
* @since Method available since Release 3.6.0
*/
public static function phpunitFiles()
{
if (self::$phpunitFiles === NULL) {
self::addDirectoryContainingClassToPHPUnitFilesList('File_Iterator');
self::addDirectoryContainingClassToPHPUnitFilesList('PHP_CodeCoverage');
self::addDirectoryContainingClassToPHPUnitFilesList('PHP_Invoker');
self::addDirectoryContainingClassToPHPUnitFilesList('PHP_Timer');
self::addDirectoryContainingClassToPHPUnitFilesList('PHP_Token');
self::addDirectoryContainingClassToPHPUnitFilesList('PHPUnit_Framework_TestCase', 2);
self::addDirectoryContainingClassToPHPUnitFilesList('PHPUnit_Extensions_Database_TestCase', 2);
self::addDirectoryContainingClassToPHPUnitFilesList('PHPUnit_Framework_MockObject_Generator', 2);
self::addDirectoryContainingClassToPHPUnitFilesList('PHPUnit_Extensions_SeleniumTestCase', 2);
self::addDirectoryContainingClassToPHPUnitFilesList('PHPUnit_Extensions_Story_TestCase', 2);
self::addDirectoryContainingClassToPHPUnitFilesList('Text_Template');
}
return self::$phpunitFiles;
}
/**
* @param string $className
* @param integer $parent
* @since Method available since Release 3.7.2
*/
protected static function addDirectoryContainingClassToPHPUnitFilesList($className, $parent = 1)
{
if (!class_exists($className)) {
return;
}
$reflector = new ReflectionClass($className);
$directory = $reflector->getFileName();
for ($i = 0; $i < $parent; $i++) {
$directory = dirname($directory);
}
$facade = new File_Iterator_Facade;
foreach ($facade->getFilesAsArray($directory, '.php') as $file) {
self::$phpunitFiles[$file] = TRUE;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
/**
* Utility methods to load PHP sourcefiles.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.3.0
*/
class PHPUnit_Util_Fileloader
{
/**
* Checks if a PHP sourcefile is readable.
* The sourcefile is loaded through the load() method.
*
* @param string $filename
* @throws PHPUnit_Framework_Exception
*/
public static function checkAndLoad($filename)
{
$includePathFilename = stream_resolve_include_path($filename);
if (!$includePathFilename || !is_readable($includePathFilename)) {
throw new PHPUnit_Framework_Exception(
sprintf('Cannot open file "%s".' . "\n", $filename)
);
}
self::load($includePathFilename);
return $includePathFilename;
}
/**
* Loads a PHP sourcefile.
*
* @param string $filename
* @return mixed
* @since Method available since Release 3.0.0
*/
public static function load($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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2010, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Ralph Schindler <ralph.schindler@zend.com>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2002-2010 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.7
*/
/**
* Test Listener that tracks the usage of deprecated features.
*
* @package PHPUnit
* @subpackage Framework
* @author Ralph Schindler <ralph.schindler@zend.com>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2002-2010 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.5.7
*/
class PHPUnit_Util_DeprecatedFeature_Logger implements PHPUnit_Framework_TestListener
{
/**
* @var PHPUnit_Framework_TestCase
*/
protected static $currentTest = NULL;
/**
* This is the publically accessible API for notifying the system that a
* deprecated feature has been used.
*
* If it is run via a TestRunner and the test extends
* PHPUnit_Framework_TestCase, then this will inject the result into the
* test runner for display, if not, it will throw the notice to STDERR.
*
* @param string $message
* @param int|bool $backtraceDepth
*/
public static function log($message, $backtraceDepth = 2)
{
if ($backtraceDepth !== FALSE) {
$trace = debug_backtrace(FALSE);
if (is_int($backtraceDepth)) {
$traceItem = $trace[$backtraceDepth];
}
if (!isset($traceItem['file'])) {
$reflectionClass = new ReflectionClass($traceItem['class']);
$traceItem['file'] = $reflectionClass->getFileName();
}
if (!isset($traceItem['line']) &&
isset($traceItem['class']) &&
isset($traceItem['function'])) {
if (!isset($reflectionClass)) {
$reflectionClass = new ReflectionClass($traceItem['class']);
}
$method = $reflectionClass->getMethod($traceItem['function']);
$traceItem['line'] = '(between ' . $method->getStartLine() .
' and ' . $method->getEndLine() . ')';
}
}
$deprecatedFeature = new PHPUnit_Util_DeprecatedFeature(
$message, $traceItem
);
if (self::$currentTest instanceof PHPUnit_Framework_TestCase) {
$result = self::$currentTest->getTestResultObject();
$result->addDeprecatedFeature($deprecatedFeature);
} else {
file_put_contents('php://stderr', $deprecatedFeature);
}
}
/**
* 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)
{
self::$currentTest = $test;
}
/**
* A test ended.
*
* @param PHPUnit_Framework_Test $test
* @param float $time
*/
public function endTest(PHPUnit_Framework_Test $test, $time)
{
self::$currentTest = NULL;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Utility class for code filtering.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 2.0.0
*/
class PHPUnit_Util_Filter
{
/**
* Filters stack frames from PHPUnit classes.
*
* @param Exception $e
* @param boolean $asString
* @return string
*/
public static function getFilteredStacktrace(Exception $e, $asString = TRUE)
{
$prefix = FALSE;
$script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
if (defined('__PHPUNIT_PHAR__')) {
$prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
}
if (!defined('PHPUNIT_TESTSUITE')) {
$blacklist = PHPUnit_Util_GlobalState::phpunitFiles();
} else {
$blacklist = array();
}
if ($asString === TRUE) {
$filteredStacktrace = '';
} else {
$filteredStacktrace = array();
}
if ($e instanceof PHPUnit_Framework_SyntheticError) {
$eTrace = $e->getSyntheticTrace();
$eFile = $e->getSyntheticFile();
$eLine = $e->getSyntheticLine();
} else {
if ($e->getPrevious()) {
$eTrace = $e->getPrevious()->getTrace();
} else {
$eTrace = $e->getTrace();
}
$eFile = $e->getFile();
$eLine = $e->getLine();
}
if (!self::frameExists($eTrace, $eFile, $eLine)) {
array_unshift(
$eTrace, array('file' => $eFile, 'line' => $eLine)
);
}
foreach ($eTrace as $frame) {
if (isset($frame['file']) && is_file($frame['file']) &&
!isset($blacklist[$frame['file']]) &&
strpos($frame['file'], $prefix) !== 0 &&
$frame['file'] !== $script) {
if ($asString === TRUE) {
$filteredStacktrace .= sprintf(
"%s:%s\n",
$frame['file'],
isset($frame['line']) ? $frame['line'] : '?'
);
} else {
$filteredStacktrace[] = $frame;
}
}
}
return $filteredStacktrace;
}
/**
* @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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
// Workaround for http://bugs.php.net/bug.php?id=47987,
// see https://github.com/sebastianbergmann/phpunit/issues#issue/125 for details
require_once __DIR__ . '/../Framework/Error.php';
require_once __DIR__ . '/../Framework/Error/Notice.php';
require_once __DIR__ . '/../Framework/Error/Warning.php';
require_once __DIR__ . '/../Framework/Error/Deprecated.php';
/**
* Error handler that converts PHP errors and warnings to exceptions.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
$trace = debug_backtrace(FALSE);
array_shift($trace);
foreach ($trace as $frame) {
if ($frame['function'] == '__toString') {
return FALSE;
}
}
if ($errno == E_NOTICE || $errno == E_USER_NOTICE || $errno == E_STRICT) {
if (PHPUnit_Framework_Error_Notice::$enabled !== TRUE) {
return FALSE;
}
$exception = 'PHPUnit_Framework_Error_Notice';
}
else if ($errno == E_WARNING || $errno == E_USER_WARNING) {
if (PHPUnit_Framework_Error_Warning::$enabled !== TRUE) {
return FALSE;
}
$exception = 'PHPUnit_Framework_Error_Warning';
}
else if ($errno == E_DEPRECATED || $errno == E_USER_DEPRECATED) {
if (PHPUnit_Framework_Error_Deprecated::$enabled !== TRUE) {
return FALSE;
}
$exception = 'PHPUnit_Framework_Error_Deprecated';
}
else {
$exception = 'PHPUnit_Framework_Error';
}
throw new $exception($errstr, $errno, $errfile, $errline);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Utility methods for PHP sub-processes.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.4.0
*/
abstract class PHPUnit_Util_PHP
{
/**
* @var string $phpBinary
*/
protected $phpBinary;
/**
* 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 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.
*
* 2. 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.
*
* 3. When the PHP CLI/CGI binary configured with the PEAR Installer
* (php_bin configuration value) is readable, it will be used.
*
* 4. The current PHP interpreter is assumed to be in the $PATH and
* to be invokable through "php".
*
* @return string
*/
protected function getPhpBinary()
{
if ($this->phpBinary === NULL) {
if (defined("PHP_BINARY")) {
$this->phpBinary = PHP_BINARY;
} else if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
if (strpos($_SERVER['_'], 'phpunit') !== FALSE) {
$file = file($_SERVER['_']);
if (strpos($file[0], ' ') !== FALSE) {
$tmp = explode(' ', $file[0]);
$this->phpBinary = trim($tmp[1]);
} else {
$this->phpBinary = ltrim(trim($file[0]), '#!');
}
} else if (strpos(basename($_SERVER['_']), 'php') !== FALSE) {
$this->phpBinary = $_SERVER['_'];
}
}
if ($this->phpBinary === NULL) {
$possibleBinaryLocations = array(
PHP_BINDIR . '/php',
PHP_BINDIR . '/php-cli.exe',
PHP_BINDIR . '/php.exe',
'@php_bin@',
);
foreach ($possibleBinaryLocations as $binary) {
if (is_readable($binary)) {
$this->phpBinary = $binary;
break;
}
}
}
if (!is_readable($this->phpBinary)) {
$this->phpBinary = 'php';
} else {
$this->phpBinary = escapeshellarg($this->phpBinary);
}
}
return $this->phpBinary;
}
/**
* @return PHPUnit_Util_PHP
* @since Method available since Release 3.5.12
*/
public static function factory()
{
if (DIRECTORY_SEPARATOR == '\\') {
return new PHPUnit_Util_PHP_Windows;
}
return new PHPUnit_Util_PHP_Default;
}
/**
* Runs a single job (PHP code) using a separate PHP process.
*
* @param string $job
* @param PHPUnit_Framework_TestCase $test
* @param PHPUnit_Framework_TestResult $result
* @return array|null
* @throws PHPUnit_Framework_Exception
*/
public function runJob($job, PHPUnit_Framework_Test $test = NULL, PHPUnit_Framework_TestResult $result = NULL)
{
$process = proc_open(
$this->getPhpBinary(),
array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
),
$pipes
);
if (!is_resource($process)) {
throw new PHPUnit_Framework_Exception(
'Unable to create process for process isolation.'
);
}
if ($result !== NULL) {
$result->startTest($test);
}
$this->process($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);
$this->cleanup();
if ($result !== NULL) {
$this->processChildResult($test, $result, $stdout, $stderr);
} else {
return array('stdout' => $stdout, 'stderr' => $stderr);
}
}
/**
* @param resource $pipe
* @param string $job
* @since Method available since Release 3.5.12
*/
abstract protected function process($pipe, $job);
/**
* @since Method available since Release 3.5.12
*/
protected function cleanup()
{
}
/**
* Processes the TestResult object from an isolated process.
*
* @param PHPUnit_Framework_TestCase $test
* @param PHPUnit_Framework_TestResult $result
* @param string $stdout
* @param string $stderr
* @since Method available since Release 3.5.0
*/
protected function processChildResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result, $stdout, $stderr)
{
$time = 0;
if (!empty($stderr)) {
$result->addError(
$test,
new PHPUnit_Framework_Exception(trim($stderr)), $time
);
} else {
set_error_handler(function($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
});
try {
$childResult = unserialize($stdout);
restore_error_handler();
} catch (ErrorException $e) {
restore_error_handler();
$childResult = FALSE;
$result->addError(
$test, new PHPUnit_Framework_Exception(trim($stdout), 0, $e), $time
);
}
if ($childResult !== FALSE) {
if (!empty($childResult['output'])) {
print $childResult['output'];
}
$test->setResult($childResult['testResult']);
$test->addToAssertionCount($childResult['numAssertions']);
$childResult = $childResult['result'];
if ($result->getCollectCodeCoverageInformation()) {
$result->getCodeCoverage()->merge(
$childResult->getCodeCoverage()
);
}
$time = $childResult->time();
$notImplemented = $childResult->notImplemented();
$skipped = $childResult->skipped();
$errors = $childResult->errors();
$failures = $childResult->failures();
if (!empty($notImplemented)) {
$result->addError(
$test, $this->getException($notImplemented[0]), $time
);
}
else if (!empty($skipped)) {
$result->addError(
$test, $this->getException($skipped[0]), $time
);
}
else if (!empty($errors)) {
$result->addError(
$test, $this->getException($errors[0]), $time
);
}
else if (!empty($failures)) {
$result->addFailure(
$test, $this->getException($failures[0]), $time
);
}
}
}
$result->endTest($test, $time);
}
/**
* Gets the thrown exception from a PHPUnit_Framework_TestFailure.
*
* @param PHPUnit_Framework_TestFailure $error
* @since Method available since Release 3.6.0
* @see https://github.com/sebastianbergmann/phpunit/issues/74
*/
protected function getException(PHPUnit_Framework_TestFailure $error)
{
$exception = $error->thrownException();
if ($exception instanceof __PHP_Incomplete_Class) {
$exceptionArray = array();
foreach ((array)$exception as $key => $value) {
$key = substr($key, strrpos($key, "\0") + 1);
$exceptionArray[$key] = $value;
}
$exception = new PHPUnit_Framework_SyntheticError(
sprintf(
'%s: %s',
$exceptionArray['_PHP_Incomplete_Class_Name'],
$exceptionArray['message']
),
$exceptionArray['code'],
$exceptionArray['file'],
$exceptionArray['line'],
$exceptionArray['trace']
);
}
return $exception;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.6.0
*/
/**
* String helpers.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.6.0
*/
class PHPUnit_Util_String
{
/**
* Converts a string to UTF-8 encoding.
*
* @param string $string
* @return string
*/
public 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
*/
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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* A TestListener that generates a logfile of the
* test execution using the Test Anything Protocol (TAP).
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 PHPUnit_Framework_Exception
* @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()
);
}
}
$yaml = new Symfony\Component\Yaml\Dumper;
$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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.3.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
$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);
$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)
)
);
$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)
)
);
$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;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* A TestListener that generates JSON messages.
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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, FALSE),
$e->getMessage(),
$test
);
$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, FALSE),
$e->getMessage(),
$test
);
$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,
PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE),
'Incomplete Test: ' . $e->getMessage(),
$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,
PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE),
'Skipped Test: ' . $e->getMessage(),
$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 = '';
$this->write(
array(
'event' => 'suiteStart',
'suite' => $this->currentTestSuiteName,
'tests' => count($suite)
)
);
}
/**
* 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;
$this->write(
array(
'event' => 'testStart',
'suite' => $this->currentTestSuiteName,
'test' => $this->currentTestName
)
);
}
/**
* 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, array(), '', $test);
}
}
/**
* @param string $status
* @param float $time
* @param array $trace
* @param string $message
*/
protected function writeCase($status, $time, array $trace = array(), $message = '', $test = NULL)
{
$output = '';
if ($test !== NULL && $test->hasOutput()) {
$output = $test->getActualOutput();
}
$this->write(
array(
'event' => 'test',
'suite' => $this->currentTestSuiteName,
'test' => $this->currentTestName,
'status' => $status,
'time' => $time,
'trace' => $trace,
'message' => PHPUnit_Util_String::convertToUtf8($message),
'output' => $output,
)
);
}
/**
* @param string $buffer
*/
public function write($buffer)
{
array_walk_recursive($buffer, function(&$input) {
if (is_string($input)) {
$input = PHPUnit_Util_String::convertToUtf8($input);
}
});
if (defined('JSON_PRETTY_PRINT')) {
parent::write(json_encode($buffer, JSON_PRETTY_PRINT));
} else {
parent::write(json_encode($buffer));
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.2.0
*/
/**
* XML helpers.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 <mail@kore-nordmann.de>
* @since Method available since Release 3.4.6
*/
public static function prepareString($string)
{
return preg_replace_callback(
'/[\\x00-\\x04\\x0b\\x0c\\x0e-\\x1f\\x7f]/',
function ($matches)
{
return sprintf('&#x%02x;', ord($matches[0]));
},
htmlspecialchars(
PHPUnit_Util_String::convertToUtf8($string), ENT_COMPAT, 'UTF-8'
)
);
}
/**
* Loads an XML (or HTML) file into a DOMDocument object.
*
* @param string $filename
* @param boolean $isHtml
* @param boolean $xinclude
* @return DOMDocument
* @since Method available since Release 3.3.0
*/
public static function loadFile($filename, $isHtml = FALSE, $xinclude = 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, $xinclude);
}
/**
* 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. If $isHtml is
* false and $xinclude is true, xinclude is performed on the loaded
* DOMDocument.
*
* 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
* @param boolean $xinclude
* @return DOMDocument
* @since Method available since Release 3.3.0
* @author Mike Naberezny <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
* @author Tobias Schlitt <toby@php.net>
*/
public static function load($actual, $isHtml = FALSE, $filename = '', $xinclude = FALSE)
{
if ($actual instanceof DOMDocument) {
return $actual;
}
$document = new DOMDocument;
$internal = libxml_use_internal_errors(TRUE);
$message = '';
$reporting = error_reporting(0);
if ($isHtml) {
$loaded = $document->loadHTML($actual);
} else {
$loaded = $document->loadXML($actual);
}
if ('' !== $filename) {
// Necessary for xinclude
$document->documentURI = $filename;
}
if (!$isHtml && $xinclude) {
$document->xinclude();
}
foreach (libxml_get_errors() as $error) {
$message .= $error->message;
}
libxml_use_internal_errors($internal);
error_reporting($reporting);
if ($loaded === FALSE) {
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 $document;
}
/**
*
*
* @param DOMNode $node
* @return string
* @since Method available since Release 3.4.0
*/
public static function nodeToText(DOMNode $node)
{
if ($node->childNodes->length == 1) {
return $node->nodeValue;
}
$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 <mattis@xait.no>
*/
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 PHPUnit_Framework_Exception
* @since Method available since Release 3.3.0
* @author Mike Naberezny <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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 PHPUnit_Framework_Exception(
'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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
* @author Tobias Schlitt <toby@php.net>
*/
public static function cssSelect($selector, $content, $actual, $isHtml = TRUE)
{
$matcher = self::convertSelectToTag($selector, $content);
$dom = self::load($actual, $isHtml);
$tags = self::findNodes($dom, $matcher, $isHtml);
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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
* @author Tobias Schlitt <toby@php.net>
*/
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 empty string
else if ($options['content'] === '') {
if (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'], $isHtml);
$parentNode = isset($parentNodes[0]) ? $parentNodes[0] : NULL;
foreach ($nodes as $node) {
if ($parentNode !== $node->parentNode) {
continue;
}
$filtered[] = $node;
}
$nodes = $filtered;
$filtered = array();
if (empty($nodes)) {
return FALSE;
}
}
// filter by child node
if ($options['child']) {
$childNodes = self::findNodes($dom, $options['child'], $isHtml);
$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'], $isHtml);
$ancestorNode = isset($ancestorNodes[0]) ? $ancestorNodes[0] : NULL;
foreach ($nodes as $node) {
$parent = $node->parentNode;
while ($parent && $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'], $isHtml);
$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'], $isHtml
);
// 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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
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 <mike@maintainable.com>
* @author Derek DeVries <derek@maintainable.com>
*/
protected static function getNodeText(DOMNode $node)
{
if (!$node->childNodes instanceof DOMNodeList) {
return '';
}
$result = '';
foreach ($node->childNodes as $childNode) {
if ($childNode->nodeType === XML_TEXT_NODE ||
$childNode->nodeType === XML_CDATA_SECTION_NODE) {
$result .= trim($childNode->data) . ' ';
} else {
$result .= self::getNodeText($childNode);
}
}
return str_replace(' ', ' ', $result);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Command-line options parsing class.
*
* @package PHPUnit
* @subpackage Util
* @author Andrei Zmievski <andrei@php.net>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.0.0
*/
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");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Filesystem helpers.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.0.0
*/
class PHPUnit_Util_Filesystem
{
/**
* @var array
*/
protected static $buffer = 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';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Utility class for textual type (and value) representation.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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'
)
);
}
/**
* Exports a value into a string
*
* The output of this method is similar to the output of print_r(), but
* improved in various aspects:
*
* - NULL is rendered as "null" (instead of "")
* - TRUE is rendered as "true" (instead of "1")
* - FALSE is rendered as "false" (instead of "")
* - Strings are always quoted with single quotes
* - Carriage returns and newlines are normalized to \n
* - Recursion and repeated rendering is treated properly
*
* @param mixed $value The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
* @since Method available since Release 3.6.0
*/
public static function export($value, $indentation = 0)
{
return self::recursiveExport($value, $indentation);
}
/**
* Recursive implementation of export
*
* @param mixed $value The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @param array $processedObjects Contains all objects that were already
* rendered
* @return string
* @since Method available since Release 3.6.0
* @see PHPUnit_Util_Type::export
*/
protected static function recursiveExport($value, $indentation, &$processedObjects = array())
{
if ($value === NULL) {
return 'null';
}
if ($value === TRUE) {
return 'true';
}
if ($value === FALSE) {
return 'false';
}
if (is_string($value)) {
// Match for most non printable chars somewhat taking multibyte chars into account
if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
return 'Binary String: 0x' . bin2hex($value);
}
return "'" .
str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) .
"'";
}
$origValue = $value;
if (is_object($value)) {
if (in_array($value, $processedObjects, TRUE)) {
return sprintf(
'%s Object (*RECURSION*)',
get_class($value)
);
}
$processedObjects[] = $value;
// Convert object to array
$value = self::toArray($value);
}
if (is_array($value)) {
$whitespace = str_repeat(' ', $indentation);
// There seems to be no other way to check arrays for recursion
// http://www.php.net/manual/en/language.types.array.php#73936
preg_match_all('/\n \[(\w+)\] => Array\s+\*RECURSION\*/', print_r($value, TRUE), $matches);
$recursiveKeys = array_unique($matches[1]);
// Convert to valid array keys
// Numeric integer strings are automatically converted to integers
// by PHP
foreach ($recursiveKeys as $key => $recursiveKey) {
if ((string)(integer)$recursiveKey === $recursiveKey) {
$recursiveKeys[$key] = (integer)$recursiveKey;
}
}
$content = '';
foreach ($value as $key => $val) {
if (in_array($key, $recursiveKeys, TRUE)) {
$val = 'Array (*RECURSION*)';
}
else {
$val = self::recursiveExport($val, $indentation+1, $processedObjects);
}
$content .= $whitespace . ' ' . self::export($key) . ' => ' . $val . "\n";
}
if (strlen($content) > 0) {
$content = "\n" . $content . $whitespace;
}
return sprintf(
"%s (%s)",
is_object($origValue) ? get_class($origValue) . ' Object' : 'Array',
$content
);
}
if (is_double($value) && (double)(integer)$value === $value) {
return $value . '.0';
}
return (string)$value;
}
/**
* Exports a value into a single-line string
*
* The output of this method is similar to the output of
* PHPUnit_Util_Type::export. This method guarantees thought that the
* result contains now newlines.
*
* Newlines are replaced by the visible string '\n'. Contents of arrays
* and objects (if any) are replaced by '...'.
*
* @param mixed $value The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
* @see PHPUnit_Util_Type::export
*/
public static function shortenedExport($value)
{
if (is_string($value)) {
return self::shortenedString($value);
}
if (is_object($value)) {
return sprintf(
'%s Object (%s)',
get_class($value),
count(self::toArray($value)) > 0 ? '...' : ''
);
}
if (is_array($value)) {
return sprintf(
'Array (%s)',
count($value) > 0 ? '...' : ''
);
}
return self::export($value);
}
/**
* Shortens a string and converts all new lines to '\n'
*
* @param string $string The string to shorten
* @param integer $max The maximum length for the string
* @return string
*/
public static function shortenedString($string, $maxLength = 40)
{
$string = self::export($string);
if (strlen($string) > $maxLength) {
$string = substr($string, 0, $maxLength - 10) . '...' . substr($string, -7);
}
return str_replace("\n", '\n', $string);
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
* @since Method available since Release 3.6.0
*/
public static function toArray($object)
{
$array = array();
foreach ((array)$object as $key => $value) {
// properties are transformed to keys in the following way:
// private $property => "\0Classname\0property"
// protected $property => "\0*\0property"
// public $property => "property"
if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
$key = $matches[1];
}
$array[$key] = $value;
}
// Some internal classes like SplObjectStorage don't work with the
// above (fast) mechanism nor with reflection
// Format the output similarly to print_r() in this case
if ($object instanceof SplObjectStorage) {
foreach ($object as $key => $value) {
$array[spl_object_hash($value)] = array(
'obj' => $value,
'inf' => $object->getInfo(),
);
}
}
return $array;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Factory for PHPUnit_Framework_Exception objects that are used to describe
* invalid arguments passed to a function or method.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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)
{
$stack = debug_backtrace(FALSE);
return new PHPUnit_Framework_Exception(
sprintf(
'Argument #%d%sof %s::%s() must be a %s',
$argument,
$value !== NULL ? ' (' . $value . ')' : ' ',
$stack[1]['class'],
$stack[1]['function'],
$type
)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.0
*/
/**
* Class helpers.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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)
);
}
/**
* 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
* @param boolean $forCall
* @return string
* @since Method available since Release 3.2.0
*/
public static function getMethodParameters($method, $forCall = FALSE)
{
$parameters = array();
foreach ($method->getParameters() as $i => $parameter) {
$name = '$' . $parameter->getName();
/* Note: PHP extensions may use empty names for reference arguments
* or "..." for methods taking a variable number of arguments.
*/
if ($name === '$' || $name === '$...') {
$name = '$arg' . $i;
}
$default = '';
$reference = '';
$typeHint = '';
if (!$forCall) {
if ($parameter->isArray()) {
$typeHint = 'array ';
}
else if (version_compare(PHP_VERSION, '5.4', '>') &&
$parameter->isCallable()) {
$typeHint = 'callable ';
}
else {
try {
$class = $parameter->getClass();
}
catch (ReflectionException $e) {
$class = FALSE;
}
if ($class) {
$typeHint = $class->getName() . ' ';
}
}
if ($parameter->isDefaultValueAvailable()) {
$value = $parameter->getDefaultValue();
$default = ' = ' . var_export($value, TRUE);
}
else if ($parameter->isOptional()) {
$default = ' = null';
}
}
if ($parameter->isPassedByReference()) {
$reference = '&';
}
$parameters[] = $typeHint . $reference . $name . $default;
}
return join(', ', $parameters);
}
/**
* 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 PHPUnit_Framework_Exception
* @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 PHPUnit_Framework_Exception
* @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');
}
try {
$attribute = new ReflectionProperty($object, $attributeName);
}
catch (ReflectionException $e) {
$reflector = new ReflectionObject($object);
while ($reflector = $reflector->getParentClass()) {
try {
$attribute = $reflector->getProperty($attributeName);
break;
}
catch(ReflectionException $e) {
}
}
}
if (isset($attribute)) {
if (!$attribute || $attribute->isPublic()) {
return $object->$attributeName;
}
$attribute->setAccessible(TRUE);
$value = $attribute->getValue($object);
$attribute->setAccessible(FALSE);
return $value;
}
throw new PHPUnit_Framework_Exception(
sprintf(
'Attribute "%s" not found in object.',
$attributeName
)
);
}
/**
* 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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2010, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Framework
* @author Ralph Schindler <ralph.schindler@zend.com>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2002-2010 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.5.7
*/
/**
* Class to hold the information about a deprecated feature that was used
*
* @package PHPUnit
* @subpackage Framework
* @author Ralph Schindler <ralph.schindler@zend.com>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2002-2010 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Interface available since Release 3.5.7
*/
class PHPUnit_Util_DeprecatedFeature
{
/**
* @var array
*/
protected $traceInfo = array();
/**
* @var string
*/
protected $message = NULL;
/**
* @param string $message
* @param array $traceInfo
*/
public function __construct($message, array $traceInfo = array())
{
$this->message = $message;
$this->traceInfo = $traceInfo;
}
/**
* Build a string representation of the deprecated feature that was raised
*
* @return string
*/
public function __toString()
{
$string = '';
if (isset($this->traceInfo['file'])) {
$string .= $this->traceInfo['file'];
if (isset($this->traceInfo['line'])) {
$string .= ':' . $this->traceInfo['line'] . ' - ';
}
}
$string .= $this->message;
return $string;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.2.0
*/
/**
* Wrapper for the PHPUnit XML configuration file.
*
* Example XML configuration file:
* <code>
* <?xml version="1.0" encoding="utf-8" ?>
*
* <phpunit backupGlobals="true"
* backupStaticAttributes="false"
* bootstrap="/path/to/bootstrap.php"
* cacheTokens="false"
* colors="false"
* convertErrorsToExceptions="true"
* convertNoticesToExceptions="true"
* convertWarningsToExceptions="true"
* forceCoversAnnotation="false"
* mapTestClassNameToCoveredClassName="false"
* printerClass="PHPUnit_TextUI_ResultPrinter"
* processIsolation="false"
* stopOnError="false"
* stopOnFailure="false"
* stopOnIncomplete="false"
* stopOnSkipped="false"
* testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
* timeoutForSmallTests="1"
* timeoutForMediumTests="10"
* timeoutForLargeTests="60"
* strict="false"
* verbose="false">
* <testsuites>
* <testsuite name="My Test Suite">
* <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">/path/to/files</directory>
* <file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>
* <exclude>/path/to/files/exclude</exclude>
* </testsuite>
* </testsuites>
*
* <groups>
* <include>
* <group>name</group>
* </include>
* <exclude>
* <group>name</group>
* </exclude>
* </groups>
*
* <filter>
* <blacklist>
* <directory suffix=".php">/path/to/files</directory>
* <file>/path/to/file</file>
* <exclude>
* <directory suffix=".php">/path/to/files</directory>
* <file>/path/to/file</file>
* </exclude>
* </blacklist>
* <whitelist addUncoveredFilesFromWhitelist="true"
* processUncoveredFilesFromWhitelist="false">
* <directory suffix=".php">/path/to/files</directory>
* <file>/path/to/file</file>
* <exclude>
* <directory suffix=".php">/path/to/files</directory>
* <file>/path/to/file</file>
* </exclude>
* </whitelist>
* </filter>
*
* <listeners>
* <listener class="MyListener" file="/optional/path/to/MyListener.php">
* <arguments>
* <array>
* <element key="0">
* <string>Sebastian</string>
* </element>
* </array>
* <integer>22</integer>
* <string>April</string>
* <double>19.78</double>
* <null/>
* <object class="stdClass"/>
* <file>MyRelativeFile.php</file>
* <directory>MyRelativeDir</directory>
* </arguments>
* </listener>
* </listeners>
*
* <logging>
* <log type="coverage-html" target="/tmp/report"
charset="UTF-8" highlight="false"
* lowUpperBound="35" highLowerBound="70"/>
* <log type="coverage-clover" target="/tmp/clover.xml"/>
* <log type="json" target="/tmp/logfile.json"/>
* <log type="plain" target="/tmp/logfile.txt"/>
* <log type="tap" target="/tmp/logfile.tap"/>
* <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
* <log type="testdox-html" target="/tmp/testdox.html"/>
* <log type="testdox-text" target="/tmp/testdox.txt"/>
* </logging>
*
* <php>
* <includePath>.</includePath>
* <ini name="foo" value="bar"/>
* <const name="foo" value="bar"/>
* <var name="foo" value="bar"/>
* <env name="foo" value="bar"/>
* <post name="foo" value="bar"/>
* <get name="foo" value="bar"/>
* <cookie name="foo" value="bar"/>
* <server name="foo" value="bar"/>
* <files name="foo" value="bar"/>
* <request name="foo" value="bar"/>
* </php>
*
* <selenium>
* <browser name="Firefox on Linux"
* browser="*firefox /usr/lib/firefox/firefox-bin"
* host="my.linux.box"
* port="4444"
* timeout="30000"/>
* </selenium>
* </phpunit>
* </code>
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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;
protected $filename;
/**
* Loads a PHPUnit configuration file.
*
* @param string $filename
*/
protected function __construct($filename)
{
$this->filename = $filename;
$this->document = PHPUnit_Util_XML::loadFile($filename, FALSE, TRUE);
$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 realpath to the configuration file.
*
* @return string
* @since Method available since Release 3.6.0
*/
public function getFilename()
{
return $this->filename;
}
/**
* Returns the configuration for SUT filtering.
*
* @return array
* @since Method available since Release 3.2.1
*/
public function getFilterConfiguration()
{
$addUncoveredFilesFromWhitelist = TRUE;
$processUncoveredFilesFromWhitelist = FALSE;
$tmp = $this->xpath->query('filter/whitelist');
if ($tmp->length == 1) {
if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
$addUncoveredFilesFromWhitelist = $this->getBoolean(
(string)$tmp->item(0)->getAttribute(
'addUncoveredFilesFromWhitelist'
),
TRUE
);
}
if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) {
$processUncoveredFilesFromWhitelist = $this->getBoolean(
(string)$tmp->item(0)->getAttribute(
'processUncoveredFilesFromWhitelist'
),
FALSE
);
}
}
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,
'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist,
'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 = $this->toAbsolutePath(
(string)$listener->getAttribute('file'), TRUE
);
}
foreach ($listener->childNodes as $node) {
if ($node instanceof DOMElement && $node->tagName == 'arguments') {
foreach ($node->childNodes as $argument) {
if ($argument instanceof DOMElement) {
if ($argument->tagName == 'file' ||
$argument->tagName == 'directory') {
$arguments[] = $this->toAbsolutePath((string)$argument->nodeValue);
} else {
$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 = $this->toAbsolutePath(
(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('highlight')) {
$result['highlight'] = $this->getBoolean(
(string)$log->getAttribute('highlight'),
FALSE
);
}
}
else if ($type == 'junit') {
if ($log->hasAttribute('logIncompleteSkipped')) {
$result['logIncompleteSkipped'] = $this->getBoolean(
(string)$log->getAttribute('logIncompleteSkipped'),
FALSE
);
}
}
else if ($type == 'coverage-text') {
if ($log->hasAttribute('showUncoveredFiles')) {
$result['coverageTextShowUncoveredFiles'] = $this->getBoolean(
(string)$log->getAttribute('showUncoveredFiles'),
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(
'include_path' => array(),
'ini' => array(),
'const' => array(),
'var' => array(),
'env' => array(),
'post' => array(),
'get' => array(),
'cookie' => array(),
'server' => array(),
'files' => array(),
'request' => array()
);
foreach ($this->xpath->query('php/includePath') as $includePath) {
$path = (string)$includePath->nodeValue;
$result['include_path'][] = $this->toAbsolutePath($path);
}
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');
$result['const'][$name] = $this->getBoolean($value, $value);
}
foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
foreach ($this->xpath->query('php/' . $array) as $var) {
$name = (string)$var->getAttribute('name');
$value = (string)$var->getAttribute('value');
$result[$array][$name] = $this->getBoolean($value, $value);
}
}
return $result;
}
/**
* Handles the PHP configuration.
*
* @since Method available since Release 3.2.20
*/
public function handlePHPConfiguration()
{
$configuration = $this->getPHPConfiguration();
if (! empty($configuration['include_path'])) {
ini_set(
'include_path',
implode(PATH_SEPARATOR, $configuration['include_path']) .
PATH_SEPARATOR .
ini_get('include_path')
);
}
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 (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
// See https://github.com/sebastianbergmann/phpunit/issues/277
switch ($array) {
case 'var':
$target = &$GLOBALS;
break;
case 'env':
$target = &$_ENV;
break;
case 'server':
$target = &$_SERVER;
break;
default:
$target = &$GLOBALS['_' . strtoupper($array)];
break;
}
foreach ($configuration[$array] as $name => $value) {
$target[$name] = $value;
}
}
foreach ($configuration['env'] as $name => $value) {
putenv("$name=$value");
}
}
/**
* Returns the PHPUnit configuration.
*
* @return array
* @since Method available since Release 3.2.14
*/
public function getPHPUnitConfiguration()
{
$result = array();
$root = $this->document->documentElement;
if ($root->hasAttribute('cacheTokens')) {
$result['cacheTokens'] = $this->getBoolean(
(string)$root->getAttribute('cacheTokens'), FALSE
);
}
if ($root->hasAttribute('colors')) {
$result['colors'] = $this->getBoolean(
(string)$root->getAttribute('colors'), FALSE
);
}
if ($root->hasAttribute('backupGlobals')) {
$result['backupGlobals'] = $this->getBoolean(
(string)$root->getAttribute('backupGlobals'), TRUE
);
}
if ($root->hasAttribute('backupStaticAttributes')) {
$result['backupStaticAttributes'] = $this->getBoolean(
(string)$root->getAttribute('backupStaticAttributes'), FALSE
);
}
if ($root->hasAttribute('bootstrap')) {
$result['bootstrap'] = $this->toAbsolutePath(
(string)$root->getAttribute('bootstrap')
);
}
if ($root->hasAttribute('convertErrorsToExceptions')) {
$result['convertErrorsToExceptions'] = $this->getBoolean(
(string)$root->getAttribute('convertErrorsToExceptions'), TRUE
);
}
if ($root->hasAttribute('convertNoticesToExceptions')) {
$result['convertNoticesToExceptions'] = $this->getBoolean(
(string)$root->getAttribute('convertNoticesToExceptions'), TRUE
);
}
if ($root->hasAttribute('convertWarningsToExceptions')) {
$result['convertWarningsToExceptions'] = $this->getBoolean(
(string)$root->getAttribute('convertWarningsToExceptions'), TRUE
);
}
if ($root->hasAttribute('forceCoversAnnotation')) {
$result['forceCoversAnnotation'] = $this->getBoolean(
(string)$root->getAttribute('forceCoversAnnotation'), FALSE
);
}
if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) {
$result['mapTestClassNameToCoveredClassName'] = $this->getBoolean(
(string)$root->getAttribute('mapTestClassNameToCoveredClassName'),
FALSE
);
}
if ($root->hasAttribute('processIsolation')) {
$result['processIsolation'] = $this->getBoolean(
(string)$root->getAttribute('processIsolation'), FALSE
);
}
if ($root->hasAttribute('stopOnError')) {
$result['stopOnError'] = $this->getBoolean(
(string)$root->getAttribute('stopOnError'), FALSE
);
}
if ($root->hasAttribute('stopOnFailure')) {
$result['stopOnFailure'] = $this->getBoolean(
(string)$root->getAttribute('stopOnFailure'), FALSE
);
}
if ($root->hasAttribute('stopOnIncomplete')) {
$result['stopOnIncomplete'] = $this->getBoolean(
(string)$root->getAttribute('stopOnIncomplete'), FALSE
);
}
if ($root->hasAttribute('stopOnSkipped')) {
$result['stopOnSkipped'] = $this->getBoolean(
(string)$root->getAttribute('stopOnSkipped'), FALSE
);
}
if ($root->hasAttribute('testSuiteLoaderClass')) {
$result['testSuiteLoaderClass'] = (string)$root->getAttribute(
'testSuiteLoaderClass'
);
}
if ($root->hasAttribute('testSuiteLoaderFile')) {
$result['testSuiteLoaderFile'] = (string)$root->getAttribute(
'testSuiteLoaderFile'
);
}
if ($root->hasAttribute('printerClass')) {
$result['printerClass'] = (string)$root->getAttribute(
'printerClass'
);
}
if ($root->hasAttribute('printerFile')) {
$result['printerFile'] = (string)$root->getAttribute(
'printerFile'
);
}
if ($root->hasAttribute('timeoutForSmallTests')) {
$result['timeoutForSmallTests'] = $this->getInteger(
(string)$root->getAttribute('timeoutForSmallTests'), 1
);
}
if ($root->hasAttribute('timeoutForMediumTests')) {
$result['timeoutForMediumTests'] = $this->getInteger(
(string)$root->getAttribute('timeoutForMediumTests'), 10
);
}
if ($root->hasAttribute('timeoutForLargeTests')) {
$result['timeoutForLargeTests'] = $this->getInteger(
(string)$root->getAttribute('timeoutForLargeTests'), 60
);
}
if ($root->hasAttribute('strict')) {
$result['strict'] = $this->getBoolean(
(string)$root->getAttribute('strict'), FALSE
);
}
if ($root->hasAttribute('verbose')) {
$result['verbose'] = $this->getBoolean(
(string)$root->getAttribute('verbose'), FALSE
);
}
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 = $this->getInteger(
(string)$config->getAttribute('port'), 4444
);
} else {
$port = 4444;
}
if ($config->hasAttribute('timeout')) {
$timeout = $this->getInteger(
(string)$config->getAttribute('timeout'), 30000
);
} else {
$timeout = 30000;
}
$result[] = array(
'name' => $name,
'browser' => $browser,
'host' => $host,
'port' => $port,
'timeout' => $timeout
);
}
return $result;
}
/**
* Returns the test suite configuration.
*
* @return PHPUnit_Framework_TestSuite
* @since Method available since Release 3.2.1
*/
public function getTestSuiteConfiguration($testSuiteFilter=null)
{
$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), $testSuiteFilter);
}
if ($testSuiteNodes->length > 1) {
$suite = new PHPUnit_Framework_TestSuite;
foreach ($testSuiteNodes as $testSuiteNode) {
$suite->addTestSuite(
$this->getTestSuite($testSuiteNode, $testSuiteFilter)
);
}
return $suite;
}
}
/**
* @param DOMElement $testSuiteNode
* @return PHPUnit_Framework_TestSuite
* @since Method available since Release 3.4.0
*/
protected function getTestSuite(DOMElement $testSuiteNode, $testSuiteFilter=null)
{
if ($testSuiteNode->hasAttribute('name')) {
$suite = new PHPUnit_Framework_TestSuite(
(string)$testSuiteNode->getAttribute('name')
);
} else {
$suite = new PHPUnit_Framework_TestSuite;
}
$exclude = array();
foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) {
$exclude[] = (string)$excludeNode->nodeValue;
}
$fileIteratorFacade = new File_Iterator_Facade;
foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
if ($testSuiteFilter && $directoryNode->parentNode->getAttribute('name') != $testSuiteFilter) {
continue;
}
$directory = (string)$directoryNode->nodeValue;
if (empty($directory)) {
continue;
}
if ($directoryNode->hasAttribute('phpVersion')) {
$phpVersion = (string)$directoryNode->getAttribute('phpVersion');
} else {
$phpVersion = PHP_VERSION;
}
if ($directoryNode->hasAttribute('phpVersionOperator')) {
$phpVersionOperator = (string)$directoryNode->getAttribute('phpVersionOperator');
} else {
$phpVersionOperator = '>=';
}
if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
continue;
}
if ($directoryNode->hasAttribute('prefix')) {
$prefix = (string)$directoryNode->getAttribute('prefix');
} else {
$prefix = '';
}
if ($directoryNode->hasAttribute('suffix')) {
$suffix = (string)$directoryNode->getAttribute('suffix');
} else {
$suffix = 'Test.php';
}
$files = $fileIteratorFacade->getFilesAsArray(
$this->toAbsolutePath($directory),
$suffix,
$prefix,
$exclude
);
$suite->addTestFiles($files);
}
foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
if ($testSuiteFilter && $fileNode->parentNode->getAttribute('name') != $testSuiteFilter) {
continue;
}
$file = (string)$fileNode->nodeValue;
if (empty($file)) {
continue;
}
// Get the absolute path to the file
$file = $fileIteratorFacade->getFilesAsArray($file);
if (!isset($file[0])) {
continue;
}
$file = $file[0];
if ($fileNode->hasAttribute('phpVersion')) {
$phpVersion = (string)$fileNode->getAttribute('phpVersion');
} else {
$phpVersion = PHP_VERSION;
}
if ($fileNode->hasAttribute('phpVersionOperator')) {
$phpVersionOperator = (string)$fileNode->getAttribute('phpVersionOperator');
} else {
$phpVersionOperator = '>=';
}
if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
continue;
}
$suite->addTestFile($file);
}
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 $value
* @param boolean $default
* @return boolean
* @since Method available since Release 3.6.0
*/
protected function getInteger($value, $default)
{
if (is_numeric($value)) {
return (int)$value;
}
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' => $this->toAbsolutePath((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[] = $this->toAbsolutePath((string)$file->nodeValue);
}
return $files;
}
/**
* @param string $path
* @param boolean $useIncludePath
* @return string
* @since Method available since Release 3.5.0
*/
protected function toAbsolutePath($path, $useIncludePath = FALSE)
{
// Check whether the path is already absolute.
if ($path[0] === '/' || $path[0] === '\\' ||
(strlen($path) > 3 && ctype_alpha($path[0]) &&
$path[1] === ':' && ($path[2] === '\\' || $path[2] === '/'))) {
return $path;
}
// Check whether a stream is used.
if (strpos($path, '://') !== FALSE) {
return $path;
}
$file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path;
if ($useIncludePath && !file_exists($file)) {
$includePathFile = stream_resolve_include_path($path);
if ($includePathFile) {
$file = $includePathFile;
}
}
return $file;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* Test helpers.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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._:-\\\\x7f-\xff]+)/';
const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<value>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s(?P<value>([^ ]+))\r?$/m';
const SMALL = 0;
const MEDIUM = 1;
const LARGE = 2;
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));
}
}
}
/**
* Returns the requirements for a test.
*
* @param string $className
* @param string $methodName
* @return array
* @since Method available since Release 3.6.0
*/
public static function getRequirements($className, $methodName)
{
$reflector = new ReflectionClass($className);
$docComment = $reflector->getDocComment();
$reflector = new ReflectionMethod($className, $methodName);
$docComment .= "\n" . $reflector->getDocComment();
$requires = array();
if ($count = preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) {
for ($i = 0; $i < $count; $i++) {
$requires[$matches['name'][$i]] = $matches['value'][$i];
}
}
// https://bugs.php.net/bug.php?id=63055
$matches = array();
if ($count = preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) {
for ($i = 0; $i < $count; $i++) {
$name = $matches['name'][$i] . 's';
if (!isset($requires[$name])) {
$requires[$name] = array();
}
$requires[$name][] = $matches['value'][$i];
}
}
return $requires;
}
/**
* Returns the expected exception for a test.
*
* @param string $className
* @param string $methodName
* @return array
* @since Method available since Release 3.3.6
*/
public static function getExpectedException($className, $methodName)
{
$reflector = new ReflectionMethod($className, $methodName);
$docComment = $reflector->getDocComment();
$docComment = substr($docComment, 3, -2);
if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) {
$annotations = self::parseTestMethodAnnotations(
$className, $methodName
);
$class = $matches[1];
$code = NULL;
$message = '';
if (isset($matches[2])) {
$message = trim($matches[2]);
}
else if (isset($annotations['method']['expectedExceptionMessage'])) {
$message = self::_parseAnnotationContent(
$annotations['method']['expectedExceptionMessage'][0]
);
}
if (isset($matches[3])) {
$code = $matches[3];
}
else if (isset($annotations['method']['expectedExceptionCode'])) {
$code = self::_parseAnnotationContent(
$annotations['method']['expectedExceptionCode'][0]
);
}
if (is_numeric($code)) {
$code = (int)$code;
}
else if (is_string($code) && defined($code)) {
$code = (int)constant($code);
}
return array(
'class' => $class, 'code' => $code, 'message' => $message
);
}
return FALSE;
}
/**
* Parse annotation content to use constant/class constant values
*
* Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME
*
* If the constant is not found the string is used as is to ensure maximum BC.
*
* @param string $message
* @return string
*/
protected static function _parseAnnotationContent($message)
{
if (strpos($message, '::') !== FALSE && count(explode('::', $message) == 2)) {
if (defined($message)) {
$message = constant($message);
}
}
return $message;
}
/**
* Returns the provided data for a method.
*
* @param string $className
* @param string $methodName
* @param string $docComment
* @return mixed array|Iterator when a data provider is specified and exists
* false when a data provider is specified and does not exist
* null when no data provider is specified
* @since Method available since Release 3.2.0
*/
public static function getProvidedData($className, $methodName)
{
$reflector = new ReflectionMethod($className, $methodName);
$docComment = $reflector->getDocComment();
$data = NULL;
if (preg_match(self::REGEX_DATA_PROVIDER, $docComment, $matches)) {
$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) {
$data = $dataProviderMethod->invoke($object);
} else {
$data = $dataProviderMethod->invoke($object, $methodName);
}
}
if ($data !== NULL) {
if (is_object($data)) {
$data = iterator_to_array($data);
}
foreach ($data as $key => $value) {
if (!is_array($value)) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Data set %s is invalid.',
is_int($key) ? '#' . $key : '"' . $key . '"'
)
);
}
}
}
return $data;
}
/**
* @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])) {
try {
$method = new ReflectionMethod($className, $methodName);
$annotations = self::parseAnnotations($method->getDocComment());
} catch (ReflectionException $e) {
$annotations = array();
}
self::$annotationCache[$className . '::' . $methodName] = $annotations;
}
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();
// Strip away the docblock header and footer to ease parsing of one line annotations
$docblock = substr($docblock, 3, -2);
if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \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['method']['author'])) {
$groups = $annotations['method']['author'];
}
else if (isset($annotations['class']['author'])) {
$groups = $annotations['class']['author'];
}
if (isset($annotations['class']['group'])) {
$groups = array_merge($groups, $annotations['class']['group']);
}
if (isset($annotations['method']['group'])) {
$groups = array_merge($groups, $annotations['method']['group']);
}
if (isset($annotations['class']['ticket'])) {
$groups = array_merge($groups, $annotations['class']['ticket']);
}
if (isset($annotations['method']['ticket'])) {
$groups = array_merge($groups, $annotations['method']['ticket']);
}
foreach (array('small', 'medium', 'large') as $size) {
if (isset($annotations['method'][$size])) {
$groups[] = $size;
}
else if (isset($annotations['class'][$size])) {
$groups[] = $size;
}
}
return array_unique($groups);
}
/**
* Returns the size of the test.
*
* @param string $className
* @param string $methodName
* @return integer
* @since Method available since Release 3.6.0
*/
public static function getSize($className, $methodName)
{
$groups = array_flip(self::getGroups($className, $methodName));
$size = self::SMALL;
$class = new ReflectionClass($className);
if ((class_exists('PHPUnit_Extensions_Database_TestCase', FALSE) &&
$class->isSubclassOf('PHPUnit_Extensions_Database_TestCase')) ||
(class_exists('PHPUnit_Extensions_SeleniumTestCase', FALSE) &&
$class->isSubclassOf('PHPUnit_Extensions_SeleniumTestCase'))) {
$size = self::LARGE;
}
else if (isset($groups['medium'])) {
$size = self::MEDIUM;
}
else if (isset($groups['large'])) {
$size = self::LARGE;
}
return $size;
}
/**
* 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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Extensions
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.3.0
*/
/**
* 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 .
*
* <code>
* $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D'));
* </code>
*
* @package PHPUnit
* @subpackage Extensions
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
}
}
}
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Extensions_TicketListener
* @author Sean Coates <sean@caedmon.net>
* @author Raphael Stolt <raphael.stolt@gmail.com>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.4.0
*/
/**
* Base class for test listeners that interact with an issue tracker.
*
* @package PHPUnit
* @subpackage Extensions_TicketListener
* @author Sean Coates <sean@caedmon.net>
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since Class available since Release 3.4.0
*/
abstract class PHPUnit_Extensions_TicketListener implements PHPUnit_Framework_TestListener
{
/**
* @var array
*/
protected $ticketCounts = array();
/**
* @var boolean
*/
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(FALSE);
$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(FALSE);
$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;
}
$ticketInfo = $this->getTicketInfo($ticket);
if ($adjustTicket && in_array($ticketInfo['status'], $ifStatus)) {
$this->updateTicket($ticket, $newStatus, $message, $resolution);
}
}
}
}
abstract protected function getTicketInfo($ticketId = NULL);
abstract protected function updateTicket($ticketId, $newStatus, $message, $resolution);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A Decorator that runs a test repeatedly.
*
* @package PHPUnit
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 boolean
*/
protected $processIsolation = FALSE;
/**
* @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 PHPUnit_Framework_Exception
*/
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 PHPUnit_Util_InvalidArgumentHelper::factory(
2, '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 PHPUnit_Framework_Exception
*/
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
if ($result === NULL) {
$result = $this->createResult();
}
//@codingStandardsIgnoreStart
for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) {
//@codingStandardsIgnoreEnd
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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.4
*/
if (stream_resolve_include_path('PEAR/RunTest.php')) {
$currentErrorReporting = error_reporting(E_ERROR | E_WARNING | E_PARSE);
require_once 'PEAR/RunTest.php';
error_reporting($currentErrorReporting);
}
/**
* Wrapper to run .phpt test cases.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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);
PHP_Timer::start();
$buffer = $runner->run($this->filename, $options);
$time = PHP_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 (is_object($buffer) && $buffer instanceof PEAR_Error) {
$result->addError(
$this,
new PHPUnit_Framework_Exception($buffer->getMessage()),
$time
);
}
else if ($buffer == 'SKIPPED') {
$result->addFailure($this, new PHPUnit_Framework_SkippedTestError, 0);
}
else if ($buffer != 'PASSED') {
$expContent = file_get_contents($expFile);
$outContent = file_get_contents($outFile);
$result->addFailure(
$this,
new PHPUnit_Framework_ComparisonFailure(
$expContent,
$outContent,
$expContent,
$outContent
),
$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->getCodeCoverage()->append($coverageData, $this);
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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.4
*/
/**
* Dummy logger for PEAR_RunTest.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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)
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Extensions
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* 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.
*
* @package PHPUnit
* @subpackage Extensions
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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
*/
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
if ($result === NULL) {
$result = $this->createResult();
}
$this->basicRun($result);
return $result;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.1.4
*/
/**
* Suite for .phpt test cases.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 PHPUnit_Framework_Exception
*/
public function __construct($directory, array $options = array())
{
if (is_string($directory) && is_dir($directory)) {
$this->setName($directory);
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray($directory, '.phpt');
foreach ($files as $file) {
$this->addTestFile($file, $options);
}
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'directory name');
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 3.0.0
*/
/**
* A TestRunner for the Command Line Interface (CLI)
* PHP SAPI Module.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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,
'useDefaultConfiguration' => TRUE
);
/**
* @var array
*/
protected $options = array();
/**
* @var array
*/
protected $longOptions = array(
'colors' => NULL,
'bootstrap=' => NULL,
'configuration=' => NULL,
'coverage-html=' => NULL,
'coverage-clover=' => NULL,
'coverage-php=' => NULL,
'coverage-text==' => NULL,
'debug' => NULL,
'exclude-group=' => NULL,
'filter=' => NULL,
'testsuite=' => NULL,
'group=' => NULL,
'help' => NULL,
'include-path=' => NULL,
'list-groups' => NULL,
'loader=' => NULL,
'log-json=' => NULL,
'log-junit=' => NULL,
'log-tap=' => NULL,
'process-isolation' => NULL,
'repeat=' => NULL,
'stderr' => NULL,
'stop-on-error' => NULL,
'stop-on-failure' => NULL,
'stop-on-incomplete' => NULL,
'stop-on-skipped' => NULL,
'strict' => NULL,
'tap' => NULL,
'testdox' => NULL,
'testdox-html=' => NULL,
'testdox-text=' => NULL,
'test-suffix=' => NULL,
'no-configuration' => NULL,
'no-globals-backup' => NULL,
'printer=' => NULL,
'static-backup' => NULL,
'verbose' => NULL,
'version' => NULL
);
/**
* @var array
*/
protected $missingExtensions = array();
/**
* @param boolean $exit
*/
public static function main($exit = TRUE)
{
$command = new PHPUnit_TextUI_Command;
return $command->run($_SERVER['argv'], $exit);
}
/**
* @param array $argv
* @param boolean $exit
*/
public function run(array $argv, $exit = TRUE)
{
$this->handleArguments($argv);
$runner = $this->createRunner();
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['testSuffixes']
);
}
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";
}
if ($exit) {
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
} else {
return 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";
}
$ret = PHPUnit_TextUI_TestRunner::FAILURE_EXIT;
if (isset($result) && $result->wasSuccessful()) {
$ret = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
}
else if (!isset($result) || $result->errorCount() > 0) {
$ret = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT;
}
if ($exit) {
exit($ret);
} else {
return $ret;
}
}
/**
* Create a TestRunner, override in subclasses.
*
* @return PHPUnit_TextUI_TestRunner
* @since Method available since Release 3.6.0
*/
protected function createRunner()
{
return new PHPUnit_TextUI_TestRunner($this->arguments['loader']);
}
/**
* 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
*
* <code>
* <?php
* class MyCommand extends PHPUnit_TextUI_Command
* {
* public function __construct()
* {
* $this->longOptions['--my-switch'] = 'myHandler';
* }
*
* // --my-switch foo -> myHandler('foo')
* protected function myHandler($value)
* {
* }
* }
* </code>
*
* @param array $argv
*/
protected function handleArguments(array $argv)
{
try {
$this->options = PHPUnit_Util_Getopt::getopt(
$argv,
'd:c:hv',
array_keys($this->longOptions)
);
}
catch (PHPUnit_Framework_Exception $e) {
PHPUnit_TextUI_TestRunner::showError($e->getMessage());
}
foreach ($this->options[0] as $option) {
switch ($option[0]) {
case '--colors': {
$this->arguments['colors'] = TRUE;
}
break;
case '--bootstrap': {
$this->arguments['bootstrap'] = $option[1];
}
break;
case 'c':
case '--configuration': {
$this->arguments['configuration'] = $option[1];
}
break;
case '--coverage-clover':
case '--coverage-html':
case '--coverage-php':
case '--coverage-text': {
if (!extension_loaded('tokenizer')) {
$this->showExtensionNotLoadedMessage(
'tokenizer', 'No code coverage will be generated.'
);
continue;
}
if (!extension_loaded('xdebug')) {
$this->showExtensionNotLoadedMessage(
'Xdebug', 'No code coverage will be generated.'
);
continue;
}
switch ($option[0]) {
case '--coverage-clover': {
$this->arguments['coverageClover'] = $option[1];
}
break;
case '--coverage-html': {
$this->arguments['reportDirectory'] = $option[1];
}
break;
case '--coverage-php': {
$this->arguments['coveragePHP'] = $option[1];
}
break;
case '--coverage-text': {
if ($option[1] === NULL) {
$option[1] = 'php://stdout';
}
$this->arguments['coverageText'] = $option[1];
$this->arguments['coverageTextShowUncoveredFiles'] = FALSE;
}
break;
}
}
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 'h':
case '--help': {
$this->showHelp();
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
}
break;
case '--filter': {
$this->arguments['filter'] = $option[1];
}
break;
case '--testsuite': {
$this->arguments['testsuite'] = $option[1];
}
break;
case '--group': {
$this->arguments['groups'] = explode(',', $option[1]);
}
break;
case '--exclude-group': {
$this->arguments['excludeGroups'] = explode(
',', $option[1]
);
}
break;
case '--test-suffix': {
$this->arguments['testSuffixes'] = explode(
',', $option[1]
);
}
break;
case '--include-path': {
$includePath = $option[1];
}
break;
case '--list-groups': {
$this->arguments['listGroups'] = TRUE;
}
break;
case '--printer': {
$this->arguments['printer'] = $option[1];
}
break;
case '--loader': {
$this->arguments['loader'] = $option[1];
}
break;
case '--log-json': {
$this->arguments['jsonLogfile'] = $option[1];
}
break;
case '--log-junit': {
$this->arguments['junitLogfile'] = $option[1];
}
break;
case '--log-tap': {
$this->arguments['tapLogfile'] = $option[1];
}
break;
case '--process-isolation': {
$this->arguments['processIsolation'] = TRUE;
}
break;
case '--repeat': {
$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-error': {
$this->arguments['stopOnError'] = TRUE;
}
break;
case '--stop-on-failure': {
$this->arguments['stopOnFailure'] = TRUE;
}
break;
case '--stop-on-incomplete': {
$this->arguments['stopOnIncomplete'] = TRUE;
}
break;
case '--stop-on-skipped': {
$this->arguments['stopOnSkipped'] = TRUE;
}
break;
case '--tap': {
$this->arguments['printer'] = new PHPUnit_Util_Log_TAP;
}
break;
case '--testdox': {
$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 'v':
case '--verbose': {
$this->arguments['verbose'] = TRUE;
}
break;
case '--version': {
PHPUnit_TextUI_TestRunner::printVersionString();
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
}
break;
case '--strict': {
$this->arguments['strict'] = 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]);
}
}
}
}
$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']) &&
substr($this->arguments['test'], -5, 5) != '.phpt') {
$this->arguments['testFile'] = realpath($this->arguments['test']);
$this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.'));
}
}
if (!isset($this->arguments['testSuffixes'])) {
$this->arguments['testSuffixes'] = array('Test.php', '.phpt');
}
if (isset($includePath)) {
ini_set(
'include_path',
$includePath . PATH_SEPARATOR . ini_get('include_path')
);
}
if (isset($this->arguments['bootstrap'])) {
$this->handleBootstrap($this->arguments['bootstrap']);
}
if (isset($this->arguments['printer']) &&
is_string($this->arguments['printer'])) {
$this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']);
}
if ($this->arguments['loader'] !== NULL) {
$this->arguments['loader'] = $this->handleLoader($this->arguments['loader']);
}
if (isset($this->arguments['configuration']) &&
is_dir($this->arguments['configuration'])) {
$configurationFile = $this->arguments['configuration'] .
'/phpunit.xml';
if (file_exists($configurationFile)) {
$this->arguments['configuration'] = realpath(
$configurationFile
);
}
else if (file_exists($configurationFile . '.dist')) {
$this->arguments['configuration'] = realpath(
$configurationFile . '.dist'
);
}
}
else 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'])) {
try {
$configuration = PHPUnit_Util_Configuration::getInstance(
$this->arguments['configuration']
);
}
catch (Exception $e) {
print $e->getMessage() . "\n";
exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
}
$phpunit = $configuration->getPHPUnitConfiguration();
$configuration->handlePHPConfiguration();
if (!isset($this->arguments['bootstrap']) && isset($phpunit['bootstrap'])) {
$this->handleBootstrap($phpunit['bootstrap']);
}
if (isset($phpunit['printerClass'])) {
if (isset($phpunit['printerFile'])) {
$file = $phpunit['printerFile'];
} else {
$file = '';
}
$this->arguments['printer'] = $this->handlePrinter(
$phpunit['printerClass'], $file
);
}
if (isset($phpunit['testSuiteLoaderClass'])) {
if (isset($phpunit['testSuiteLoaderFile'])) {
$file = $phpunit['testSuiteLoaderFile'];
} else {
$file = '';
}
$this->arguments['loader'] = $this->handleLoader(
$phpunit['testSuiteLoaderClass'], $file
);
}
$logging = $configuration->getLoggingConfiguration();
if (isset($logging['coverage-html']) || isset($logging['coverage-clover']) || isset($logging['coverage-text']) ) {
if (!extension_loaded('tokenizer')) {
$this->showExtensionNotLoadedMessage(
'tokenizer', 'No code coverage will be generated.'
);
}
else if (!extension_loaded('Xdebug')) {
$this->showExtensionNotLoadedMessage(
'Xdebug', 'No code coverage will be generated.'
);
}
}
$browsers = $configuration->getSeleniumBrowserConfiguration();
if (!empty($browsers) &&
class_exists('PHPUnit_Extensions_SeleniumTestCase')) {
PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers;
}
if (!isset($this->arguments['test'])) {
$testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null);
if ($testSuite !== NULL) {
$this->arguments['test'] = $testSuite;
}
}
}
if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') {
$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);
}
}
/**
* Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation.
*
* @param string $loaderClass
* @param string $loaderFile
* @return PHPUnit_Runner_TestSuiteLoader
*/
protected function handleLoader($loaderClass, $loaderFile = '')
{
if (!class_exists($loaderClass, FALSE)) {
if ($loaderFile == '') {
$loaderFile = PHPUnit_Util_Filesystem::classNameToFilename(
$loaderClass
);
}
$loaderFile = stream_resolve_include_path($loaderFile);
if ($loaderFile) {
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;
}
/**
* Handles the loading of the PHPUnit_Util_Printer implementation.
*
* @param string $printerClass
* @param string $printerFile
* @return PHPUnit_Util_Printer
*/
protected function handlePrinter($printerClass, $printerFile = '')
{
if (!class_exists($printerClass, FALSE)) {
if ($printerFile == '') {
$printerFile = PHPUnit_Util_Filesystem::classNameToFilename(
$printerClass
);
}
$printerFile = stream_resolve_include_path($printerFile);
if ($printerFile) {
require $printerFile;
}
}
if (class_exists($printerClass, FALSE)) {
$class = new ReflectionClass($printerClass);
if ($class->implementsInterface('PHPUnit_Framework_TestListener') &&
$class->isSubclassOf('PHPUnit_Util_Printer') &&
$class->isInstantiable()) {
$printer = $class->newInstance();
}
}
if (!isset($printer)) {
PHPUnit_TextUI_TestRunner::showError(
sprintf(
'Could not use "%s" as printer.',
$printerClass
)
);
}
return $printer;
}
/**
* Loads a bootstrap file.
*
* @param string $filename
*/
protected function handleBootstrap($filename)
{
try {
PHPUnit_Util_Fileloader::checkAndLoad($filename);
}
catch (PHPUnit_Framework_Exception $e) {
PHPUnit_TextUI_TestRunner::showError($e->getMessage());
}
}
/**
* @param string $message
* @since Method available since Release 3.6.0
*/
protected function showExtensionNotLoadedMessage($extension, $message = '')
{
if (isset($this->missingExtensions[$extension])) {
return;
}
if (!empty($message)) {
$message = ' ' . $message;
}
$this->showMessage(
'The ' . $extension . ' extension is not loaded.' . $message . "\n",
FALSE
);
$this->missingExtensions[$extension] = TRUE;
}
/**
* 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 <<<EOT
Usage: phpunit [switches] UnitTest [UnitTest.php]
phpunit [switches] <directory>
--log-junit <file> Log test execution in JUnit XML format to file.
--log-tap <file> Log test execution in TAP format to file.
--log-json <file> Log test execution in JSON format.
--coverage-clover <file> Generate code coverage report in Clover XML format.
--coverage-html <dir> Generate code coverage report in HTML format.
--coverage-php <file> Serialize PHP_CodeCoverage object to file.
--coverage-text=<file> Generate code coverage report in text format.
Default to writing to the standard output.
--testdox-html <file> Write agile documentation in HTML format to file.
--testdox-text <file> Write agile documentation in Text format to file.
--filter <pattern> Filter which tests to run.
--testsuite <pattern> Filter which testsuite 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.
--test-suffix ... Only search for test in files with specified
suffix(es). Default: Test.php,.phpt
--loader <loader> TestSuiteLoader implementation to use.
--printer <printer> TestSuiteListener implementation to use.
--repeat <times> Runs the test(s) repeatedly.
--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-error Stop execution upon first error.
--stop-on-failure Stop execution upon first error or failure.
--stop-on-skipped Stop execution upon first skipped test.
--stop-on-incomplete Stop execution upon first incomplete test.
--strict Run tests in strict mode.
-v|--verbose Output more verbose information.
--debug Display debugging information during test execution.
--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.
--bootstrap <file> A "bootstrap" PHP file that is run before the tests.
-c|--configuration <file> Read configuration from XML file.
--no-configuration Ignore default configuration file (phpunit.xml).
--include-path <path(s)> Prepend PHP's include_path with given path(s).
-d key[=value] Sets a php.ini value.
-h|--help Prints this usage information.
--version Prints the version and exits.
EOT;
}
/**
* Custom callback for test suite discovery.
*/
protected function handleCustomTestSuite()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* Prints the result of a TextUI TestRunner run.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 $maxColumn;
/**
* @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 PHPUnit_Framework_Exception
* @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();
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->deprecatedFeaturesCount() > 0) {
if ($result->failureCount() > 0) {
print "\n--\n\nDeprecated PHPUnit features are being used";
}
foreach ($result->deprecatedFeatures() as $deprecatedFeature) {
$this->write($deprecatedFeature . "\n\n");
}
}
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()
)
);
$e = $defect->thrownException()->getPrevious();
while ($e) {
$this->write(
"\nCaused by\n" .
PHPUnit_Framework_TestFailure::exceptionToString($e). "\n" .
PHPUnit_Util_Filter::getFilteredStacktrace($e)
);
$e = $e->getPrevious();
}
}
/**
* @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'
);
}
protected function printHeader()
{
$this->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n");
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printFooter(PHPUnit_Framework_TestResult $result)
{
if (count($result) === 0) {
if ($this->colors) {
$this->write("\x1b[30;43m\x1b[2K");
}
$this->write(
"No tests executed!\n"
);
if ($this->colors) {
$this->write("\x1b[0m\x1b[2K");
}
}
else if ($result->wasSuccessful() &&
$result->allCompletelyImplemented() &&
$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->allCompletelyImplemented() ||
!$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");
}
}
if (!$this->verbose &&
$result->deprecatedFeaturesCount() > 0) {
$message = sprintf(
"Warning: Deprecated PHPUnit features are being used %s times!\n" .
"Use --verbose for more information.\n",
$result->deprecatedFeaturesCount()
);
if ($this->colors) {
$message = "\x1b[37;41m\x1b[2K" . $message .
"\x1b[0m";
}
$this->write("\n" . $message);
}
}
/**
* @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<RETURN> 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)
{
if ($this->colors) {
$this->writeProgress("\x1b[31;1mE\x1b[0m");
} else {
$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)
{
if ($this->colors) {
$this->writeProgress("\x1b[41;37mF\x1b[0m");
} else {
$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)
{
if ($this->colors) {
$this->writeProgress("\x1b[33;1mI\x1b[0m");
} else {
$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)
{
if ($this->colors) {
$this->writeProgress("\x1b[36;1mS\x1b[0m");
} else {
$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);
$this->maxColumn = 69 - (2 * $this->numTestsWidth);
}
}
/**
* 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 ($this->debug) {
$this->write(
sprintf(
"\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test)
)
);
}
}
/**
* 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();
}
else if ($test instanceof PHPUnit_Extensions_PhptTestCase) {
$this->numAssertions++;
}
$this->lastTestFailed = FALSE;
if ($test instanceof PHPUnit_Framework_TestCase) {
if (!$test->hasPerformedExpectationsOnOutput()) {
$this->write($test->getActualOutput());
}
}
}
/**
* @param string $progress
*/
protected function writeProgress($progress)
{
$this->write($progress);
$this->column++;
$this->numTestsRun++;
if ($this->column == $this->maxColumn) {
$this->write(
sprintf(
' %' . $this->numTestsWidth . 'd / %' .
$this->numTestsWidth . 'd (%3s%%)',
$this->numTestsRun,
$this->numTests,
floor(($this->numTestsRun / $this->numTests) * 100)
)
);
$this->writeNewLine();
}
}
protected function writeNewLine()
{
$this->column = 0;
$this->write("\n");
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 2.0.0
*/
/**
* A TestRunner for the Command Line Interface (CLI)
* PHP SAPI Module.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @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 PHP_CodeCoverage_Filter
*/
protected $codeCoverageFilter;
/**
* @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
* @param PHP_CodeCoverage_Filter $filter
* @since Method available since Release 3.4.0
*/
public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = NULL, PHP_CodeCoverage_Filter $filter = NULL)
{
if ($filter === NULL) {
$filter = new PHP_CodeCoverage_Filter;
}
$this->codeCoverageFilter = $filter;
$this->loader = $loader;
}
/**
* @param mixed $test
* @param array $arguments
* @throws PHPUnit_Framework_Exception
*/
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 PHPUnit_Framework_Exception(
'No test case or test suite found.'
);
}
}
/**
* @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'])) {
$GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap'];
}
if ($arguments['backupGlobals'] === FALSE) {
$suite->setBackupGlobals(FALSE);
}
if ($arguments['backupStaticAttributes'] === TRUE) {
$suite->setBackupStaticAttributes(TRUE);
}
if (is_integer($arguments['repeat'])) {
$test = new PHPUnit_Extensions_RepeatedTest(
$suite,
$arguments['repeat'],
$arguments['filter'],
$arguments['groups'],
$arguments['excludeGroups'],
$arguments['processIsolation']
);
$suite = new PHPUnit_Framework_TestSuite();
$suite->addTest($test);
}
$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['stopOnError']) {
$result->stopOnError(TRUE);
}
if ($arguments['stopOnFailure']) {
$result->stopOnFailure(TRUE);
}
if ($arguments['stopOnIncomplete']) {
$result->stopOnIncomplete(TRUE);
}
if ($arguments['stopOnSkipped']) {
$result->stopOnSkipped(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"
);
if (isset($arguments['configuration'])) {
$this->printer->write(
sprintf(
"Configuration read from %s\n\n",
$arguments['configuration']->getFilename()
)
);
}
}
foreach ($arguments['listeners'] as $listener) {
$result->addListener($listener);
}
$result->addListener($this->printer);
if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) {
$result->addListener(new PHPUnit_Util_DeprecatedFeature_Logger);
}
if (isset($arguments['testdoxHTMLFile'])) {
$result->addListener(
new PHPUnit_Util_TestDox_ResultPrinter_HTML(
$arguments['testdoxHTMLFile']
)
);
}
if (isset($arguments['testdoxTextFile'])) {
$result->addListener(
new PHPUnit_Util_TestDox_ResultPrinter_Text(
$arguments['testdoxTextFile']
)
);
}
$codeCoverageReports = 0;
if (extension_loaded('xdebug')) {
if (isset($arguments['coverageClover'])) {
$codeCoverageReports++;
}
if (isset($arguments['reportDirectory'])) {
$codeCoverageReports++;
}
if (isset($arguments['coveragePHP'])) {
$codeCoverageReports++;
}
if (isset($arguments['coverageText'])) {
$codeCoverageReports++;
}
}
if ($codeCoverageReports > 0) {
$codeCoverage = new PHP_CodeCoverage(
NULL, $this->codeCoverageFilter
);
$codeCoverage->setAddUncoveredFilesFromWhitelist(
$arguments['addUncoveredFilesFromWhitelist']
);
$codeCoverage->setProcessUncoveredFilesFromWhitelist(
$arguments['processUncoveredFilesFromWhitelist']
);
if (isset($arguments['forceCoversAnnotation'])) {
$codeCoverage->setForceCoversAnnotation(
$arguments['forceCoversAnnotation']
);
}
if (isset($arguments['mapTestClassNameToCoveredClassName'])) {
$codeCoverage->setMapTestClassNameToCoveredClassName(
$arguments['mapTestClassNameToCoveredClassName']
);
}
$result->setCodeCoverage($codeCoverage);
}
if ($codeCoverageReports > 1) {
if (isset($arguments['cacheTokens'])) {
$codeCoverage->setCacheTokens($arguments['cacheTokens']);
}
}
if (isset($arguments['jsonLogfile'])) {
$result->addListener(
new PHPUnit_Util_Log_JSON($arguments['jsonLogfile'])
);
}
if (isset($arguments['tapLogfile'])) {
$result->addListener(
new PHPUnit_Util_Log_TAP($arguments['tapLogfile'])
);
}
if (isset($arguments['junitLogfile'])) {
$result->addListener(
new PHPUnit_Util_Log_JUnit(
$arguments['junitLogfile'], $arguments['logIncompleteSkipped']
)
);
}
if ($arguments['strict']) {
$result->strictMode(TRUE);
$result->setTimeoutForSmallTests(
$arguments['timeoutForSmallTests']
);
$result->setTimeoutForMediumTests(
$arguments['timeoutForMediumTests']
);
$result->setTimeoutForLargeTests(
$arguments['timeoutForLargeTests']
);
}
$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 (isset($codeCoverage)) {
if (isset($arguments['coverageClover'])) {
$this->printer->write(
"\nGenerating code coverage report in Clover XML format ..."
);
$writer = new PHP_CodeCoverage_Report_Clover;
$writer->process($codeCoverage, $arguments['coverageClover']);
$this->printer->write(" done\n");
unset($writer);
}
if (isset($arguments['reportDirectory'])) {
$this->printer->write(
"\nGenerating code coverage report in HTML format ..."
);
$writer = new PHP_CodeCoverage_Report_HTML(
$arguments['reportCharset'],
$arguments['reportHighlight'],
$arguments['reportLowUpperBound'],
$arguments['reportHighLowerBound'],
sprintf(
' and <a href="http://phpunit.de/">PHPUnit %s</a>',
PHPUnit_Runner_Version::id()
)
);
$writer->process($codeCoverage, $arguments['reportDirectory']);
$this->printer->write(" done\n");
unset($writer);
}
if (isset($arguments['coveragePHP'])) {
$this->printer->write(
"\nGenerating code coverage report in PHP format ..."
);
$writer = new PHP_CodeCoverage_Report_PHP;
$writer->process($codeCoverage, $arguments['coveragePHP']);
$this->printer->write(" done\n");
unset($writer);
}
if (isset($arguments['coverageText'])) {
if ($arguments['coverageText'] == 'php://stdout') {
$outputStream = $this->printer;
$colors = (bool)$arguments['colors'];
} else {
$outputStream = new PHPUnit_Util_Printer($arguments['coverageText']);
$colors = FALSE;
}
$writer = new PHP_CodeCoverage_Report_Text(
$outputStream,
$arguments['reportLowUpperBound'],
$arguments['reportHighLowerBound'],
$arguments['coverageTextShowUncoveredFiles']
);
$writer->process($codeCoverage, $colors);
}
}
return $result;
}
/**
* @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 . PHP_EOL);
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['debug'] = isset($arguments['debug']) ? $arguments['debug'] : FALSE;
$arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : FALSE;
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
if (isset($arguments['configuration'])) {
$arguments['configuration']->handlePHPConfiguration();
$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['cacheTokens']) &&
!isset($arguments['cacheTokens'])) {
$arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens'];
}
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'];
}
if (isset($phpunitConfiguration['timeoutForSmallTests']) &&
!isset($arguments['timeoutForSmallTests'])) {
$arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests'];
}
if (isset($phpunitConfiguration['timeoutForMediumTests']) &&
!isset($arguments['timeoutForMediumTests'])) {
$arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests'];
}
if (isset($phpunitConfiguration['timeoutForLargeTests']) &&
!isset($arguments['timeoutForLargeTests'])) {
$arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests'];
}
if (isset($phpunitConfiguration['strict']) &&
!isset($arguments['strict'])) {
$arguments['strict'] = $phpunitConfiguration['strict'];
}
if (isset($phpunitConfiguration['verbose']) &&
!isset($arguments['verbose'])) {
$arguments['verbose'] = $phpunitConfiguration['verbose'];
}
if (isset($phpunitConfiguration['forceCoversAnnotation']) &&
!isset($arguments['forceCoversAnnotation'])) {
$arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation'];
}
if (isset($phpunitConfiguration['mapTestClassNameToCoveredClassName']) &&
!isset($arguments['mapTestClassNameToCoveredClassName'])) {
$arguments['mapTestClassNameToCoveredClassName'] = $phpunitConfiguration['mapTestClassNameToCoveredClassName'];
}
$groupCliArgs = array();
if (!empty($arguments['groups'])) {
$groupCliArgs = $arguments['groups'];
}
$groupConfiguration = $arguments['configuration']->getGroupConfiguration();
if (!empty($groupConfiguration['include']) &&
!isset($arguments['groups'])) {
$arguments['groups'] = $groupConfiguration['include'];
}
if (!empty($groupConfiguration['exclude']) &&
!isset($arguments['excludeGroups'])) {
$arguments['excludeGroups'] = array_diff($groupConfiguration['exclude'], $groupCliArgs);
}
foreach ($arguments['configuration']->getListenerConfiguration() as $listener) {
if (!class_exists($listener['class'], FALSE) &&
$listener['file'] !== '') {
require_once $listener['file'];
}
if (class_exists($listener['class'])) {
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['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-php']) &&
!isset($arguments['coveragePHP'])) {
$arguments['coveragePHP'] = $loggingConfiguration['coverage-php'];
}
if (isset($loggingConfiguration['coverage-text']) &&
!isset($arguments['coverageText'])) {
$arguments['coverageText'] = $loggingConfiguration['coverage-text'];
if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) {
$arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles'];
} else {
$arguments['coverageTextShowUncoveredFiles'] = FALSE;
}
}
if (isset($loggingConfiguration['json']) &&
!isset($arguments['jsonLogfile'])) {
$arguments['jsonLogfile'] = $loggingConfiguration['json'];
}
if (isset($loggingConfiguration['plain'])) {
$arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter(
$loggingConfiguration['plain'], TRUE
);
}
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['testdox-html']) &&
!isset($arguments['testdoxHTMLFile'])) {
$arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html'];
}
if (isset($loggingConfiguration['testdox-text']) &&
!isset($arguments['testdoxTextFile'])) {
$arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text'];
}
if ((isset($arguments['coverageClover']) ||
isset($arguments['reportDirectory']) ||
isset($arguments['coveragePHP']) ||
isset($arguments['coverageText'])) &&
extension_loaded('xdebug')) {
$filterConfiguration = $arguments['configuration']->getFilterConfiguration();
$arguments['addUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist'];
$arguments['processUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist'];
foreach ($filterConfiguration['blacklist']['include']['directory'] as $dir) {
$this->codeCoverageFilter->addDirectoryToBlacklist(
$dir['path'], $dir['suffix'], $dir['prefix'], $dir['group']
);
}
foreach ($filterConfiguration['blacklist']['include']['file'] as $file) {
$this->codeCoverageFilter->addFileToBlacklist($file);
}
foreach ($filterConfiguration['blacklist']['exclude']['directory'] as $dir) {
$this->codeCoverageFilter->removeDirectoryFromBlacklist(
$dir['path'], $dir['suffix'], $dir['prefix'], $dir['group']
);
}
foreach ($filterConfiguration['blacklist']['exclude']['file'] as $file) {
$this->codeCoverageFilter->removeFileFromBlacklist($file);
}
foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) {
$this->codeCoverageFilter->addDirectoryToWhitelist(
$dir['path'], $dir['suffix'], $dir['prefix']
);
}
foreach ($filterConfiguration['whitelist']['include']['file'] as $file) {
$this->codeCoverageFilter->addFileToWhitelist($file);
}
foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) {
$this->codeCoverageFilter->removeDirectoryFromWhitelist(
$dir['path'], $dir['suffix'], $dir['prefix']
);
}
foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) {
$this->codeCoverageFilter->removeFileFromWhitelist($file);
}
}
}
$arguments['addUncoveredFilesFromWhitelist'] = isset($arguments['addUncoveredFilesFromWhitelist']) ? $arguments['addUncoveredFilesFromWhitelist'] : TRUE;
$arguments['processUncoveredFilesFromWhitelist'] = isset($arguments['processUncoveredFilesFromWhitelist']) ? $arguments['processUncoveredFilesFromWhitelist'] : FALSE;
$arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : NULL;
$arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : NULL;
$arguments['cacheTokens'] = isset($arguments['cacheTokens']) ? $arguments['cacheTokens'] : FALSE;
$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['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : FALSE;
$arguments['reportCharset'] = isset($arguments['reportCharset']) ? $arguments['reportCharset'] : 'UTF-8';
$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['stopOnError'] = isset($arguments['stopOnError']) ? $arguments['stopOnError'] : FALSE;
$arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : FALSE;
$arguments['stopOnIncomplete'] = isset($arguments['stopOnIncomplete']) ? $arguments['stopOnIncomplete'] : FALSE;
$arguments['stopOnSkipped'] = isset($arguments['stopOnSkipped']) ? $arguments['stopOnSkipped'] : FALSE;
$arguments['timeoutForSmallTests'] = isset($arguments['timeoutForSmallTests']) ? $arguments['timeoutForSmallTests'] : 1;
$arguments['timeoutForMediumTests'] = isset($arguments['timeoutForMediumTests']) ? $arguments['timeoutForMediumTests'] : 10;
$arguments['timeoutForLargeTests'] = isset($arguments['timeoutForLargeTests']) ? $arguments['timeoutForLargeTests'] : 60;
$arguments['strict'] = isset($arguments['strict']) ? $arguments['strict'] : FALSE;
$arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : FALSE;
if ($arguments['filter'] !== FALSE &&
preg_match('/^[a-zA-Z0-9_]/', $arguments['filter'])) {
// Escape delimiters in regular expression. Do NOT use preg_quote,
// to keep magic characters.
$arguments['filter'] = '/' . str_replace(
'/', '\\/', $arguments['filter']
) . '/';
}
}
}
<?php
/**
* PHP_Invoker
*
* Copyright (c) 2011-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHP
* @subpackage Invoker
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2011-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-invoker
* @since File available since Release 1.0.0
*/
/**
* @package PHP
* @subpackage Invoker
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2011-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.1.2
* @link http://github.com/sebastianbergmann/php-invoker
* @since Class available since Release 1.0.0
*/
class PHP_Invoker_TimeoutException extends RuntimeException
{
}
<?php
declare(ticks = 1);
/**
* PHP_Invoker
*
* Copyright (c) 2011-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHP
* @subpackage Invoker
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2011-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-invoker
* @since File available since Release 1.0.0
*/
/**
* Utility class for invoking callables with a timeout.
*
* @package PHP
* @subpackage Invoker
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2011-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.1.2
* @link http://github.com/sebastianbergmann/php-invoker
* @since Class available since Release 1.0.0
*/
class PHP_Invoker
{
/**
* @var integer
*/
protected $timeout;
/**
* Invokes a callable and raises an exception when the execution does not
* finish before the specified timeout.
*
* @param callable $callable
* @param array $arguments
* @param integer $timeout in seconds
* @return mixed
* @throws InvalidArgumentException
*/
public function invoke($callable, array $arguments, $timeout)
{
if (!is_callable($callable)) {
throw new InvalidArgumentException;
}
if (!is_integer($timeout)) {
throw new InvalidArgumentException;
}
pcntl_signal(SIGALRM, array($this, 'callback'), TRUE);
pcntl_alarm($timeout);
$this->timeout = $timeout;
try {
$result = call_user_func_array($callable, $arguments);
}
catch (Exception $e) {
pcntl_alarm(0);
throw $e;
}
pcntl_alarm(0);
return $result;
}
/**
* Invoked by pcntl_signal() when a SIGALRM occurs.
*/
public function callback()
{
throw new PHP_Invoker_TimeoutException(
sprintf(
'Execution aborted after %s',
PHP_Timer::secondsToTimeString($this->timeout)
)
);
}
}
PHP_Invoker
Copyright (c) 2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
PHP_Invoker 1.1
===============
This is the list of changes for the PHP_Invoker 1.1 release series.
PHP_Invoker 1.1.2
-----------------
* No changes.
PHP_Invoker 1.1.1
-----------------
* No changes.
PHP_Invoker 1.1.0
-----------------
* `PHP_Invoker_TimeoutException` now holds information on the timeout.
PHP_Invoker
===========
Utility class for invoking callables with a timeout.
Installation
------------
PHP_Invoker should be installed using the [PEAR Installer](http://pear.php.net/). This installer is the backbone of PEAR, which provides a distribution system for PHP packages, and is shipped with every release of PHP since version 4.3.0.
The PEAR channel (`pear.phpunit.de`) that is used to distribute PHP_Invoker needs to be registered with the local PEAR environment:
sb@ubuntu ~ % pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded
This has to be done only once. Now the PEAR Installer can be used to install packages from the PHPUnit channel:
sb@vmware ~ % pear install phpunit/PHP_Invoker
downloading PHP_Invoker-1.0.0.tgz ...
Starting to download PHP_Invoker-1.0.0.tgz (2,536 bytes)
....done: 2,536 bytes
install ok: channel://pear.phpunit.de/PHP_Invoker-1.0.0
After the installation you can find the PHP_Invoker source files inside your local PEAR directory; the path is usually `/usr/lib/php/PHP`.
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
// @codeCoverageIgnoreStart
// @codingStandardsIgnoreStart
/**
* @SuppressWarnings(PHPMD)
*/
if (!function_exists('trait_exists')) {
function trait_exists($name)
{
return FALSE;
}
}
// @codingStandardsIgnoreEnd
// @codeCoverageIgnoreEnd
/**
* Provides collection functionality for PHP code coverage information.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
*/
class PHP_CodeCoverage
{
/**
* @var PHP_CodeCoverage_Driver
*/
protected $driver;
/**
* @var PHP_CodeCoverage_Filter
*/
protected $filter;
/**
* @var boolean
*/
protected $cacheTokens = FALSE;
/**
* @var boolean
*/
protected $forceCoversAnnotation = FALSE;
/**
* @var boolean
*/
protected $mapTestClassNameToCoveredClassName = FALSE;
/**
* @var boolean
*/
protected $addUncoveredFilesFromWhitelist = TRUE;
/**
* @var boolean
*/
protected $processUncoveredFilesFromWhitelist = FALSE;
/**
* @var mixed
*/
protected $currentId;
/**
* Code coverage data.
*
* @var array
*/
protected $data = array();
/**
* Test data.
*
* @var array
*/
protected $tests = array();
/**
* Constructor.
*
* @param PHP_CodeCoverage_Driver $driver
* @param PHP_CodeCoverage_Filter $filter
*/
public function __construct(PHP_CodeCoverage_Driver $driver = NULL, PHP_CodeCoverage_Filter $filter = NULL)
{
if ($driver === NULL) {
$driver = new PHP_CodeCoverage_Driver_Xdebug;
}
if ($filter === NULL) {
$filter = new PHP_CodeCoverage_Filter;
}
$this->driver = $driver;
$this->filter = $filter;
}
/**
* Returns the PHP_CodeCoverage_Report_Node_* object graph
* for this PHP_CodeCoverage object.
*
* @return PHP_CodeCoverage_Report_Node_Directory
* @since Method available since Release 1.1.0
*/
public function getReport()
{
$factory = new PHP_CodeCoverage_Report_Factory;
return $factory->create($this);
}
/**
* Clears collected code coverage data.
*/
public function clear()
{
$this->currentId = NULL;
$this->data = array();
$this->tests = array();
}
/**
* Returns the PHP_CodeCoverage_Filter used.
*
* @return PHP_CodeCoverage_Filter
*/
public function filter()
{
return $this->filter;
}
/**
* Returns the collected code coverage data.
*
* @return array
* @since Method available since Release 1.1.0
*/
public function getData()
{
if ($this->addUncoveredFilesFromWhitelist) {
$this->addUncoveredFilesFromWhitelist();
}
// We need to apply the blacklist filter a second time
// when no whitelist is used.
if (!$this->filter->hasWhitelist()) {
$this->applyListsFilter($this->data);
}
return $this->data;
}
/**
* Returns the test data.
*
* @return array
* @since Method available since Release 1.1.0
*/
public function getTests()
{
return $this->tests;
}
/**
* Start collection of code coverage information.
*
* @param mixed $id
* @param boolean $clear
* @throws PHP_CodeCoverage_Exception
*/
public function start($id, $clear = FALSE)
{
if (!is_bool($clear)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
if ($clear) {
$this->clear();
}
$this->currentId = $id;
$this->driver->start();
}
/**
* Stop collection of code coverage information.
*
* @param boolean $append
* @return array
* @throws PHP_CodeCoverage_Exception
*/
public function stop($append = TRUE)
{
if (!is_bool($append)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
$data = $this->driver->stop();
$this->append($data, NULL, $append);
$this->currentId = NULL;
return $data;
}
/**
* Appends code coverage data.
*
* @param array $data
* @param mixed $id
* @param boolean $append
*/
public function append(array $data, $id = NULL, $append = TRUE)
{
if ($id === NULL) {
$id = $this->currentId;
}
if ($id === NULL) {
throw new PHP_CodeCoverage_Exception;
}
$this->applyListsFilter($data);
$this->initializeFilesThatAreSeenTheFirstTime($data);
if (!$append) {
return;
}
if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
$this->applyCoversAnnotationFilter($data, $id);
}
if (empty($data)) {
return;
}
$status = NULL;
if ($id instanceof PHPUnit_Framework_TestCase) {
$status = $id->getStatus();
$id = get_class($id) . '::' . $id->getName();
}
else if ($id instanceof PHPUnit_Extensions_PhptTestCase) {
$id = $id->getName();
}
$this->tests[$id] = $status;
foreach ($data as $file => $lines) {
if (!$this->filter->isFile($file)) {
continue;
}
foreach ($lines as $k => $v) {
if ($v == 1) {
$this->data[$file][$k][] = $id;
}
}
}
}
/**
* Merges the data from another instance of PHP_CodeCoverage.
*
* @param PHP_CodeCoverage $that
*/
public function merge(PHP_CodeCoverage $that)
{
foreach ($that->data as $file => $lines) {
if (!isset($this->data[$file])) {
if (!$this->filter->isFiltered($file)) {
$this->data[$file] = $lines;
}
continue;
}
foreach ($lines as $line => $data) {
if ($data !== NULL) {
if (!isset($this->data[$file][$line])) {
$this->data[$file][$line] = $data;
} else {
$this->data[$file][$line] = array_unique(
array_merge($this->data[$file][$line], $data)
);
}
}
}
}
$this->tests = array_merge($this->tests, $that->getTests());
}
/**
* @param boolean $flag
* @throws PHP_CodeCoverage_Exception
* @since Method available since Release 1.1.0
*/
public function setCacheTokens($flag)
{
if (!is_bool($flag)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
$this->cacheTokens = $flag;
}
/**
* @param boolean $flag
* @since Method available since Release 1.1.0
*/
public function getCacheTokens()
{
return $this->cacheTokens;
}
/**
* @param boolean $flag
* @throws PHP_CodeCoverage_Exception
*/
public function setForceCoversAnnotation($flag)
{
if (!is_bool($flag)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
$this->forceCoversAnnotation = $flag;
}
/**
* @param boolean $flag
* @throws PHP_CodeCoverage_Exception
*/
public function setMapTestClassNameToCoveredClassName($flag)
{
if (!is_bool($flag)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
$this->mapTestClassNameToCoveredClassName = $flag;
}
/**
* @param boolean $flag
* @throws PHP_CodeCoverage_Exception
*/
public function setAddUncoveredFilesFromWhitelist($flag)
{
if (!is_bool($flag)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
$this->addUncoveredFilesFromWhitelist = $flag;
}
/**
* @param boolean $flag
* @throws PHP_CodeCoverage_Exception
*/
public function setProcessUncoveredFilesFromWhitelist($flag)
{
if (!is_bool($flag)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
$this->processUncoveredFilesFromWhitelist = $flag;
}
/**
* Applies the @covers annotation filtering.
*
* @param array $data
* @param mixed $id
*/
protected function applyCoversAnnotationFilter(&$data, $id)
{
if ($id instanceof PHPUnit_Framework_TestCase) {
$testClassName = get_class($id);
$linesToBeCovered = $this->getLinesToBeCovered(
$testClassName, $id->getName()
);
if ($linesToBeCovered === FALSE) {
$data = array();
return;
}
if ($this->mapTestClassNameToCoveredClassName &&
empty($linesToBeCovered)) {
$testedClass = substr($testClassName, 0, -4);
if (class_exists($testedClass)) {
$class = new ReflectionClass($testedClass);
$linesToBeCovered = array(
$class->getFileName() => range(
$class->getStartLine(), $class->getEndLine()
)
);
}
}
} else {
$linesToBeCovered = array();
}
if (!empty($linesToBeCovered)) {
$data = array_intersect_key($data, $linesToBeCovered);
foreach (array_keys($data) as $filename) {
$data[$filename] = array_intersect_key(
$data[$filename], array_flip($linesToBeCovered[$filename])
);
}
}
else if ($this->forceCoversAnnotation) {
$data = array();
}
}
/**
* Applies the blacklist/whitelist filtering.
*
* @param array $data
*/
protected function applyListsFilter(&$data)
{
foreach (array_keys($data) as $filename) {
if ($this->filter->isFiltered($filename)) {
unset($data[$filename]);
}
}
}
/**
* @since Method available since Release 1.1.0
*/
protected function initializeFilesThatAreSeenTheFirstTime($data)
{
foreach ($data as $file => $lines) {
if ($this->filter->isFile($file) && !isset($this->data[$file])) {
$this->data[$file] = array();
foreach ($lines as $k => $v) {
$this->data[$file][$k] = $v == -2 ? NULL : array();
}
}
}
}
/**
* Processes whitelisted files that are not covered.
*/
protected function addUncoveredFilesFromWhitelist()
{
$data = array();
$uncoveredFiles = array_diff(
$this->filter->getWhitelist(), array_keys($this->data)
);
foreach ($uncoveredFiles as $uncoveredFile) {
if (!file_exists($uncoveredFile)) {
continue;
}
if ($this->processUncoveredFilesFromWhitelist) {
$this->processUncoveredFileFromWhitelist(
$uncoveredFile, $data, $uncoveredFiles
);
} else {
$data[$uncoveredFile] = array();
$lines = count(file($uncoveredFile));
for ($i = 1; $i <= $lines; $i++) {
$data[$uncoveredFile][$i] = -1;
}
}
}
$this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
}
/**
* @param string $uncoveredFile
* @param array $data
* @param array $uncoveredFiles
*/
protected function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles)
{
$this->driver->start();
include_once $uncoveredFile;
$coverage = $this->driver->stop();
foreach ($coverage as $file => $fileCoverage) {
if (!isset($data[$file]) &&
in_array($file, $uncoveredFiles)) {
foreach (array_keys($fileCoverage) as $key) {
if ($fileCoverage[$key] == 1) {
$fileCoverage[$key] = -1;
}
}
$data[$file] = $fileCoverage;
}
}
}
/**
* Returns the files and lines a test method wants to cover.
*
* @param string $className
* @param string $methodName
* @return array
* @since Method available since Release 1.2.0
*/
protected function getLinesToBeCovered($className, $methodName)
{
$codeToCoverList = array();
$result = array();
// @codeCoverageIgnoreStart
if (($pos = strpos($methodName, ' ')) !== FALSE) {
$methodName = substr($methodName, 0, $pos);
}
// @codeCoverageIgnoreEnd
$class = new ReflectionClass($className);
try {
$method = new ReflectionMethod($className, $methodName);
}
catch (ReflectionException $e) {
return array();
}
$docComment = substr($class->getDocComment(), 3, -2) . PHP_EOL . substr($method->getDocComment(), 3, -2);
$templateMethods = array(
'setUp', 'assertPreConditions', 'assertPostConditions', 'tearDown'
);
foreach ($templateMethods as $templateMethod) {
if ($class->hasMethod($templateMethod)) {
$reflector = $class->getMethod($templateMethod);
$docComment .= PHP_EOL . substr($reflector->getDocComment(), 3, -2);
unset($reflector);
}
}
if (strpos($docComment, '@coversNothing') !== FALSE) {
return FALSE;
}
$classShortcut = preg_match_all(
'(@coversDefaultClass\s+(?P<coveredClass>[^\s]++)\s*$)m',
$class->getDocComment(),
$matches
);
if ($classShortcut) {
if ($classShortcut > 1) {
throw new PHP_CodeCoverage_Exception(
sprintf(
'More than one @coversClass annotation in class or interface "%s".',
$className
)
);
}
$classShortcut = $matches['coveredClass'][0];
}
$match = preg_match_all(
'(@covers\s+(?P<coveredElement>[^\s()]++)[\s()]*$)m',
$docComment,
$matches
);
if ($match) {
foreach ($matches['coveredElement'] as $coveredElement) {
if ($classShortcut && strncmp($coveredElement, '::', 2) === 0) {
$coveredElement = $classShortcut . $coveredElement;
}
$codeToCoverList = array_merge(
$codeToCoverList,
$this->resolveCoversToReflectionObjects($coveredElement)
);
}
foreach ($codeToCoverList as $codeToCover) {
$fileName = $codeToCover->getFileName();
if (!isset($result[$fileName])) {
$result[$fileName] = array();
}
$result[$fileName] = array_unique(
array_merge(
$result[$fileName],
range(
$codeToCover->getStartLine(), $codeToCover->getEndLine()
)
)
);
}
}
return $result;
}
/**
* @param string $coveredElement
* @return array
* @since Method available since Release 1.2.0
*/
protected function resolveCoversToReflectionObjects($coveredElement)
{
$codeToCoverList = array();
if (strpos($coveredElement, '::') !== FALSE) {
list($className, $methodName) = explode('::', $coveredElement);
if (isset($methodName[0]) && $methodName[0] == '<') {
$classes = array($className);
foreach ($classes as $className) {
if (!class_exists($className) &&
!interface_exists($className)) {
throw new PHP_CodeCoverage_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 ($className == '' && function_exists($methodName)) {
$codeToCoverList[] = new ReflectionFunction(
$methodName
);
} else {
if (!((class_exists($className) ||
interface_exists($className) ||
trait_exists($className)) &&
method_exists($className, $methodName))) {
throw new PHP_CodeCoverage_Exception(
sprintf(
'Trying to @cover not existing method "%s::%s".',
$className,
$methodName
)
);
}
$codeToCoverList[] = new ReflectionMethod(
$className, $methodName
);
}
}
}
} else {
$extended = FALSE;
if (strpos($coveredElement, '<extended>') !== FALSE) {
$coveredElement = str_replace(
'<extended>', '', $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) &&
!trait_exists($className)) {
throw new PHP_CodeCoverage_Exception(
sprintf(
'Trying to @cover not existing class or ' .
'interface "%s".',
$className
)
);
}
$codeToCoverList[] = new ReflectionClass($className);
}
}
return $codeToCoverList;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.2.0
*/
/**
* Factory for PHP_CodeCoverage_Exception objects that are used to describe
* invalid arguments passed to a function or method.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.2.0
*/
class PHP_CodeCoverage_Util_InvalidArgumentHelper
{
/**
* @param integer $argument
* @param string $type
* @param mixed $value
*/
public static function factory($argument, $type, $value = NULL)
{
$stack = debug_backtrace(FALSE);
return new PHP_CodeCoverage_Exception(
sprintf(
'Argument #%d%sof %s::%s() must be a %s',
$argument,
$value !== NULL ? ' (' . $value . ')' : ' ',
$stack[1]['class'],
$stack[1]['function'],
$type
)
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
/**
* Driver for Xdebug's code coverage functionality.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
* @codeCoverageIgnore
*/
class PHP_CodeCoverage_Driver_Xdebug implements PHP_CodeCoverage_Driver
{
/**
* Constructor.
*/
public function __construct()
{
if (!extension_loaded('xdebug')) {
throw new PHP_CodeCoverage_Exception('Xdebug is not loaded.');
}
if (version_compare(phpversion('xdebug'), '2.2.0-dev', '>=') &&
!ini_get('xdebug.coverage_enable')) {
throw new PHP_CodeCoverage_Exception(
'You need to set xdebug.coverage_enable=On in your php.ini.'
);
}
}
/**
* Start collection of code coverage information.
*/
public function start()
{
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
}
/**
* Stop collection of code coverage information.
*
* @return array
*/
public function stop()
{
$codeCoverage = xdebug_get_code_coverage();
xdebug_stop_code_coverage();
return $codeCoverage;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
/**
* Utility methods.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
*/
class PHP_CodeCoverage_Util
{
/**
* @var array
*/
protected static $ignoredLines = array();
/**
* @var array
*/
protected static $ids = array();
/**
* Returns the lines of a source file that should be ignored.
*
* @param string $filename
* @param boolean $cacheTokens
* @return array
* @throws PHP_CodeCoverage_Exception
*/
public static function getLinesToBeIgnored($filename, $cacheTokens = TRUE)
{
if (!is_string($filename)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'string'
);
}
if (!is_bool($cacheTokens)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
2, 'boolean'
);
}
if (!isset(self::$ignoredLines[$filename])) {
self::$ignoredLines[$filename] = array();
$ignore = FALSE;
$stop = FALSE;
$lines = file($filename);
foreach ($lines as $index => $line) {
if (!trim($line)) {
self::$ignoredLines[$filename][$index+1] = TRUE;
}
}
if ($cacheTokens) {
$tokens = PHP_Token_Stream_CachingFactory::get($filename);
} else {
$tokens = new PHP_Token_Stream($filename);
}
$classes = array_merge($tokens->getClasses(), $tokens->getTraits());
$tokens = $tokens->tokens();
foreach ($tokens as $token) {
switch (get_class($token)) {
case 'PHP_Token_COMMENT':
case 'PHP_Token_DOC_COMMENT': {
$_token = trim($token);
$_line = trim($lines[$token->getLine() - 1]);
if ($_token == '// @codeCoverageIgnore' ||
$_token == '//@codeCoverageIgnore') {
$ignore = TRUE;
$stop = TRUE;
}
else if ($_token == '// @codeCoverageIgnoreStart' ||
$_token == '//@codeCoverageIgnoreStart') {
$ignore = TRUE;
}
else if ($_token == '// @codeCoverageIgnoreEnd' ||
$_token == '//@codeCoverageIgnoreEnd') {
$stop = TRUE;
}
// be sure the comment doesn't have some token BEFORE it on the same line...
// it would not be safe to ignore the whole line in those cases.
if (0 === strpos($_token, $_line)) {
$count = substr_count($token, "\n");
$line = $token->getLine();
for ($i = $line; $i < $line + $count; $i++) {
self::$ignoredLines[$filename][$i] = TRUE;
}
if ($token instanceof PHP_Token_DOC_COMMENT) {
// Workaround for the fact the DOC_COMMENT token
// does not include the final \n character in its
// text.
if (substr(trim($lines[$i-1]), -2) == '*/') {
self::$ignoredLines[$filename][$i] = TRUE;
}
}
}
}
break;
case 'PHP_Token_INTERFACE':
case 'PHP_Token_TRAIT':
case 'PHP_Token_CLASS':
case 'PHP_Token_FUNCTION': {
$docblock = $token->getDocblock();
if (strpos($docblock, '@codeCoverageIgnore')) {
$endLine = $token->getEndLine();
for ($i = $token->getLine(); $i <= $endLine; $i++) {
self::$ignoredLines[$filename][$i] = TRUE;
}
}
else if ($token instanceof PHP_Token_INTERFACE ||
$token instanceof PHP_Token_TRAIT ||
$token instanceof PHP_Token_CLASS) {
if (empty($classes[$token->getName()]['methods'])) {
for ($i = $token->getLine();
$i <= $token->getEndLine();
$i++) {
self::$ignoredLines[$filename][$i] = TRUE;
}
} else {
$firstMethod = array_shift(
$classes[$token->getName()]['methods']
);
do {
$lastMethod = array_pop(
$classes[$token->getName()]['methods']
);
} while ($lastMethod !== NULL && substr($lastMethod['signature'], 0, 18) == 'anonymous function');
if ($lastMethod === NULL) {
$lastMethod = $firstMethod;
}
for ($i = $token->getLine();
$i < $firstMethod['startLine'];
$i++) {
self::$ignoredLines[$filename][$i] = TRUE;
}
for ($i = $token->getEndLine();
$i > $lastMethod['endLine'];
$i--) {
self::$ignoredLines[$filename][$i] = TRUE;
}
}
}
}
break;
case 'PHP_Token_NAMESPACE': {
self::$ignoredLines[$filename][$token->getEndLine()] = TRUE;
} // Intentional fallthrough
case 'PHP_Token_OPEN_TAG':
case 'PHP_Token_CLOSE_TAG':
case 'PHP_Token_USE': {
self::$ignoredLines[$filename][$token->getLine()] = TRUE;
}
break;
}
if ($ignore) {
self::$ignoredLines[$filename][$token->getLine()] = TRUE;
if ($stop) {
$ignore = FALSE;
$stop = FALSE;
}
}
}
}
return self::$ignoredLines[$filename];
}
/**
* @param float $a
* @param float $b
* @return float ($a / $b) * 100
*/
public static function percent($a, $b, $asString = FALSE, $fixedWidth = FALSE)
{
if ($asString && $b == 0) {
return '';
}
if ($b > 0) {
$percent = ($a / $b) * 100;
} else {
$percent = 100;
}
if ($asString) {
if ($fixedWidth) {
return sprintf('%6.2F%%', $percent);
}
return sprintf('%01.2F%%', $percent);
} else {
return $percent;
}
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Exception class for PHP_CodeCoverage component.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Exception extends RuntimeException
{
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
/**
* Interface for code coverage drivers.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
*/
interface PHP_CodeCoverage_Driver
{
/**
* Start collection of code coverage information.
*/
public function start();
/**
* Stop collection of code coverage information.
*
* @return array
*/
public function stop();
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
/**
* Filter for blacklisting and whitelisting of code coverage information.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
*/
class PHP_CodeCoverage_Filter
{
/**
* Source files that are blacklisted.
*
* @var array
*/
protected $blacklistedFiles = array();
/**
* Source files that are whitelisted.
*
* @var array
*/
protected $whitelistedFiles = array();
/**
* @var boolean
*/
protected $blacklistPrefilled = FALSE;
/**
* Adds a directory to the blacklist (recursively).
*
* @param string $directory
* @param string $suffix
* @param string $prefix
*/
public function addDirectoryToBlacklist($directory, $suffix = '.php', $prefix = '')
{
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray(
$directory, $suffix, $prefix
);
foreach ($files as $file) {
$this->addFileToBlacklist($file);
}
}
/**
* Adds a file to the blacklist.
*
* @param string $filename
*/
public function addFileToBlacklist($filename)
{
$this->blacklistedFiles[realpath($filename)] = TRUE;
}
/**
* Adds files to the blacklist.
*
* @param array $files
*/
public function addFilesToBlacklist(array $files)
{
foreach ($files as $file) {
$this->addFileToBlacklist($file);
}
}
/**
* Removes a directory from the blacklist (recursively).
*
* @param string $directory
* @param string $suffix
* @param string $prefix
*/
public function removeDirectoryFromBlacklist($directory, $suffix = '.php', $prefix = '')
{
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray(
$directory, $suffix, $prefix
);
foreach ($files as $file) {
$this->removeFileFromBlacklist($file);
}
}
/**
* Removes a file from the blacklist.
*
* @param string $filename
*/
public function removeFileFromBlacklist($filename)
{
$filename = realpath($filename);
if (isset($this->blacklistedFiles[$filename])) {
unset($this->blacklistedFiles[$filename]);
}
}
/**
* Adds a directory to the whitelist (recursively).
*
* @param string $directory
* @param string $suffix
* @param string $prefix
*/
public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '')
{
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray(
$directory, $suffix, $prefix
);
foreach ($files as $file) {
$this->addFileToWhitelist($file);
}
}
/**
* Adds a file to the whitelist.
*
* @param string $filename
*/
public function addFileToWhitelist($filename)
{
$this->whitelistedFiles[realpath($filename)] = TRUE;
}
/**
* Adds files to the whitelist.
*
* @param array $files
*/
public function addFilesToWhitelist(array $files)
{
foreach ($files as $file) {
$this->addFileToWhitelist($file);
}
}
/**
* Removes a directory from the whitelist (recursively).
*
* @param string $directory
* @param string $suffix
* @param string $prefix
*/
public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '')
{
$facade = new File_Iterator_Facade;
$files = $facade->getFilesAsArray(
$directory, $suffix, $prefix
);
foreach ($files as $file) {
$this->removeFileFromWhitelist($file);
}
}
/**
* Removes a file from the whitelist.
*
* @param string $filename
*/
public function removeFileFromWhitelist($filename)
{
$filename = realpath($filename);
if (isset($this->whitelistedFiles[$filename])) {
unset($this->whitelistedFiles[$filename]);
}
}
/**
* Checks whether a filename is a real filename.
*
* @param string $filename
*/
public function isFile($filename)
{
if ($filename == '-' ||
strpos($filename, 'eval()\'d code') !== FALSE ||
strpos($filename, 'runtime-created function') !== FALSE ||
strpos($filename, 'runkit created function') !== FALSE ||
strpos($filename, 'assert code') !== FALSE ||
strpos($filename, 'regexp code') !== FALSE) {
return FALSE;
}
return TRUE;
}
/**
* Checks whether or not a file is filtered.
*
* When the whitelist is empty (default), blacklisting is used.
* When the whitelist is not empty, whitelisting is used.
*
* @param string $filename
* @param boolean $ignoreWhitelist
* @return boolean
* @throws PHP_CodeCoverage_Exception
*/
public function isFiltered($filename)
{
$filename = realpath($filename);
if (!empty($this->whitelistedFiles)) {
return !isset($this->whitelistedFiles[$filename]);
}
if (!$this->blacklistPrefilled) {
$this->prefillBlacklist();
}
return isset($this->blacklistedFiles[$filename]);
}
/**
* Returns the list of blacklisted files.
*
* @return array
*/
public function getBlacklist()
{
return array_keys($this->blacklistedFiles);
}
/**
* Returns the list of whitelisted files.
*
* @return array
*/
public function getWhitelist()
{
return array_keys($this->whitelistedFiles);
}
/**
* Returns whether this filter has a whitelist.
*
* @return boolean
* @since Method available since Release 1.1.0
*/
public function hasWhitelist()
{
return !empty($this->whitelistedFiles);
}
/**
* @since Method available since Release 1.2.3
*/
protected function prefillBlacklist()
{
if (defined('__PHPUNIT_PHAR__')) {
$this->addFileToBlacklist(__PHPUNIT_PHAR__);
}
$this->addDirectoryContainingClassToBlacklist('File_Iterator');
$this->addDirectoryContainingClassToBlacklist('PHP_CodeCoverage');
$this->addDirectoryContainingClassToBlacklist('PHP_Invoker');
$this->addDirectoryContainingClassToBlacklist('PHP_Timer');
$this->addDirectoryContainingClassToBlacklist('PHP_Token');
$this->addDirectoryContainingClassToBlacklist('PHPUnit_Framework_TestCase', 2);
$this->addDirectoryContainingClassToBlacklist('PHPUnit_Extensions_Database_TestCase', 2);
$this->addDirectoryContainingClassToBlacklist('PHPUnit_Framework_MockObject_Generator', 2);
$this->addDirectoryContainingClassToBlacklist('PHPUnit_Extensions_SeleniumTestCase', 2);
$this->addDirectoryContainingClassToBlacklist('PHPUnit_Extensions_Story_TestCase', 2);
$this->addDirectoryContainingClassToBlacklist('Text_Template');
$this->addDirectoryContainingClassToBlacklist('Symfony\Component\Yaml\Yaml');
$this->blacklistPrefilled = TRUE;
}
/**
* @param string $className
* @param integer $parent
* @since Method available since Release 1.2.3
*/
protected function addDirectoryContainingClassToBlacklist($className, $parent = 1)
{
if (!class_exists($className)) {
return;
}
$reflector = new ReflectionClass($className);
$directory = $reflector->getFileName();
for ($i = 0; $i < $parent; $i++) {
$directory = dirname($directory);
}
$this->addDirectoryToBlacklist($directory);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.2.1
*/
/**
*
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.2.1
*/
class PHP_CodeCoverage_Version
{
const VERSION = '1.2.12';
protected static $version;
/**
* Returns the version of PHP_CodeCoverage.
*
* @return string
*/
public static function id()
{
if (self::$version === NULL) {
self::$version = self::VERSION;
if (is_dir(dirname(dirname(__DIR__)) . '/.git')) {
$dir = getcwd();
chdir(__DIR__);
$version = exec('git describe --tags');
chdir($dir);
if ($version) {
if (count(explode('.', self::VERSION)) == 3) {
self::$version = $version;
} else {
$version = explode('-', $version);
self::$version = self::VERSION . '-' . $version[2];
}
}
}
}
return self::$version;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Base class for nodes in the code coverage information tree.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
abstract class PHP_CodeCoverage_Report_Node implements Countable
{
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $path;
/**
* @var array
*/
protected $pathArray;
/**
* @var PHP_CodeCoverage_Report_Node
*/
protected $parent;
/**
* @var string
*/
protected $id;
/**
* Constructor.
*
* @param string $name
* @param PHP_CodeCoverage_Report_Node $parent
*/
public function __construct($name, PHP_CodeCoverage_Report_Node $parent = NULL)
{
if (substr($name, -1) == '/') {
$name = substr($name, 0, -1);
}
$this->name = $name;
$this->parent = $parent;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
public function getId()
{
if ($this->id === NULL) {
$parent = $this->getParent();
if ($parent === NULL) {
$this->id = 'index';
} else {
$parentId = $parent->getId();
if ($parentId == 'index') {
$this->id = str_replace(':', '_', $this->name);
} else {
$this->id = $parentId . '_' . $this->name;
}
}
}
return $this->id;
}
/**
* @return string
*/
public function getPath()
{
if ($this->path === NULL) {
if ($this->parent === NULL) {
$this->path = $this->name;
} else {
$this->path = $this->parent->getPath() . '/' . $this->name;
}
}
return $this->path;
}
/**
* @return array
*/
public function getPathAsArray()
{
if ($this->pathArray === NULL) {
if ($this->parent === NULL) {
$this->pathArray = array();
} else {
$this->pathArray = $this->parent->getPathAsArray();
}
$this->pathArray[] = $this;
}
return $this->pathArray;
}
/**
* @return PHP_CodeCoverage_Report_Node
*/
public function getParent()
{
return $this->parent;
}
/**
* Returns the percentage of classes that has been tested.
*
* @param boolean $asString
* @return integer
*/
public function getTestedClassesPercent($asString = TRUE)
{
return PHP_CodeCoverage_Util::percent(
$this->getNumTestedClasses(),
$this->getNumClasses(),
$asString
);
}
/**
* Returns the percentage of traits that has been tested.
*
* @param boolean $asString
* @return integer
*/
public function getTestedTraitsPercent($asString = TRUE)
{
return PHP_CodeCoverage_Util::percent(
$this->getNumTestedTraits(),
$this->getNumTraits(),
$asString
);
}
/**
* Returns the percentage of traits that has been tested.
*
* @param boolean $asString
* @return integer
* @since Method available since Release 1.2.0
*/
public function getTestedClassesAndTraitsPercent($asString = TRUE)
{
return PHP_CodeCoverage_Util::percent(
$this->getNumTestedClassesAndTraits(),
$this->getNumClassesAndTraits(),
$asString
);
}
/**
* Returns the percentage of methods that has been tested.
*
* @param boolean $asString
* @return integer
*/
public function getTestedMethodsPercent($asString = TRUE)
{
return PHP_CodeCoverage_Util::percent(
$this->getNumTestedMethods(),
$this->getNumMethods(),
$asString
);
}
/**
* Returns the percentage of executed lines.
*
* @param boolean $asString
* @return integer
*/
public function getLineExecutedPercent($asString = TRUE)
{
return PHP_CodeCoverage_Util::percent(
$this->getNumExecutedLines(),
$this->getNumExecutableLines(),
$asString
);
}
/**
* Returns the number of classes and traits.
*
* @return integer
* @since Method available since Release 1.2.0
*/
public function getNumClassesAndTraits()
{
return $this->getNumClasses() + $this->getNumTraits();
}
/**
* Returns the number of tested classes and traits.
*
* @return integer
* @since Method available since Release 1.2.0
*/
public function getNumTestedClassesAndTraits()
{
return $this->getNumTestedClasses() + $this->getNumTestedTraits();
}
/**
* Returns the classes and traits of this node.
*
* @return array
* @since Method available since Release 1.2.0
*/
public function getClassesAndTraits()
{
return array_merge($this->getClasses(), $this->getTraits());
}
/**
* Returns the classes of this node.
*
* @return array
*/
abstract public function getClasses();
/**
* Returns the traits of this node.
*
* @return array
*/
abstract public function getTraits();
/**
* Returns the functions of this node.
*
* @return array
*/
abstract public function getFunctions();
/**
* Returns the LOC/CLOC/NCLOC of this node.
*
* @return array
*/
abstract public function getLinesOfCode();
/**
* 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 traits.
*
* @return integer
*/
abstract public function getNumTraits();
/**
* Returns the number of tested traits.
*
* @return integer
*/
abstract public function getNumTestedTraits();
/**
* Returns the number of methods.
*
* @return integer
*/
abstract public function getNumMethods();
/**
* Returns the number of tested methods.
*
* @return integer
*/
abstract public function getNumTestedMethods();
/**
* Returns the number of functions.
*
* @return integer
*/
abstract public function getNumFunctions();
/**
* Returns the number of tested functions.
*
* @return integer
*/
abstract public function getNumTestedFunctions();
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Represents a file in the code coverage information tree.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_Node_File extends PHP_CodeCoverage_Report_Node
{
/**
* @var array
*/
protected $coverageData;
/**
* @var array
*/
protected $testData;
/**
* @var array
*/
protected $ignoredLines;
/**
* @var integer
*/
protected $numExecutableLines = 0;
/**
* @var integer
*/
protected $numExecutedLines = 0;
/**
* @var array
*/
protected $classes = array();
/**
* @var array
*/
protected $traits = array();
/**
* @var array
*/
protected $functions = array();
/**
* @var array
*/
protected $linesOfCode = array();
/**
* @var integer
*/
protected $numTestedTraits = 0;
/**
* @var integer
*/
protected $numTestedClasses = 0;
/**
* @var integer
*/
protected $numMethods = NULL;
/**
* @var integer
*/
protected $numTestedMethods = NULL;
/**
* @var integer
*/
protected $numTestedFunctions = NULL;
/**
* @var array
*/
protected $startLines = array();
/**
* @var array
*/
protected $endLines = array();
/**
* @var boolean
*/
protected $cacheTokens;
/**
* Constructor.
*
* @param string $name
* @param PHP_CodeCoverage_Report_Node $parent
* @param array $coverageData
* @param array $testData
* @param boolean $cacheTokens
* @throws PHP_CodeCoverage_Exception
*/
public function __construct($name, PHP_CodeCoverage_Report_Node $parent, array $coverageData, array $testData, $cacheTokens)
{
if (!is_bool($cacheTokens)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1, 'boolean'
);
}
parent::__construct($name, $parent);
$this->coverageData = $coverageData;
$this->testData = $testData;
$this->ignoredLines = PHP_CodeCoverage_Util::getLinesToBeIgnored(
$this->getPath(), $cacheTokens
);
$this->cacheTokens = $cacheTokens;
$this->calculateStatistics();
}
/**
* Returns the number of files in/under this node.
*
* @return integer
*/
public function count()
{
return 1;
}
/**
* Returns the code coverage data of this node.
*
* @return array
*/
public function getCoverageData()
{
return $this->coverageData;
}
/**
* Returns the test data of this node.
*
* @return array
*/
public function getTestData()
{
return $this->testData;
}
/**
* @return array
*/
public function getIgnoredLines()
{
return $this->ignoredLines;
}
/**
* Returns the classes of this node.
*
* @return array
*/
public function getClasses()
{
return $this->classes;
}
/**
* Returns the traits of this node.
*
* @return array
*/
public function getTraits()
{
return $this->traits;
}
/**
* Returns the functions of this node.
*
* @return array
*/
public function getFunctions()
{
return $this->functions;
}
/**
* Returns the LOC/CLOC/NCLOC of this node.
*
* @return array
*/
public function getLinesOfCode()
{
return $this->linesOfCode;
}
/**
* 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 count($this->classes);
}
/**
* Returns the number of tested classes.
*
* @return integer
*/
public function getNumTestedClasses()
{
return $this->numTestedClasses;
}
/**
* Returns the number of traits.
*
* @return integer
*/
public function getNumTraits()
{
return count($this->traits);
}
/**
* Returns the number of tested traits.
*
* @return integer
*/
public function getNumTestedTraits()
{
return $this->numTestedTraits;
}
/**
* Returns the number of methods.
*
* @return integer
*/
public function getNumMethods()
{
if ($this->numMethods === NULL) {
$this->numMethods = 0;
foreach ($this->classes as $class) {
foreach ($class['methods'] as $method) {
if ($method['executableLines'] > 0) {
$this->numMethods++;
}
}
}
foreach ($this->traits as $trait) {
foreach ($trait['methods'] as $method) {
if ($method['executableLines'] > 0) {
$this->numMethods++;
}
}
}
}
return $this->numMethods;
}
/**
* Returns the number of tested methods.
*
* @return integer
*/
public function getNumTestedMethods()
{
if ($this->numTestedMethods === NULL) {
$this->numTestedMethods = 0;
foreach ($this->classes as $class) {
foreach ($class['methods'] as $method) {
if ($method['executableLines'] > 0 &&
$method['coverage'] == 100) {
$this->numTestedMethods++;
}
}
}
foreach ($this->traits as $trait) {
foreach ($trait['methods'] as $method) {
if ($method['executableLines'] > 0 &&
$method['coverage'] == 100) {
$this->numTestedMethods++;
}
}
}
}
return $this->numTestedMethods;
}
/**
* Returns the number of functions.
*
* @return integer
*/
public function getNumFunctions()
{
return count($this->functions);
}
/**
* Returns the number of tested functions.
*
* @return integer
*/
public function getNumTestedFunctions()
{
if ($this->numTestedFunctions === NULL) {
$this->numTestedFunctions = 0;
foreach ($this->functions as $function) {
if ($function['executableLines'] > 0 &&
$function['coverage'] == 100) {
$this->numTestedFunctions++;
}
}
}
return $this->numTestedFunctions;
}
/**
* Calculates coverage statistics for the file.
*/
protected function calculateStatistics()
{
if ($this->cacheTokens) {
$tokens = PHP_Token_Stream_CachingFactory::get($this->getPath());
} else {
$tokens = new PHP_Token_Stream($this->getPath());
}
$this->processClasses($tokens);
$this->processTraits($tokens);
$this->processFunctions($tokens);
$this->linesOfCode = $tokens->getLinesOfCode();
unset($tokens);
for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
if (isset($this->startLines[$lineNumber])) {
// Start line of a class.
if (isset($this->startLines[$lineNumber]['className'])) {
$currentClass = &$this->startLines[$lineNumber];
}
// Start line of a trait.
else if (isset($this->startLines[$lineNumber]['traitName'])) {
$currentTrait = &$this->startLines[$lineNumber];
}
// Start line of a method.
else if (isset($this->startLines[$lineNumber]['methodName'])) {
$currentMethod = &$this->startLines[$lineNumber];
}
// Start line of a function.
else if (isset($this->startLines[$lineNumber]['functionName'])) {
$currentFunction = &$this->startLines[$lineNumber];
}
}
if (!isset($this->ignoredLines[$lineNumber]) &&
isset($this->coverageData[$lineNumber]) &&
$this->coverageData[$lineNumber] !== NULL) {
if (isset($currentClass)) {
$currentClass['executableLines']++;
}
if (isset($currentTrait)) {
$currentTrait['executableLines']++;
}
if (isset($currentMethod)) {
$currentMethod['executableLines']++;
}
if (isset($currentFunction)) {
$currentFunction['executableLines']++;
}
$this->numExecutableLines++;
if (count($this->coverageData[$lineNumber]) > 0 ||
isset($this->ignoredLines[$lineNumber])) {
if (isset($currentClass)) {
$currentClass['executedLines']++;
}
if (isset($currentTrait)) {
$currentTrait['executedLines']++;
}
if (isset($currentMethod)) {
$currentMethod['executedLines']++;
}
if (isset($currentFunction)) {
$currentFunction['executedLines']++;
}
$this->numExecutedLines++;
}
}
if (isset($this->endLines[$lineNumber])) {
// End line of a class.
if (isset($this->endLines[$lineNumber]['className'])) {
unset($currentClass);
}
// End line of a trait.
else if (isset($this->endLines[$lineNumber]['traitName'])) {
unset($currentTrait);
}
// End line of a method.
else if (isset($this->endLines[$lineNumber]['methodName'])) {
unset($currentMethod);
}
// End line of a function.
else if (isset($this->endLines[$lineNumber]['functionName'])) {
unset($currentFunction);
}
}
}
foreach ($this->traits as &$trait) {
foreach ($trait['methods'] as &$method) {
if ($method['executableLines'] > 0) {
$method['coverage'] = ($method['executedLines'] /
$method['executableLines']) * 100;
} else {
$method['coverage'] = 100;
}
$method['crap'] = $this->crap(
$method['ccn'], $method['coverage']
);
$trait['ccn'] += $method['ccn'];
}
if ($trait['executableLines'] > 0) {
$trait['coverage'] = ($trait['executedLines'] /
$trait['executableLines']) * 100;
} else {
$trait['coverage'] = 100;
}
if ($trait['coverage'] == 100) {
$this->numTestedClasses++;
}
$trait['crap'] = $this->crap(
$trait['ccn'], $trait['coverage']
);
}
foreach ($this->classes as &$class) {
foreach ($class['methods'] as &$method) {
if ($method['executableLines'] > 0) {
$method['coverage'] = ($method['executedLines'] /
$method['executableLines']) * 100;
} else {
$method['coverage'] = 100;
}
$method['crap'] = $this->crap(
$method['ccn'], $method['coverage']
);
$class['ccn'] += $method['ccn'];
}
if ($class['executableLines'] > 0) {
$class['coverage'] = ($class['executedLines'] /
$class['executableLines']) * 100;
} else {
$class['coverage'] = 100;
}
if ($class['coverage'] == 100) {
$this->numTestedClasses++;
}
$class['crap'] = $this->crap(
$class['ccn'], $class['coverage']
);
}
}
/**
* @param PHP_Token_Stream $tokens
*/
protected function processClasses(PHP_Token_Stream $tokens)
{
$classes = $tokens->getClasses();
unset($tokens);
$link = $this->getId() . '.html#';
foreach ($classes as $className => $class) {
$this->classes[$className] = array(
'className' => $className,
'methods' => array(),
'startLine' => $class['startLine'],
'executableLines' => 0,
'executedLines' => 0,
'ccn' => 0,
'coverage' => 0,
'crap' => 0,
'package' => $class['package'],
'link' => $link . $class['startLine']
);
$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(
'methodName' => $methodName,
'signature' => $method['signature'],
'startLine' => $method['startLine'],
'endLine' => $method['endLine'],
'executableLines' => 0,
'executedLines' => 0,
'ccn' => $method['ccn'],
'coverage' => 0,
'crap' => 0,
'link' => $link . $method['startLine']
);
$this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName];
$this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName];
}
}
}
/**
* @param PHP_Token_Stream $tokens
*/
protected function processTraits(PHP_Token_Stream $tokens)
{
$traits = $tokens->getTraits();
unset($tokens);
$link = $this->getId() . '.html#';
foreach ($traits as $traitName => $trait) {
$this->traits[$traitName] = array(
'traitName' => $traitName,
'methods' => array(),
'startLine' => $trait['startLine'],
'executableLines' => 0,
'executedLines' => 0,
'ccn' => 0,
'coverage' => 0,
'crap' => 0,
'package' => $trait['package'],
'link' => $link . $trait['startLine']
);
$this->startLines[$trait['startLine']] = &$this->traits[$traitName];
$this->endLines[$trait['endLine']] = &$this->traits[$traitName];
foreach ($trait['methods'] as $methodName => $method) {
$this->traits[$traitName]['methods'][$methodName] = array(
'methodName' => $methodName,
'signature' => $method['signature'],
'startLine' => $method['startLine'],
'endLine' => $method['endLine'],
'executableLines' => 0,
'executedLines' => 0,
'ccn' => $method['ccn'],
'coverage' => 0,
'crap' => 0,
'link' => $link . $method['startLine']
);
$this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName];
$this->endLines[$method['endLine']] = &$this->traits[$traitName]['methods'][$methodName];
}
}
}
/**
* @param PHP_Token_Stream $tokens
*/
protected function processFunctions(PHP_Token_Stream $tokens)
{
$functions = $tokens->getFunctions();
unset($tokens);
$link = $this->getId() . '.html#';
foreach ($functions as $functionName => $function) {
$this->functions[$functionName] = array(
'functionName' => $functionName,
'signature' => $function['signature'],
'startLine' => $function['startLine'],
'executableLines' => 0,
'executedLines' => 0,
'ccn' => $function['ccn'],
'coverage' => 0,
'crap' => 0,
'link' => $link . $function['startLine']
);
$this->startLines[$function['startLine']] = &$this->functions[$functionName];
$this->endLines[$function['endLine']] = &$this->functions[$functionName];
}
}
/**
* Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code
* based on its cyclomatic complexity and percentage of code coverage.
*
* @param integer $ccn
* @param float $coverage
* @return string
* @since Method available since Release 1.2.0
*/
protected function crap($ccn, $coverage)
{
if ($coverage == 0) {
return (string)pow($ccn, 2) + $ccn;
}
if ($coverage >= 95) {
return (string)$ccn;
}
return sprintf(
'%01.2F', pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Recursive iterator for PHP_CodeCoverage_Report_Node object graphs.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_Node_Iterator implements RecursiveIterator
{
/**
* @var integer
*/
protected $position;
/**
* @var PHP_CodeCoverage_Report_Node[]
*/
protected $nodes;
/**
* Constructor.
*
* @param PHP_CodeCoverage_Report_Node_Directory $node
*/
public function __construct(PHP_CodeCoverage_Report_Node_Directory $node)
{
$this->nodes = $node->getChildNodes();
}
/**
* 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->nodes);
}
/**
* 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->nodes[$this->position] : NULL;
}
/**
* Moves forward to next element.
*
*/
public function next()
{
$this->position++;
}
/**
* Returns the sub iterator for the current element.
*
* @return PHP_CodeCoverage_Report_Node_Iterator
*/
public function getChildren()
{
return new PHP_CodeCoverage_Report_Node_Iterator(
$this->nodes[$this->position]
);
}
/**
* Checks whether the current element has children.
*
* @return boolean
*/
public function hasChildren()
{
return $this->nodes[$this->position] instanceof PHP_CodeCoverage_Report_Node_Directory;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Represents a directory in the code coverage information tree.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_Node_Directory extends PHP_CodeCoverage_Report_Node implements IteratorAggregate
{
/**
* @var PHP_CodeCoverage_Report_Node[]
*/
protected $children = array();
/**
* @var PHP_CodeCoverage_Report_Node_Directory[]
*/
protected $directories = array();
/**
* @var PHP_CodeCoverage_Report_Node_File[]
*/
protected $files = array();
/**
* @var array
*/
protected $classes;
/**
* @var array
*/
protected $traits;
/**
* @var array
*/
protected $functions;
/**
* @var array
*/
protected $linesOfCode = NULL;
/**
* @var integer
*/
protected $numFiles = -1;
/**
* @var integer
*/
protected $numExecutableLines = -1;
/**
* @var integer
*/
protected $numExecutedLines = -1;
/**
* @var integer
*/
protected $numClasses = -1;
/**
* @var integer
*/
protected $numTestedClasses = -1;
/**
* @var integer
*/
protected $numTraits = -1;
/**
* @var integer
*/
protected $numTestedTraits = -1;
/**
* @var integer
*/
protected $numMethods = -1;
/**
* @var integer
*/
protected $numTestedMethods = -1;
/**
* @var integer
*/
protected $numFunctions = -1;
/**
* @var integer
*/
protected $numTestedFunctions = -1;
/**
* Returns the number of files in/under this node.
*
* @return integer
*/
public function count()
{
if ($this->numFiles == -1) {
$this->numFiles = 0;
foreach ($this->children as $child) {
$this->numFiles += count($child);
}
}
return $this->numFiles;
}
/**
* Returns an iterator for this node.
*
* @return RecursiveIteratorIterator
*/
public function getIterator()
{
return new RecursiveIteratorIterator(
new PHP_CodeCoverage_Report_Node_Iterator($this),
RecursiveIteratorIterator::SELF_FIRST
);
}
/**
* Adds a new directory.
*
* @param string $name
* @return PHP_CodeCoverage_Report_Node_Directory
*/
public function addDirectory($name)
{
$directory = new PHP_CodeCoverage_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 $coverageData
* @param array $testData
* @param boolean $cacheTokens
* @return PHP_CodeCoverage_Report_Node_File
* @throws PHP_CodeCoverage_Exception
*/
public function addFile($name, array $coverageData, array $testData, $cacheTokens)
{
$file = new PHP_CodeCoverage_Report_Node_File(
$name, $this, $coverageData, $testData, $cacheTokens
);
$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 child nodes of this node.
*
* @return array
*/
public function getChildNodes()
{
return $this->children;
}
/**
* 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 traits of this node.
*
* @return array
*/
public function getTraits()
{
if ($this->traits === NULL) {
$this->traits = array();
foreach ($this->children as $child) {
$this->traits = array_merge(
$this->traits, $child->getTraits()
);
}
}
return $this->traits;
}
/**
* Returns the functions of this node.
*
* @return array
*/
public function getFunctions()
{
if ($this->functions === NULL) {
$this->functions = array();
foreach ($this->children as $child) {
$this->functions = array_merge(
$this->functions, $child->getFunctions()
);
}
}
return $this->functions;
}
/**
* Returns the LOC/CLOC/NCLOC of this node.
*
* @return array
*/
public function getLinesOfCode()
{
if ($this->linesOfCode === NULL) {
$this->linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
foreach ($this->children as $child) {
$linesOfCode = $child->getLinesOfCode();
$this->linesOfCode['loc'] += $linesOfCode['loc'];
$this->linesOfCode['cloc'] += $linesOfCode['cloc'];
$this->linesOfCode['ncloc'] += $linesOfCode['ncloc'];
}
}
return $this->linesOfCode;
}
/**
* 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 traits.
*
* @return integer
*/
public function getNumTraits()
{
if ($this->numTraits == -1) {
$this->numTraits = 0;
foreach ($this->children as $child) {
$this->numTraits += $child->getNumTraits();
}
}
return $this->numTraits;
}
/**
* Returns the number of tested traits.
*
* @return integer
*/
public function getNumTestedTraits()
{
if ($this->numTestedTraits == -1) {
$this->numTestedTraits = 0;
foreach ($this->children as $child) {
$this->numTestedTraits += $child->getNumTestedTraits();
}
}
return $this->numTestedTraits;
}
/**
* 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;
}
/**
* Returns the number of functions.
*
* @return integer
*/
public function getNumFunctions()
{
if ($this->numFunctions == -1) {
$this->numFunctions = 0;
foreach ($this->children as $child) {
$this->numFunctions += $child->getNumFunctions();
}
}
return $this->numFunctions;
}
/**
* Returns the number of tested functions.
*
* @return integer
*/
public function getNumTestedFunctions()
{
if ($this->numTestedFunctions == -1) {
$this->numTestedFunctions = 0;
foreach ($this->children as $child) {
$this->numTestedFunctions += $child->getNumTestedFunctions();
}
}
return $this->numTestedFunctions;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Base class for PHP_CodeCoverage_Report_Node renderers.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
abstract class PHP_CodeCoverage_Report_HTML_Renderer
{
/**
* @var string
*/
protected $templatePath;
/**
* @var string
*/
protected $charset;
/**
* @var string
*/
protected $generator;
/**
* @var string
*/
protected $date;
/**
* @var integer
*/
protected $lowUpperBound;
/**
* @var integer
*/
protected $highLowerBound;
/**
* Constructor.
*
* @param string $templatePath
* @param string $charset
* @param string $generator
* @param string $date
* @param integer $lowUpperBound
* @param integer $highLowerBound
*/
public function __construct($templatePath, $charset, $generator, $date, $lowUpperBound, $highLowerBound)
{
$this->templatePath = $templatePath;
$this->charset = $charset;
$this->generator = $generator;
$this->date = $date;
$this->lowUpperBound = $lowUpperBound;
$this->highLowerBound = $highLowerBound;
}
/**
* @param Text_Template $template
* @param array $data
* @return string
*/
protected function renderItemTemplate(Text_Template $template, array $data)
{
$numSeperator = '&nbsp;/&nbsp;';
$classesBar = '&nbsp;';
$classesLevel = 'None';
$classesNumber = '&nbsp;';
if (isset($data['numClasses']) && $data['numClasses'] > 0) {
$classesLevel = $this->getColorLevel($data['testedClassesPercent']);
$classesNumber = $data['numTestedClasses'] . $numSeperator .
$data['numClasses'];
$classesBar = $this->getCoverageBar(
$data['testedClassesPercent']
);
}
$methodsBar = '&nbsp;';
$methodsLevel = 'None';
$methodsNumber = '&nbsp;';
if ($data['numMethods'] > 0) {
$methodsLevel = $this->getColorLevel($data['testedMethodsPercent']);
$methodsNumber = $data['numTestedMethods'] . $numSeperator .
$data['numMethods'];
$methodsBar = $this->getCoverageBar(
$data['testedMethodsPercent']
);
}
$linesBar = '&nbsp;';
$linesLevel = 'None';
$linesNumber = '&nbsp;';
if ($data['numExecutableLines'] > 0) {
$linesLevel = $this->getColorLevel($data['linesExecutedPercent']);
$linesNumber = $data['numExecutedLines'] . $numSeperator .
$data['numExecutableLines'];
$linesBar = $this->getCoverageBar(
$data['linesExecutedPercent']
);
}
$template->setVar(
array(
'icon' => isset($data['icon']) ? $data['icon'] : '',
'crap' => isset($data['crap']) ? $data['crap'] : '',
'name' => $data['name'],
'lines_bar' => $linesBar,
'lines_executed_percent' => $data['linesExecutedPercentAsString'],
'lines_level' => $linesLevel,
'lines_number' => $linesNumber,
'methods_bar' => $methodsBar,
'methods_tested_percent' => $data['testedMethodsPercentAsString'],
'methods_level' => $methodsLevel,
'methods_number' => $methodsNumber,
'classes_bar' => $classesBar,
'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '',
'classes_level' => $classesLevel,
'classes_number' => $classesNumber
)
);
return $template->render();
}
/**
* @param Text_Template $template
* @param PHP_CodeCoverage_Report_Node $node
*/
protected function setCommonTemplateVariables(Text_Template $template, PHP_CodeCoverage_Report_Node $node)
{
$template->setVar(
array(
'id' => $node->getId(),
'full_path' => $node->getPath(),
'breadcrumbs' => $this->getBreadcrumbs($node),
'charset' => $this->charset,
'date' => $this->date,
'version' => PHP_CodeCoverage_Version::id(),
'php_version' => PHP_VERSION,
'generator' => $this->generator,
'low_upper_bound' => $this->lowUpperBound,
'high_lower_bound' => $this->highLowerBound
)
);
}
protected function getBreadcrumbs(PHP_CodeCoverage_Report_Node $node)
{
$breadcrumbs = '';
$path = $node->getPathAsArray();
foreach ($path as $step) {
if ($step !== $node) {
$breadcrumbs .= $this->getInactiveBreadcrumb($step);
} else {
$breadcrumbs .= $this->getActiveBreadcrumb(
$step,
$node instanceof PHP_CodeCoverage_Report_Node_Directory
);
}
}
return $breadcrumbs;
}
protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node, $isDirectory)
{
$buffer = sprintf(
' <li class="active">%s</li>' . "\n",
$node->getName()
);
if ($isDirectory) {
$buffer .= sprintf(
' <li>(<a href="%s.dashboard.html">Dashboard</a>)</li>' . "\n",
$node->getId()
);
}
return $buffer;
}
protected function getInactiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
{
return sprintf(
' <li><a href="%s.html">%s</a> <span class="divider">/</span></li>' . "\n",
$node->getId(),
$node->getName()
);
}
protected function getCoverageBar($percent)
{
$level = $this->getColorLevel($percent);
$template = new Text_Template(
$this->templatePath . 'coverage_bar.html'
);
$template->setVar(array('level' => $level, 'percent' => sprintf("%.2F", $percent)));
return $template->render();
}
/**
* @param integer $percent
* @return string
*/
protected function getColorLevel($percent)
{
if ($percent < $this->lowUpperBound) {
return 'danger';
}
else if ($percent >= $this->lowUpperBound &&
$percent < $this->highLowerBound) {
return 'warning';
}
else {
return 'success';
}
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
// @codeCoverageIgnoreStart
if (!defined('T_TRAIT')) {
define('T_TRAIT', 1001);
}
if (!defined('T_INSTEADOF')) {
define('T_INSTEADOF', 1002);
}
if (!defined('T_CALLABLE')) {
define('T_CALLABLE', 1003);
}
// @codeCoverageIgnoreEnd
/**
* Renders a PHP_CodeCoverage_Report_Node_File node.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_HTML_Renderer_File extends PHP_CodeCoverage_Report_HTML_Renderer
{
/**
* @var boolean
*/
protected $highlight;
/**
* Constructor.
*
* @param string $templatePath
* @param string $charset
* @param string $generator
* @param string $date
* @param integer $lowUpperBound
* @param integer $highLowerBound
* @param boolean $highlight
*/
public function __construct($templatePath, $charset, $generator, $date, $lowUpperBound, $highLowerBound, $highlight)
{
parent::__construct(
$templatePath,
$charset,
$generator,
$date,
$lowUpperBound,
$highLowerBound
);
$this->highlight = $highlight;
}
/**
* @param PHP_CodeCoverage_Report_Node_File $node
* @param string $file
*/
public function render(PHP_CodeCoverage_Report_Node_File $node, $file)
{
$template = new Text_Template($this->templatePath . 'file.html');
$template->setVar(
array(
'items' => $this->renderItems($node),
'lines' => $this->renderSource($node)
)
);
$this->setCommonTemplateVariables($template, $node);
$template->renderTo($file);
}
/**
* @param PHP_CodeCoverage_Report_Node_File $node
* @return string
*/
protected function renderItems(PHP_CodeCoverage_Report_Node_File $node)
{
$template = new Text_Template($this->templatePath . 'file_item.html');
$methodItemTemplate = new Text_Template(
$this->templatePath . 'method_item.html'
);
$items = $this->renderItemTemplate(
$template,
array(
'name' => 'Total',
'numClasses' => $node->getNumClassesAndTraits(),
'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
'numMethods' => $node->getNumMethods(),
'numTestedMethods' => $node->getNumTestedMethods(),
'linesExecutedPercent' => $node->getLineExecutedPercent(FALSE),
'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
'numExecutedLines' => $node->getNumExecutedLines(),
'numExecutableLines' => $node->getNumExecutableLines(),
'testedMethodsPercent' => $node->getTestedMethodsPercent(FALSE),
'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(FALSE),
'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
'crap' => '<acronym title="Change Risk Anti-Patterns (CRAP) Index">CRAP</acronym>'
)
);
$items .= $this->renderFunctionItems(
$node->getFunctions(), $methodItemTemplate
);
$items .= $this->renderTraitOrClassItems(
$node->getTraits(), $template, $methodItemTemplate
);
$items .= $this->renderTraitOrClassItems(
$node->getClasses(), $template, $methodItemTemplate
);
return $items;
}
/**
* @param array $items
* @param Text_Template $template
* @return string
*/
protected function renderTraitOrClassItems(array $items, Text_Template $template, Text_Template $methodItemTemplate)
{
if (empty($items)) {
return '';
}
$buffer = '';
foreach ($items as $name => $item) {
$numMethods = count($item['methods']);
$numTestedMethods = 0;
foreach ($item['methods'] as $method) {
if ($method['executedLines'] == $method['executableLines']) {
$numTestedMethods++;
}
}
$buffer .= $this->renderItemTemplate(
$template,
array(
'name' => $name,
'numClasses' => 1,
'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0,
'numMethods' => $numMethods,
'numTestedMethods' => $numTestedMethods,
'linesExecutedPercent' => PHP_CodeCoverage_Util::percent(
$item['executedLines'],
$item['executableLines'],
FALSE
),
'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent(
$item['executedLines'],
$item['executableLines'],
TRUE
),
'numExecutedLines' => $item['executedLines'],
'numExecutableLines' => $item['executableLines'],
'testedMethodsPercent' => PHP_CodeCoverage_Util::percent(
$numTestedMethods,
$numMethods,
FALSE
),
'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent(
$numTestedMethods,
$numMethods,
TRUE
),
'testedClassesPercent' => PHP_CodeCoverage_Util::percent(
$numTestedMethods == $numMethods ? 1 : 0,
1,
FALSE
),
'testedClassesPercentAsString' => PHP_CodeCoverage_Util::percent(
$numTestedMethods == $numMethods ? 1 : 0,
1,
TRUE
),
'crap' => $item['crap']
)
);
foreach ($item['methods'] as $method) {
$buffer .= $this->renderFunctionOrMethodItem(
$methodItemTemplate, $method, '&nbsp;'
);
}
}
return $buffer;
}
/**
* @param array $functions
* @param Text_Template $template
* @return string
*/
protected function renderFunctionItems(array $functions, Text_Template $template)
{
if (empty($functions)) {
return '';
}
$buffer = '';
foreach ($functions as $function) {
$buffer .= $this->renderFunctionOrMethodItem(
$template, $function
);
}
return $buffer;
}
/**
* @param Text_Template $template
* @return string
*/
protected function renderFunctionOrMethodItem(Text_Template $template, array $item, $indent = '')
{
$numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0;
return $this->renderItemTemplate(
$template,
array(
'name' => sprintf(
'%s<a href="#%d">%s</a>',
$indent,
$item['startLine'],
htmlspecialchars($item['signature'])
),
'numMethods' => 1,
'numTestedMethods' => $numTestedItems,
'linesExecutedPercent' => PHP_CodeCoverage_Util::percent(
$item['executedLines'],
$item['executableLines'],
FALSE
),
'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent(
$item['executedLines'],
$item['executableLines'],
TRUE
),
'numExecutedLines' => $item['executedLines'],
'numExecutableLines' => $item['executableLines'],
'testedMethodsPercent' => PHP_CodeCoverage_Util::percent(
$numTestedItems,
1,
FALSE
),
'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent(
$numTestedItems,
1,
TRUE
),
'crap' => $item['crap']
)
);
}
/**
* @param PHP_CodeCoverage_Report_Node_File $node
* @return string
*/
protected function renderSource(PHP_CodeCoverage_Report_Node_File $node)
{
$coverageData = $node->getCoverageData();
$ignoredLines = $node->getIgnoredLines();
$testData = $node->getTestData();
$codeLines = $this->loadFile($node->getPath());
$lines = '';
$i = 1;
foreach ($codeLines as $line) {
$numTests = '';
$trClass = '';
$popoverContent = '';
$popoverTitle = '';
if (!isset($ignoredLines[$i]) && isset($coverageData[$i])) {
$numTests = count($coverageData[$i]);
if ($coverageData[$i] === NULL) {
$trClass = ' class="warning"';
}
else if ($numTests == 0) {
$trClass = ' class="danger"';
}
else {
$trClass = ' class="success popin"';
$popoverContent = '<ul>';
if ($numTests > 1) {
$popoverTitle = $numTests . ' tests cover line ' . $i;
} else {
$popoverTitle = '1 test covers line ' . $i;
}
foreach ($coverageData[$i] as $test) {
switch ($testData[$test]) {
case 0: {
$testCSS = ' class="success"';
}
break;
case 1:
case 2: {
$testCSS = ' class="warning"';
}
break;
case 3: {
$testCSS = ' class="danger"';
}
break;
case 4: {
$testCSS = ' class="danger"';
}
break;
default: {
$testCSS = '';
}
}
$popoverContent .= sprintf(
'<li%s>%s</li>',
$testCSS,
htmlspecialchars($test)
);
}
$popoverContent .= '</ul>';
}
}
if (!empty($popoverTitle)) {
$popover = sprintf(
' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
$popoverTitle,
htmlspecialchars($popoverContent)
);
} else {
$popover = '';
}
$lines .= sprintf(
' <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n",
$trClass,
$popover,
$i,
$i,
$i,
!$this->highlight ? htmlspecialchars($line) : $line
);
$i++;
}
return $lines;
}
/**
* @param string $file
* @return array
*/
protected function loadFile($file)
{
$buffer = file_get_contents($file);
$lines = explode("\n", str_replace("\t", ' ', $buffer));
$result = array();
if (count($lines) == 0) {
return $result;
}
$lines = array_map('rtrim', $lines);
if (!$this->highlight) {
unset($lines[count($lines)-1]);
return $lines;
}
$tokens = token_get_all($buffer);
$stringFlag = FALSE;
$i = 0;
$result[$i] = '';
foreach ($tokens as $j => $token) {
if (is_string($token)) {
if ($token === '"' && $tokens[$j - 1] !== '\\') {
$result[$i] .= sprintf(
'<span class="string">%s</span>',
htmlspecialchars($token)
);
$stringFlag = !$stringFlag;
} else {
$result[$i] .= sprintf(
'<span class="keyword">%s</span>',
htmlspecialchars($token)
);
}
continue;
}
list ($token, $value) = $token;
$value = str_replace(
array("\t", ' '),
array('&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'),
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_AS:
case T_BREAK:
case T_CALLABLE:
case T_CASE:
case T_CATCH:
case T_CLASS:
case T_CLONE:
case T_CONTINUE:
case T_DEFAULT:
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_EXIT:
case T_EXTENDS:
case T_FINAL:
case T_FOREACH:
case T_FUNCTION:
case T_GLOBAL:
case T_IF:
case T_IMPLEMENTS:
case T_INCLUDE:
case T_INCLUDE_ONCE:
case T_INSTANCEOF:
case T_INSTEADOF:
case T_INTERFACE:
case T_ISSET:
case T_LOGICAL_AND:
case T_LOGICAL_OR:
case T_LOGICAL_XOR:
case T_NAMESPACE:
case T_NEW:
case T_PRIVATE:
case T_PROTECTED:
case T_PUBLIC:
case T_REQUIRE:
case T_REQUIRE_ONCE:
case T_RETURN:
case T_STATIC:
case T_THROW:
case T_TRAIT:
case T_TRY:
case T_UNSET:
case T_USE:
case T_VAR:
case T_WHILE: {
$colour = 'keyword';
}
break;
default: {
$colour = 'default';
}
}
}
$result[$i] .= sprintf(
'<span class="%s">%s</span>',
$colour,
$line
);
}
if (isset($lines[$jj + 1])) {
$result[++$i] = '';
}
}
}
}
unset($result[count($result)-1]);
return $result;
}
}
<div class="progress progress-{level}" style="width: 100px;">
<div class="bar" style="width: {percent}%;"></div>
</div>
<89>PNG

IHDR<01><00><04><>tEXtSoftwareAdobe ImageReadyq<79>e<1<>IDATx<54><78>}ml\E<><45>W<A6><57><>D$|nw'<27><>;vю<7F>8<C7>m0<6D><30>k<f<><38><<3C>h3$<24>  b,mn<6D><6E><E4> <0A> ғ<17><><12><>0<AB><30>L Y`6s'><14>Q<01><><BC><1D><><B7><EE>S<FD><53><FB><BE><A7><BA>n<9C>S<9F>V<F5>;1K<31>G<BD><47><89>s<F6>ԩ<EA>>Uo<55><6F><BD>TU<54>1cƖ<63>Yuּ<75><D6BC>c<EC><63>a&<26><><F7>#C,pؚ<70><14>>kں <17><><9F><B6>U<96>LW
-s<>n<C6>3V<33>q<9D><71>~N<><4E><9A><FE>o<EF><18>c<FC><63><E8>I<F8>~L<><15>{<7B><>- <09><><C6>H8%_<><5F><E8>M<9D>£w<C2A3>B<F6><42><BF>6EW<45><57>,Ģp<C4A2><70><19><><82><AC>Y<02>2+<2B>(Y<><59><B3><02>@<40><><A0>&<26><>A<F3>/<2F><><02><06><>3kX<6B><58>h<81>ߍ<>-a<><61><8D><1F><>A<D7><07><><>P<><50><F8>'\<5C><><C1>J<9B>;(<28>}<7D>#<00>Qz<51><7A><84><96><FF><94>:4<><34>%m?nf<6E>ntK*<18><><C0><AF>l<E6>9J<39><4A><C9>+<2B>D<A1><44>I<EE><49>Yu1Y<31><59><91>Z^<5E><>(]YYE<59><45>f@<40><><EC><1E>О<E2>lX<6C><58>z]<5D>U<87>t<D7> <09><>u<8F> <0A>&<26>5-P<><50><9A>W<ED>}<7D><>@t<><74>|<7C>#L<><4C>Y<59>=<3D><>s<B4><73><F0>܂<1F><><AC>,w#+<2B>R<BE><52>+?<3F>Ƌa<C68B>x<D6><78> X<>0<E9>"ea)<29>t<9D>G<0F>*ԡwV<10>w<16>V^<5E><>rf%xB(<71>4><3E><1F>W<FC>G<D5>#<23><04><>lWU<Ё<><D081><CC><13>XJVѶ<56><D1B6>l<93><6C><F7><8B><AC>R<BE><52><FD>$k<>DVr<56>I<D3><49><AF><AE><A3>7:<3A>X<<3C>s>%X<>1<02><>N<BE><4E>Ez<1A><>w<BA><77><96>;y<><79>9<EE>z<EF>9<C0>O<F8>%~<7E><><96>~<7E><>u<E1><75>ɗ*<2A>=<3D><><B1><AA><AA>I<1B>x<D1>c<91>y}<7D><>Y(<28><><FE>o<EB><12>u
±N$<24>^<18>j<AC><6A> <>e\<5C><>iX<69>񝜬]<5D><>;Y-<2D>r<A5><72><00><><D7>Ѳ<>&<26><>><3E>!<>zlY<>aVHVN԰<4E>9=<3D><>]<5D>=<3D><><1F><><8D><98>mR<6D><52>M<CC><4D><1E>d<7F><1A>OUC <0B>JUiT}r<>W<1A><>W'<15>ڹu<DAB9><75><><CAA2><16><1F>F"YU<59>#<23><>P<FC>׾<E3><D7BE><9F><84><>Ѕ<ED><D085><CF>R<CC>O<E5><4F><C0><AA>wyz<79><7A>m$<24><><AB>O<BB><4F><B2><14>s? +^<5E>FT<46><54><DB><C1><EA>I<DF>E<90>q<E1>%<25><>&<26><><99><9B><AC>~<7E> ><3E>M<EE><4D><D5>}]<5D><>Ԗ<E1><10>w<16><>A<BB><41><86>?
[<5B><><CB>Nteexn<78>(<28><E5><E68EAA><95>B<AB>d<1A><>MT<4D><14><70>nq<6E>q<FF>S<EE>?<3F><><9A>bW<62><57><96><FB><BC>XmW6<57><36><F1>x*{V_<56><5F><E3><BB><F8>!V<>jΧ<6A>s<F0><73>VL^j<><6A><EF><C2> Xk<58>Qj<51>U<A9><55><F4><FF>6<D0><05><>sk<><6B>̩n~<7E>[<5B>q<FC>Ǹ<F2>-<2D><>` <0A>O<19><><91>:G<><1C><><14><><EB>7<DD><37><E2>l<DF><6C>"k<><6B><B8><99><C7><7F><90>sR<73>e<>2<8A><32>v<1D>Q<F2>=<3D>QƼJ<C6BC>U<CF>X`<60>g<>Qy~ ď<>K<EE><4B>Ȱ<B7><DC>E<B0>]<5D><>#<23><>P<FC><50><E3>:<3A>t<97><74><A6>d<D9>\T<>/u<><1F><><F1><F7><9B><DA><F8><9D>;<3B>س<FE>:<3A>J<A8>c-%'<27><>e<A0><65><E7> q<><71><81>
?j<>"/yh<79><68><86>4<AC><34>8<AC>Zi<1A><><9A><F1><BF><C2><F9>1<D2>|JU<4A><55><FF>u<EF>><3E><>_<BE><5F><C4>N<CD><4E><EB>;hxw<78>NU <0B>J<D3>QU7\<5C><>j<B9><6A><F3>̮bT<62>:<3A><><A3><AF><98>B<>?6<><08><><FE>o<EB>J<7F><4A>1Ί%<25><>I
UY-I<><49><83>i4{<7B>=<3D>rǤ7<C7A4><37>@)H<>K<88>J+<2B>f<12>4<98>X<19>8C<38>d<D7>?'j<><0E>1<83><31><F4> <20><>N<><4E><D1><<3C> 3<>9<DA><39><FC><9F>E<<3C><77><DFAC>V<80><56><8D>z<F7>E}<7D><>^_e檴 p<><70><A5>t붾3<EBB6BE><33>9<8A>,<2C><><E3>?<3F><><BA>g<B1>l<92>Y<CD>O<F7><4F><D6><<3C><><F6>x<CE>x<02>|<7C><><86>a؎<><D88E>Ue<55><65><97><85>F<F0><46><F5><B2><D3> <09>1<16>;<3B><>{ EF<45>0`<60><05><><FF>D<E3>R<C5><52><91>+<2B>U<92>YiD<69><44><E5><D9>4<D1>?<3F>Y`|B<><42><81>s2<73><32>yip<69>I<9B>q<FF><71>>W<>o<D5> <0A>V<><56><9C>T<E1><54>G<FC><47>zg#<23>
%<25><><11>D0#ܠ3<DCA0><33><9E>[t<>i<03>آ<99>( U<>,<2C>]<5D>125<32><35>|<7C><>N<F8>̭fw<66>7w<37> <20><><E6><9A> <0B><>u+<0E>Š<17><>]<5D>D<A8>b]<5D><>K<C2> <20><>xbW<62> ՛7|<7C><>В<95><D092>X㕛<58><01><>{U<><55><DD><18>c<89><63>G<><47><CF><7F>X<F1><6B>|<13>(<28>h)IU<49>a)<16>lp 3<><33>l<10><><FA>uPU<50>]D<><44><92>)<29>/7~4W<34><16>t5<19><>J}<7D><>V<FB><07><>
X<F5>0<AB><A7><86>z<E6> <20>VM<56><4D><A9>;><3E><47>^<5E><E8><7F>|<7C><>gF:<3A><><CE>jaZ<61><5A><E9>^)74C#j<>wr,еS<D0B5>l<F5><6C>G<1F>u<8F>;1<><31><90>v<CC>m><<3C>)<29>}<7D><><AA><<3C><><BD>VZ ue۠D<DBA0><44>+j<>y<D5><79><87><96><1A>J6V{j <0B><><FD>K<92><4B>><3E><>Z<03><><F7><0F><><EF>&<26>mZ:<3A><><01>1<BE>U<EF>MB<4D>~<7E><><A2>
<1E>a<18><><ED>:<3A>/᜗:K<>W<FF>WOҠ&<26><><85><AD><9F>Y<06><><B4>2f<32><06><><F9>7cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘<66><CC98>g<E5><67>*3f<33>F5<>Lb<><62><B4>N<><4E>2#Tf=C<>`!<19><0E>ZG<5A>Ue꣇<65>e<87><65>2V<32><15><><<3C>1mkS<6B><53><A4><1E>4iϗ*.<2E>{N<>8X<38>aj~<06><><8E>ڀ<EF>nA<6E>x,<2C><><FF>%fE:<3A>|<7C>Y<E9>DV<44>j
<9E><EB><AC>¢<DA>lg6<C2>(:<3A>k~<7E><><8C>M<F7>M<F6><4D>5?<3F>4 ]WO<57>><3E><>诋W<E8AF8B><57><17><>Z<1F>iG<69>|<7C>Q<98>G<CB>Je<><65>K[Ycյ<63>pmjE\f/<2F>ǎ8&<26>OQ<4F>3<FF> <19><><8B><E2><9C>.3t<><74>t2'<27>-V<>8<E0><38><DF><F9>p<85>X<83>S<B5>r<B0>Y#J!<21><><AB>Q<F1><51><F0> <20>"<22>,ub<75>@F<><46><1A>K<>:<3A>u<BE>^<5E><>iy<69><79>[]<.Cw<43><77><00><><9D>+W\<5C>)<29><>b<EF><62><BC>
k<AF>r-<2D><04><><E5>.M<>t<>ڀ<>M<D4><4D>q<91>ʄ<15><><F5><8F><C0><B2>۰<1E><><A7><B7>#$<24>^X$<24><>"<22><><9C><8D><A7><89><BD>V`<60>T<95>4<8A>m<><6D>~<7E>w%P<>p1<70><31>|<7C>+&Ux<55>Y<05><>8<8A><38>*<2A>r<C2>8:<3A><><A3><EC><17><>k7QЃҀT<D280><54><AA><03><><E2><93><CA><FA><B8><F0>$<1F><>Ў<><D08E>ƙ<CE>
<81>S>~<7E>S<1F><><FC><AE><F5>j<84>s<CC><73>:5<>q.w<>&_Z.<04>X=<3D><><95><AA>:ވbw<06>`<60><><1A> _<>kd<6B>{'<27><>0<CA>:<3A>d<D8><0E>s<DC><73>#<23><>q<><71><1C>i!224<32><34><D3><F6>nq<6E>\<5C>9<92>-<2D><>KUT<>sSU<53><55>uVo<15>@;<3B>U<BC><55>z<B3>>^<5E><>=<3D><>N<97><4E><B2><DB><F6><95><8F><AA>p<FA><70>>o<><6F>P<85><50>O<BF><4F><85>
<90><A0>@I<><13><>@<40><1B><>'G<><47>j5<6A>o<>*U<>><15><>^<5E>*<2A>e<91>w<9B><12>>ͫʧ<CDAB><CAA7>Q<><51><B0>5 ̈́<><CD84><AF><CA><$<24>#<23>5<9E>J<B6>ٻ<D2><D9BB>j<A8><6A>6e<36>)<29><>_ <0A><><FD><EE>d]<5D><>2<D3><32><82>B:<3A><><C0>^<5E>(*<2A>:8J<38><4A><CA>Y<15>S鬆<53><E9AC86><AE><F2><4B><DD97> ]U4_<34>rj<72>{<7B><><DC>5<E1>ׇ<92>aǑ/<2F>y<ED><79>V<97><02>?<3F><>G<EC>t<BF><74>G<E4><11><0F><><D4>b@xPU<50><55>7O3<4F>|<7C><0F>I<FF><49>Q5<51><1E>Q<DD><51>Gw<47> *(;<3B>w<B3>f<>0*<2A>P<D7>UU<55><Y<>Ɣ<A4><C694><88><FF>v<B6><76><86><B2>b<FE><62>t<CE><74>5{2!<21>,}<7D><><A9><8A>Ҧ<EC><D2A6><96>:)<07><>j2Ok<4F>Ϊ<13>' ֊0I.q\(<28>%ojQ<1F><16><>ĖՇ<C496>a<<3C><><EA>ԍ<EB><D48D>ex<65>Agt<67><74>'<27>[d;׸<><1E><><F9><AB>`r<>cd<63><64><1B><><9E>j<08><>P<8A>FU<46>$<24>UeJ<65>I6<49>T<D9><54><FC>&Z}<7D><><AA>z<14><><BF>(<28>z<95> vfu<66>z<A8> <20><>{}ۿߝ<DBBF><DF9D>ݞlx<6C><78>U<CE>Z<17><EF>.<2E>Y岟b<E5B29F><62><CC>%<25><><BB><10><>nw<6E><77>@<40><>ǩ<D7><C7A9>S9<53><39>|źs%<25>><3E>_<>o#<23><><A7>9<9E>\<5C>EU~<7E>/<2F>ځ<DD>t(r<>[<5B>Q<BD><14>Zu<03><03>Oo;<3B><><B0><9F><1D>!MrU<72>]<5D><>0T<30><54>cpDő<44>?.<2E><><AC>c<1B><>Pu<50><75><ED><B1><CD>F<><46><80><B2><80><99>;<0F><><1E><>L_<4C><5F><B9><A9><AA><AB><B3>S<F9><53>b}<7D>R/<2F>J_<4A><5F>+<19><>h<D4>2$<17>a<F5><61>i<A3> <0B>U<AD>ǩ<D5><C7A9>S9><3E><>Є}7<13>6r<36><07><>zu<7A><75><F9><DE><ED>~国4<E59BBD><34>
1J<9C><AD><80><14>
<B5><8C>^<5E>̘<B1><CC98>~<7E><1E>i<43>5<81><35>5<P<>ھ<EF>r<9D>/<2F>G<C4><1E>Y<FF>k૵<6B><E0ABB5>5<97>mK
<80><8B>2姪<32>Ϊ5,<2C><><C2>?<3F>1'<0F>jÓQ<C393><51><94>pT뾺<54><EBBEBA><F0>
*<2A><>~<7E>I?H<>ם<D5><D79D>):<3A><><B4><FA>\<5C><><A9><F9><F9><FB>J<F8><4A>:3<>ѴUGo)X<><58>.<2E>Ë<CC><C38B><BC>*j<7F>\<5C><>?}<7D><DF>G~A{Y#<23>W/3<><33><EA>!ʼ<><CABC><E3>=<3D><>C<EF>g<04>u *<2A><><D4>u_<75><5F>ޮ+<2B>Qe<51><65>5<83>w<C2>:<3A><><F8>U<CF><55><E9><86>K<CB><4B>?U<>W<9C>1j\<5C><>S5/<<3C>z7P^<5E><><D6><F0><,S<><14>j<>UU8<55><38><10><><AA><EA>v,<2C>2<8A>_<87><5F><C6>_<16><>i<FB><DA><EBBB8A><AE>^<5E><><9F><AA>R5^v<><76>Nl>G׹]<5D>g<FA><67><85>w<F5><77>s<0E>n zTuO=<3D>?/<0F><><93><D3>zƲc><3E><>Οb<>#7ֻcg<63><67>k<E6><6B>ޛT<DE9B>U<9D>j<><6A><90>*-T=]<5D><><DD><FA>uu}<7D><><><0A><><1D>[ ]<5D><>:%/_<> <0C><>S<EB>z]6D.<2E>m<D4><6D><AE><87><83><AC>D7Uƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘1c<05><><E6><FA><A3>><3E>J4h<34>PP<50><50>+<2B><>A<A7>;'<27>G_<47>XK<58><4B>mL<6D><4C><AB>5I.},wFFu<46><75>m$S<>-<2D>E<A5>-;Õ
C3I-`<07>B<CF><42>R<DF><52>x1<78><31>ғT<D293>Jݕ;hΊ<68>8<9C> D<>Y<EA><59>J<AA><4A>o;<3B><><B4><E7><C0><FE>Yš5<C29A>M<><4D><B2><CD>K<E4><4B>ɰM<4D><7F>;<3B><><9A>%P<><50><BA>d9K<39>h<EE><68><94>n<80><6E>D[z<><7A>gVh<56>,<2C><12>'C<19>
p!^M<>(<28>WK2<4B>X<AA>>UQ<55><51>%<25><><E2>^<5E><10>p8 ˽<>^#<23>Ζ؄+.@<40><><97>g<F1>C<EA>z%ɔ-Pr
<96><82><B8>K<BF>X<FF><88>
<BC><85><82><A6>n<D3><C1><16>><3E><><BD>=<3D>Ք<8B>Ѩ<DE><D1A8>eSvR<76><52><15><>L<92>z<97><7A><AA><F2>5%9UQS <20><>\<5C>W<8C>ի<91><D5AB>K<CA><4B>'<27>h<DC>p)ô
J<B7><94>r<98>h<A1><DF> <0A><><9E>M0<4D>F <0C><>(f_<>R5<52>/<2F>//<2F>G<><47>+<18><><F3><AA><8B><F5><FE><0E>x 1"<22><><E8><BF><FE>eS<65><53> 5<><35>
<AD><D6>:T<><54>f<66><7F>=+<2B>7<14>Qɧ<>\<5C><><8C><97><93>TE<54><45><A2><A1>s<A7><FC>r<EF><72><C6>Y<DE>s8<73><1B>&<26>k<86><6B><ED><EC><F9><FB><B6><FF>#pSՊ5<D58A>M<><4D>T<B3>b<AA><62>D܊[Ng<4E>5Q<35>\s<><1A>5PB@[<5B><38>V1<56><14><><AA><A2><A4>&<26><>4Wsy[<5B>Ǿ
<9F>w<D2>U<80><BD><F1>2<B2>V<96><AA><B6><EE><EC>7<05><>7<C2><37>j<80><6A><EF><C4><D4><D0>މd^~Yf<59><66>C<ED><43>_<AB><5F>h;a.<2E><><CC>&<26>M<86>
i<9D> <1E><14>U<C2><55><96><16><01>Wpzs`><3E>/<2F>"<22><>'O<>I<F2><49><9D><F6>۲<DA><DBB2>y<05><><89><8A><16>:<1B>Bzd<7A><64><F5><C3><FB><93>T<F2><17><><71><C2A3><><D0B9>b:<3A><><85>"<22><><FC><BD>m<F9>/<2F><01>-/P<><1D>W<F7>DQ<44>Ǵ͐<C7B4><CD90>5<FF><35><C9>7<><37><9F><16><><17>m<>`<60>H<><48>%A<><41><9D>V<F3><56>!<21>H<C9>ԛ׿<D49B><17><>@"Q<><51>z<><7A>ދ|<7C>ߒT<DF92><07><>-<2D><>*OU<4F>^<5E><>Ҧ6<D2A6><36><FC><BA><A9>!<21><><C8>Cw<43>k<>|h<>&Hd5<64>LEY<45>y<12><>'<27>ƣ7<C6A3><37>%<25>*<2A><C'@<40>l<00><><1B>b!wL<>WW(%<25><><F8>C<10><><DF>4<14><><17><><83><81><E6><FB>3\<5C><><14><0F><><84><B3><A4>x<D0><78><E1><AD><F4><FA><B7>*<2A><><8D><AA><BD><B3>QF<51>Ҩ<1A><<3C><>m<E9><6D><A7><1F><12><><BA>߃g?߉<><1E><><C3><FB><A8>^<5E>)D<>}<7D>{<7B>U<DF><55>֘|<7C>Q<08><><AD><9B>=C'@<40>|<00>uwL<>ׂQ<D782>E<B0>=<3D>?<3F>x+<2B>x<D6> "<22><><BE><DB>g<97><67><FD>S<11> <0B>O<EF>Ҩj<D2A8><6A>׈ .<2E><>fqj[<5B><><FD>Y<9B><59><E0><47>C<FD><43><C3>焓m>{<7B><>=)<29><14><>Z<C6><><D99D>P <09><><07>*G<><47><D5>]<5D><07><><C0>/<2F><00>8L<01><>w<><77>$?8<38><7F>M<F1>)\į<><11><><10>/#<23>7U<37>fd7'6<>\h1<68>
vI<>f<>EIr<49><72><98>=<3D><90>1<BD>w<F8><77>\<5C>WK<57><1E>VZ<05>HK<><4B>g<9C>Z<FE><5A>͡<83>$m<><6D>x<E4><78><B7><8B> %<05><> <>`j}<7D>TuT<1C><><81>QJZ<4A><5A>*H>*Q<>xkLFT<46><10><1F><>y<DE><79>U<93><14><02>-<2D>)<29>ôb<><62>iA<69><41><A8>|q`<60><>F<BF>'<27><><1F>+ <09><><98>4^Q<>y <0B>x<B4><78>H)<29><1E>#<23>t^<5E><>?@]^`A<>R<D5>S<EA><53>q<19>jg<6A>B:<3A>r<h̆<68>Rn<11><02><>z<CA><16><><50>)<11><>[+<2B>n <0B><>M<D2>X<01>H!<21><><87><A6>0<7F><30><E6>I<0F><><F7><81>r<06><> <0A><>sKϡէU<>R2<52><32>T X<>gƴڳE<DAB3>3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘1c<31>n<C6><6E>j<C1><6A><B9><C0>ǴyƌI<C68C><49>xQ<78>q<FC>7fM<66><4D><83>4E<16>F<CC><46>.<2E><><C3>34<.<2E>i<><69><94>;<3B><>eВi<D092><69><9A>1c%9<><39><F9><BA>K <09><><11><>͠2<14><81>J<CD>C<8D><43>n<EC><6E>w<D5><04><0F> <45>c<F9>F<90><46><F9><8A><82><B4>`<60><>5v6<76>%˿]<5D>3<F8><33>T<AA><54>y<FC><79>`<60>~<7E><><9D>a<A8><61><A2>[[<16>J<1F>>K<0F>۷l<2<>-4<>Y<BF><59>K<E7>hgQ<67><51><B0>L<F6><4C>x<C4>V<9C>w<A7>P<DE><50>~<7E><>M <0A>Φ<F5><CEA6><BE><90><8F>0l 3<>ƅ<9A>aŊIT<49>ȀhwJ<77>m<><6D><BC><A8><AC><E8><C1><A8>xIM<49>չ<A4><D5B9>|<7C><>U7xˆS<CB86><53>~2<>ߕ?<3F>kW1k<0F><><A5>C3]<5D><>;Y<><59>nS<6E><01><>ґA<17>e<>X<BA>Yz<59>8,'<27>x<82>< k7Kx<><78><91><9D><83>]<5D><>$<24><>x<A5>$<24>v<05><>g<B4>T#w<><77>;o<><1F><><C9><FD>@ <08>z<C8>_V<5F><56><D0>m<F7>n|<7C><48><D6B5>h<1D><>Zg-^TAn<41><6E>-<2D> )<29><><83><E0>@4<>[*<2A>9xK<78><4B>Ƌ<C5><C68B><E7><D6><C1>j><3E>!,<01>Vt<56>:e<><65><F9><0F><>qn8%oh<14><><B2>S<E9>(2<>\Q<><51>^<5E>aig<69><67><E9><1A><>F<B8><46>3<B8><33>v<B3>TUDV<>l<B8>Q<92><C8>W<AC>c<A5><63>%<25>U<92><55><E0>e<AA>q<8E>4<A9>ҝº/<2F><>U<BE> <0A>$<24>_<86><5F>Q!<21><><C2>><3E><><BC><11><>t<D5>|<7C> <20>G<t<>C<DF><43><F7>[<5B>xTXmf|<7C><03><<3C><><4F>MT<4D>|(w:<3A><><CC>_X<5F><08><><A4>j7w<37><77><B0>t<B3><74><F1> <20>
AX<DF>ͦ<AA>p<D9>$<24>^xZ<78>R<AB><52><B1><EE><F6><A4><91><D5>j<EB>x<AC><78><14><>`<60>3=<11>^<5E><0F>ll<6C>+˗e<CB97>Q<><1B>8g8V <0B><>+<2B>9M<39><4D><01>/<2F><><A3><07><><00>o<96>14sn<73>b<14> <0C><1E>tX<74>܍<17>s<DB><73><8A><FD><C9>vE<76>l+@\<5C><>e<92>,<2C>,<2C><63><<3C>(<28><>i<C2>HVY<56>r<AA><72>Q<A5> O7<>a<A3><61>I<ED><49>>Q%d<>#jUՆ<55>|; H<><48>[b<><62><C8><C2><C1>ά<B9>#<23><><CA><CA><C6><1C><>,W<>s7NT1~<7E><><DD>m<>{' \<5C><><96> <0B>b<92>BKJ<12>o8<6F>%<25>!<0F><><98>$<24><>Q<AA><51><97><9B>j:<3A><>/<2F>RX)$Sy<53>޳ <>R<><52>DUg_D<5F><44><83>J<C6>\<5C><><D1><12><>j<AA>N<DF><4E>֖SU;~<7E>?<3F><>O<F7><4F>h<BC>ss<73>d<><64>ƣ}<7D>6<>(T <<16><>_<D5>4<9E><34><C9>b5<62><35><F8><16> <20>^N <0B><><AA>N<F8>%8QejF<6A>7to<74><6F><E7>My<4D>ө<DB>`)g<>[<5B><>/<2F><><A6><D2><D0><CC><C7>|<7C><><AA><BA>?<06><>өJ<D3A9><4A><C1>u<E5>G<DC><47><A7><BA>L<E3><EF><17>/=<3D>CTܠhd<68>ifH<66><48><BA><63><C79E><81><F9><E6>G4<47><34>,<2C><><BC><EE><F8><F3><E1><F5>`<60><44>{'x<><78><FD>G_p/5<><35><F8>@m +<2B>$jV<6A>H<D4><48><A8>3<8A>a"<22><>,<2C>,<2C><>H<FB><4A>ȸ<>T^Qy<51><79>o&IÉ<17>JUVwW<1F><><A7>L<C3>eM<65><4D>~<03><><8F>3t<33><74><A2><A2><10><1C><>A<BB><41>6<E3><36><F4><CE>r<C1><72><77>6<CA><36><9C>տ<B2><D5BF> <20><><D0>\0H<30>L%L<>X5<58><35>c<92><63><A8><A1><C6>@<40>HHÃZ<><5A>|NV<4E><56>+7WM<57><4D>{<7B><><FC><AD>cig<69><67><E9><E2>*<2A><><BC><CE>ȸU<C8B8><55><9A>7iÉ<17><1A>бz<D0B1><7A><8A>d<FA> *<2A> ?<15>gt<67><74>X<C7><58><F5>8<ED><38>̝O<CC9D><4F>X<B0><08><>:<3A><>]2<>ɍ]<5D>p^<5E><>++<2B><>><3E><><13>A<B8><41><94>VڛE<DA9B>{<7B><><E2> <0B><02>DB.<2E>&<26>/<2F><><C5><D2><CE><D2>56<35><36><9F>A<A9>rxY#ܕ<16>y<F7>)<29><>cKQ<74><C8AA><F3><B2>~<7E><00><><CE><F0><B6><FF><AD><EA><F5><8C>! <20><>;<3B>C}ʃ<><CA83><18>tf{<7B>6<E6><36>$N<><4E>Vsj <0B><>wup<75>Z)zŁ<7A>|<7C>-<2D>w<0F>g+n<1E>MVj<56>/d+U<><55><8F><BD><B0><04><><CDAF><C4><DB><1D>i<B2><69><8D>:_ix<69><78> w<><77>hq<68><71>r><3E>駃-<2D>x<CD>뼬)<29><>ݷ<DF>y<DA><79>R=! <20><><EC><96>ì:<05><0E>J/l<><14>Ik<49><6B><0E>V@<40>n<B9><6E>7<17>475<37><35>8<E7>Z<AB><5A> K<>J<D1>(<28><>Ux<55>z<9A><7A>1w<31>)^<5E><>\<5C>ԣ<9F><06>zȪ󲦨c<F3B2A6A8><06><>2f<32>؍<CC>v<E8>+<2B>6f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘<66>2<B1><32>N<AE><4E> o<>C<9F><43>\<5C><><9E><F5><05>F1<46>ִ<9D> <0A>UZ<55>JV̚\<5C>4<AE><34><CD><E9>M<><4D><A7><F7>gq1z{&<26><>Y<9D><59>T
<A3>,<2C>HX~D<> u<>\<5C><>g<9D><67>}x<>><3E>+Y<><59><02>dN<64>̮<DE><CCAE>o<EF>l <0A>Z<B8>X+F<><46>[<1A>/j<><6A>+S~2/jV<6A><56><EE>8<B9>J<1B>r^<5E><><AD><DB><1E>ԉ]J}J<><C5>*ۏ<<3C><>2԰&<26><4A><DDA3>jO<><4F>M@<40>ѯ#0<><13><>O<A5>[<5B><>S<FA><53><89><CA><F7><B7><B0>X<86>B^ uz<75>e<F9><1E>\<5C><><A7><D7><C1>]<5D><><85><EF>d<13><><AE>d.<2E><><B0>/<2F><><84>xXE
<A2>f'v<><76>O<EB>_<BB><5F><B4><1D>H<8B>${<7B>%;<3B>k<18>t<E7><37>m<DF><6D>ő|<7C><><08>d{a<>ފ<>^<5E><><1F>Ǜ<16>ڎE<DA8E><45>5ʋ<><CA8B>Br]W<><57><B7>=<3D>_<A8><5F><B9><9A>SA<53><13><>f(<28>0 <1E><>oU<>5<D7>q ,<1F>_\<5C>l<D7>uz<75>˪uz<1D><><BC><90><E3BBB2><0E>o<D7><6F>=Yi<59><69><E5>~|<0F><>
0+<2B>=V<><56><8C><D5><F2><B5><F6><94><00>J<A8>ت <0B><>/<2F><06>ލ<0F><>zM<7A><4D>\<5C>zC<14>L<E5><4C><C3><FF>[U<>:|k*^8"<22><>\Wٚ\ .<2E><>XTjX<6A>5 <0B>Sk<53>F<19>u\<1D>1<94><31> <20><><AD>q'<27><>m<F6>ģ/<2F>Q<><51><BF><55>*<2A>AɽDNZ׮?_<>[#<23> ˍ4<CB8D>:<3A>^j|<7C>5<>L<10>G<CA><47><F9> ||<00><><A9>ø<C2>BW{6[uQF<51><46><A9><03>.1<8A><B4>$qF<71><0E>9<ED><39><02>IHg)\<5C><><F7><0E><><CD>5<9E><35>>C<>#<23><>u<C3>X<01>Z<DC><5A>$<11>#*<<3C>ߐ<>sR<73>v<C9>1Tj>J<><4A>m>*<2A><><A7><AB>#<23><>(<28><>
<C9><E9>[F<>h<A6><73>5<F5><1C>*jQʼ<51>&<26><><9A>&<26><>&P<><50><EA><88>犛L<E78A9B><4C>[<1A>Q<DE><51><94>1*<2A><><10><> <20><>;<3B><1A><><15>X}<7D>I<D3>ΰ<95>[Q<>?<3F>q<10>Q<A8>Z H<><1E><><F3><FB>ݙ<F7><DD99><07>֞V<D69E><56>EsB<73><04>C<BC>Z9<5A><39>JTK<54><4B> <0B><><06><>tu<74><75><81>p<><70>˷<AB><CBB7> /<2F>O<A9><4F><EF><1D>,.k<>Ud<55>s<89>OHMg4=-)<29>+ؿ<><D8BF><E8>h2<68><C1>N<B9><4E>w<83>/r|W<>Qn=<3D>GIU<49>;<3B><>'<27><12><07>j,<2C><>v<><76>f<EE>dz<F1><C7B3><06><>p<99>e<BF><65><8F><AC>$<13><><F5><E0>V GTY<>sBZ<1F>O<C4>1p<31>j:<04><><FC><98>r<A8><72><1D>"n<>TUSCg<43><67>r <0B>ve<76><65><A7>A<A4>ۘ<EC><18>˜F<C298>C+Ֆ#<23>[J<><4A><96>Te<54>'v9-<2D>3 D<>m<EE>ӻ<A8>u<D4>uz<1D><><BC><FB><13><>?<3F><>0<DD><30> <20>o<94><6F><CB> <09><><A2><D2>h<>x<11><>u<AB>Y<89><59> &<26><10><><B7><1D><>_<BB>54<35>=f<><66><B5>07<30><37>kלU<D79C><07>0<F0><30>]D:<3A><><D4><F8><E6><82><1C>j<CF>dw<64>/+<2B><>P<DA><50>GUV<55><56>S<E4><53><<3C><>\2<>u<><75>at<61>c<1A>^zY<7A>R<DC>ąmC<6D>+<2B><>7<D2><02><><BC>#<23><>,|<7C><>:<3A><>i<16>N<99><4E>w<83><77>*|^s<><73>m<DC>|<7C>X>Ъ<EE9692>^<5E><>1<DD>\<5C>#<23><><81>͹<D3> &<26><><98>%<25>{,2<><32>U<B8><55>><3E>ݎ.c0<01>5<8F>z<81>#<23>
o<EB>g<85><F6>N<E0><A3><D7>O+<2B><>Q<A9><10><> <20><><10><03><06><11>,<2C><>˗<CC>-%K\<5C><><F9><B4>[S_`<60>y<FD><79>+<2B><>b<FA><62><F7>_9<5F><39>4<EB><34><9D><DE>"<22>U<A3><55>+<2B><>Ύap<61>}<7D>I<B2><49><AD><B8>[<5B>M,B<><42>.<2E>Nt<11><><F1><9C>w<C7>H<><04>j<><94><07><>E<AC> <0C><><BA><EF><12><>L<9E><4C>߀ 0DX(<28>k<A9>ڵ<8F><DAB5><A7><B6> <0B>NoU<><55>{<7B>gquz
R<E8>wkէRx'<10>uZ<>[<5B><><1E><>3'<27><>z<A5>yy<79><79>ד%<25><U<><55>hN[<5B><><B9><A6><E8>tz<74>x1<78> c<>c<97><63><FD>]F ݯ<>B<D5>"]a[J<16><><B7><98>Dս[cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3V<06>es{L+3VH ]YP<59>A <09>><3E>s<FB><73><9F><BD><A6>ƕ<A0><C695><FA>3jYF\<5C><>s<DA><73><B8>=m1<6D>&<26><><D4>V<8C><19><>Aɼ?k\+]<5D>6y<0F><EF><1D>1<BB><31><8A>gt<67>OIW7<>a<F6>l|1<08><><AB><EC> <20><><E8><A9><F5>>$]e <0C>7<9D><37>؝<DA>W<BF>I<08>e?ަ<>L#<23><><95>>|<7C><><C7><FF>
<ED><8F>ҭ<B1><08>]<5D><>
p<B1>M5M<AD>U<>dI<64><49><FA>61<36><31>Ԡ<FD>eǼY<7F>G<BD><47><F0><F0><FE>h<BB>O<ED>n<A0><6E>3<D4>խR:^<15>k_'Yuuq#<23><><EC>p<E7>#
<10>J<E2><4A><BF><87><9F>2<>x<D6><78><A5><99>l><3E><>Oj<4F><6A><05><><D9><0F>cY<63><59><B2><E9A683>!<21>ڡ+<2B>sZ/<2F><><FC><ED><EC> D<>}<7D><>2<E1><32>A<1C>Y m<><6D><99><00>p<12>c#<23><'x<><78>SKx<4B><78>`<60><>*W[,e|<7C><>6<8F><36>B<B7>H)㶤kj<6B><6A><95>p<D9><70>D<BB>U(2qzx<7A><78>9<A8><39><E9><D5>*tqa<71>/,<2C>
Z[<5B><> 0<>><3E><>Ө<EC>֜<15><F3><7F><8C>xN)f<>ă<EF><C483>@qը<71><D5A8><87><CD>FU՝<55><D59D>w(<28><17>a;ˋ<13>><3E>|T<>c|<02>w2<><32><A0><12>eiT]*<2A>!_\<5C>WG{
<8F> <0A><>]<5D><>^<5E><><05>݅<><DD85>Z5<5A><35><CC><D4>t|<7C><>6<8F>oYH<59><48><C8><CE><C8>a<7F><61><0E><><BF><AC><DB>O@<40>=<3D><><ED><AB><84> my^ak<61><6B><13><><BA>E<F1>.<2E><><BE><A8>u<C5><75><F4>z<EE><7A>]#٥<><D9A5>hWv<57>(<28><>:<3A>,<2C><1D>6<1E><>A<F5><41>߉J<DF89><E7>Fa<46><16><>\ <08><>w<82><77>W<F8><57><D7>ex>v<><<3C><>?|<7C><><FD><87>&i_<16>q<BE>z<86> <0C><><CF><F0>] e<>R_<52>7<08>|& c*<2A>kր4f<34><66><D4>,J <20>U<AB><55><97>_<>h<C4><68>\1A<><41><A4><84><EE><1A><><F9><95><BF><F9><B5><A5>u\<5C><>-<2D>L\Ϝ^<5E><>~<12>P<D4>hr<68><72>*tqa0<61><30>fT<66><54>:<0F>MU<4D><55>;q<>><3E>et<65>u<8B>M<B9><4D>Y<CF><59>A><3E><18><><8E><80><E1>).,<2C><><>C<02>bw<>jE)<29><>W<D4><57><B0><E2><1F> <0A><>Fӫ@<40>s4<73><34>e<14>6^<5E><>Q9oI}4<>x<<3C><><FB>.<2E>B?<3F><>B<96><42>߫<C2>#<23><>$<24><15>Hx<48>.x9,<2C><>a!<21>RT<>pgd5<64><35><BA><FF><89><A5>xB<78><42>e<FD><65><8A><8E><02>.L7@<40>*<2A><>
Asdutt<03>S<><53>VUa<55><61>RU|<7C><>I xG<>߃$T<><54><AE><FC><C3>񭟬<FD><F1AD9FAC><1B><>#_<><5F>IF<49>MŒ<4D>_X<5F>@f<>o<F5><6F><F7>Q<C2>ID<49><44>I<7F><49>I?|<7C>%<25><><8E><BF>$<24>r<><7F> <09><><A5>{<7B><><9C><9F><89>E<CC><45><4E><77><DE95>qq<>?<3F><03><><ED>D<E2>ؽ}<7D>}o<>/`ӣ<>CT<43>i <09><><9D><Q<>R{\yY<79><59><C7><07><>F<><46><C1>QJkh<6B><68><FB><CA><FB><9C>^?Us:<3A>E<D9><45>|]<5D><><DC>V<03>)Z|H<>jsW<73><57><F6> <0B>|<7C>H'|<7C><>o<EE><6F><91><82>=d|<7C>߼j <20>#<23><>T<F9><54><0E>%<25>O<9F><4F> W<08><>!<21>N#<1E>w<C7>1[i<69>H(<28><>SV<53><56><BD><F9>s<E6><73><AC><FA><85>[=<3D>Ɉ<D4><C988><8A><18>7<E3><37><9F><B3>1<95>ȳ<><C8B3><BE>T]A G<><D4><E68F9B><EC>3<FD><33><C0><95>CT׻<>lR<6C>ݕCV9Q<39>\V#ܛ<><DC9B>N<07>ӏj<D38F>ˇ1<CB87>/<2F>s<EE>l<00>R<A2><52><95> %^s1<73><31><93>nU<6E>j<D5><0F><><A4>,<2C>x}<7D><>f<85><66>W<7F>|JuK<75>w<><77><FE>p<AD><70><94><ED><FD>S<E7><53>m,<2C><<3C><>7<<3C><06><><8F>
<88><87>Ȼ<><C8BB><10><><9D>[<07>R<&<26><><94>p<A2><07>?<3F><1F><06>'<27><>,<2C>Й<05><><89>\<5C>;<0E><><EC><16>5<CA>bH$<24>3<E4>#<23>Q<>4\<5C><><EC><19>_<F8><5F><81><19>><3E>/<2F>yw<79>O<E3> <0A>rD 9<><1F><04>YUD]<5D><><EA> Ή<><CE89><C3><FA>@s<><73><CA>]<5D><><D9>+'UaL}<7D><> h<><68>r<9A>U<CC><15><><DD>'7<>:<3A><>sU|k)H<><48>@<40><><A7><F4><E1>h<F1>N<DF>q<1D>#<><7F>ϵ<9B>8<C1><38>y<EF>˭<AD>X<E0><58><B2>ű#<23><>w<><77>
<B4>1!<21><95>R'7<><37>f<E7>u<C8>ד<1B><>0<B2><30><8A><F9><BE>p<16>!W<><57>ÖW+Nm<4E>p<D9>\<5C><><A3><AA>-<2D>ioD$<24><00><><A3>g<F2>٠˅%<25>%<25><>Ð<BC>m<F8><6D>V<ED>]<5D>̱<94><CCB1>r<99>w*<2A><>Z<CA>}<7D><>y<F9>+L<>
N<BE><E4>o<E7>u<A9>j<05>}<7D>xt<78><74><87><F4><95><93>)lS<6C><53>tuq<75><71><F5>x<DA><78><B1><FB>m<E9>NyK<79>U<CC><05>OnDb<44>hf}<7D>k<EB>><3E>6<1A><0F>u<9D>fT<66>%<25><><FE><90><F8>{<7B><><14> <񐮸<07><><92>mj<03><>F<A4>c<>mU<6D>ï<><C3AF><08><>c<F9><63>;<3B>w<15><>8<ED><38>@dG<64>FUA<55><41>&<26><><8F> <20><><1A><><EA>=n<>q<F0>5]iP<69><50><08>}<7D>z<0E>:<3A>k⼶<6B><E2BCB6>-<2D><>ʓ<C4> Κl*'U<><55>z<8F>ax<61>W<AB><57><85>F<>dZ<64><5A>zT<7A><54>NR<4E>s+<2B><>#<23><><AB> w<03><>zgi:<3A><>MB<07><>q<C0><71><F8>t<9E><74>M<FA> <0A>l#<23><>^<5E>'G<>ߣ<99>*^<5E>t<DA>{<7B><><8D><9C>=<3D>rE<72><45><FD>R<EA><52>n<BA>Q<>$adJl<4A>02%<25><>Tڊ^<5E><><8A><84><<3C>~g<>?<3F>O<D6>f*U<>^<5E><>?<3F><>:<3A><>N<BD><4E><A2><8A><9E>+<2B>o<9B>[<5B>P<E0>U<BE>s<D2>|<7C>Q<E7><51>R']<5D>V<E7>-L)H <0A>K<9D>䐞 mY<6D><59>n<D5>\<5C><>4}Y<><59>V<EB>D<D3> <0B>h<CE><68><C9>R<F8><52><F0><A9>;g<><05>-<2D><>'<10>3aס<61>M<E6> D<>h<AD>}<1F>1cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ3f̘1cƌ<63><C68C>k<FF>*Ț4<C89A>`L<>$<24>b<81> <09><><AA><F2>U<D6><55><EA><EC>4\dt<64><74><9C>'<27><><9E>><3E>HȄ|<7C>.<2E><>+Y+/<2F>G<87><47>y<E7><79><9A>2<F3>OCWv<19><1F><><D3>3v,<2C>'kia<69><61><E5><CF><CA> <0C><><AD>W<A5><57><B3><BF> O6߯E<DFAF>=Hv
$L<>l<B0>xI<78><49>/<2F><>}<05>^]<5D><><E8><DA><04>x<D3><78>\3<1C><> <0C>ɮ5<C9AE><35> <20><06><06>Q<FF>T&G<>9A<39>y^<5E><><8E><F8><B6><AF>i<FF><69>}O<><4F>[5ޱ<35>wq<77>4,s JJ<4A><4A>I.myE<79>^<5E>%<25><><16>'V<08>B~<7E>d<BD>ׯ<81><D7AF>}<7D>*<16>j<FE><6A>*<2A> ~<7E><>u<03><>T<8F><54>k<AE><6B><86>\f<>KЬ<4B>*<2A><>Y]<5D><><9B><C0><F3>_v'I<12><>˨<D6><CBA8><E6><14><EB>鑩6<E991A9>X<06><08>o<97><6F>'<27>j&u<06><>ɧn<C9A7>g<05><>T]<5D>o<9D><05><>ڌ<84><DA8C>9<C6><0E><><AB>\*<2A>wVHӖ<48>|<10> <09>><3E><>:<3A>5EF<>'J <0A><><BF><1C>ɝ`<60><><EE><03>!<21><>A<F2><41><A6><AF><98><D8><C3> <20>
<C4><D9><E7>e~<7E><>_;<3B><><AA>5<>ױϊ<D7B1><1A><><FB><8C>镋m_&<26>O<FE><4F><F7><19>Vi<56><69><DA><C5><}"<22><AB><E99D8D><BA>hW9<57>X<D6>6<B1><36>KPƣ G<>"<22>ƭ<EB>?<3F><>/<2F><><C1><F7>O<E5>^<5E><><04>hC<7F>H<A6><48><E1>L<D0><1B>c<AC><13><17>i<AC><08>P<18><>j<AA><6A><DF>)}<7D><><FB>Q<D0>Qզ<51><D5A6>#tM<1E><08>g<9D><67>9<B0> <0C><>xGw<47><77><97><82><1E>~d;_<>J+<2B>RỲ<52><<3C><><1E>;<3B>e<07><><12> <0C><>5/Qs<>/5<><35>N[<5B><03>!<13>a+<2B>N<84>P<89>b+<2B>Ѻ<FC><D1BA>I<E9>}<7D><><B4><FB>-<2D><>t_<74>q<E2>U=<3D>MK<4D>ʞ<DC>Y<><59><0F>5no<6E><6F>*<2A><><CA><C7>v<EE><76>v<DE>b<B7>ʊ{]<5D><><B8>|<7C> ~ Z<05><1F>{-<2D><><E8><FF><8F><88><12>끇^<5E><><88><FD>FVviϵ3<CFB5><33>Ya<59><61><02><><D2><FC><98>=6n<36><6E><8C>dS;<3B>-<2D>ʹ^;<3B>uꪪ^ <0A>|<7C><>=<3D><>_<F3>w+<2B><>"<22><><8B><8E><F8>i<69>&4<><34>l<F3>#<23>w<B4><77>i<93><69>r|W<16><><96><F4>3U<33>$<24><>"J<07>~<7E><><91>O@]~t<1B><>RJV<4A><56>MH<4D>w<><CCA6><93><BC>@?<3F><05>><3E>O<EB><4F><A5>?<3F>vdr<64><72>tS<74>*$<24>&~1><3E><><13><><1D><><AB><E4>Z}^<05>n<>L(<28><>]<5D>f*<2A>&<26>*<2A>Q<E8><51>a<92>I<14><><CA><C7>Ꝅ|<7C><>3<8C>*<2A><><B0><97>O<F7><4F><8D>?<3F><><8D><AA><AC><FA><E7><91>r<FF>?<3F>*<2A><><F1>4<B3>Gyz[<5B>k/t<>k<E4><6B>Q<03><>ϖ<CF><CF96><B5>WC<57>C<12>K<D9>k/<2F><>x<FA><78>5<BC>|<7C><>S<E4>*`<16><>Ϲγ<CFB9>Q<98><06><><04><>E<19>w<16><><1A>y<9C>
o <0B><>K<D8>YqT<71>b<F8><62><AA><13>$<24><0F><><CE>-/Pt<50>sZN<5A><4E>K<9B><1C>Q<DB><51>*><3E><>ݢ<89><DDA2><EC><89>U<E5>@<40>Џ"JQ;<3B><><A2>¹&<26>
<8A>Lx<17>;+T<> /+<2B><><BF>O<DA><DD><E8B59F>><3E><> (T<><54><B2>?ķD^N*<2A>'<27>p<C2><70><F6><EF><B7><F6>$I<><49><A4><57><17>W~<7E> =<3D><>J|<7C><01>_<D4><5F>UTe<54><65>7ְP`<60>;CYjk<6A>=<1C>s<DF>U[<5B><>mߙ-<2D><><BC>;<3B>};<3B>2|<7C><><F7>w<14><>o<>1<1E>p<83>0<1E><>~><3E><>0<F0><1F><>m<12><>
@J<><72>cٷ4<D9B7>͜<><05>?q<71><0E>\<5C>UU<55>IV?2<><32><85>L<8F><04>/<2F>+Шꄾ< <16>܇^T<><54><F5> <0A>?t<>j\<12>Jr<4A><72><03>Ҁ<DC><DC><7F>B*<2A><><C1><98><B3>=k<>m<FF><6D> <0C><>X<FE>,n}a<><61><01><>Ւ<AC>Ia<49><61>d<A1><70><D7B7>l<E3>l{\<5C><>6v8<76><38>R<A4><52><AA><EA859F><BA><B7>Ҳ<B2><12><>f<7F>1<A5><05>F|Տ<>;<3B>e<E4>=\D<><44> ,D<><><CF88>r<A2><72>xQ<78>T◎<54>*|{n<><6E>S
9~<7E>=<3D><><D395>G~%j<>:D<><44>j<A9><<3C>ឫ:<3A><>jO%<25><><8C>
<EF>$T8!j<><6A><FF><EC>vm<76><6D>|'O<><4F>З<89><D097>¹➱z\vsIv`<60>Ȕ<13>ʨj<CAA8><6A>-<2D>^<5E>$-<2D><>^<5E><><AC>G <0C>Q<8F><51>{<7B>m<DB><6D><9F>`<60><>T<D2><54>#<23>c<DB>֞<8B><AD>|n<>.ߪN<DFAA>$<24><>O <0B><><C7><D6><C4><11><>JUV<55><56><BF>ʼ<EC>t,<1E><><DF><E9><8F><DD>j<E2>g<C6>-<2D><><F7><85>mסּ<6D>NV<4E><56><B6> <0C><>z<><7A>:<3A><1C><><9F>(<28>Ι*|1U<31>x<D5>=<3D>Y<8F><59>k*<2A><><FC><83>t<F9> <0A>M<><4D><B3><06>N<F7><4E>N<E5>DU<44>hK<68><4B><99> ؞X(刄Rv<52>!<>#B_<06><1C>c<AB>xR<EF8F80><52><9D><A7>Ź<><C5B9><89>o<AA><6F>E5Dg><3E>?<3F>f<FA><66><9B>XQ<58><51>Q<A8>˔|@<40>"<22>աM<D5A1><4D><91><97><A3>veC<65>><3E><>m<D2>O$H<19><>#]Y<><59> <0C>I=<3D><><DC>)_<><1C><>`<60><><A9>k<83><08><>*
<92>:a<>>!X<><58><B3>!<21><>W<AA>^<5E><><1A><1B><>l'<27><;<3B>vwgI<67><49>t<D3>_<>?Jh<4A><68>`<60><>#E:fdx=<3D><>6Wu<<3C><><83><86><19><><00>Ӌ<DB>d2<64>di<19><><16>˂<9F>c#h¬c4<63><34><ED><06>?<<3C><><B4>H<><48><BA><A4>FYo<59><6F>Vp<56>N<BF><4E>;<3B>ݷJ\<11><> <20><><F6><B6><89>><3E>` (<28><><8A>t<E9>3{<7B>>⦊<><E2A68A>;;q<><71>F<BA><46><B1>x<87>4<DD>Yc<59><07><08><>S<B5>$w<>.<2E><><A0><BD><85>d<97><64>a*k<><6B><A3>|<7C><>Q<16>,<2C><>+x<><78><F1><92>s^<5E><><4B><DFAB><D2><E6>P^<5E><><DC>n<EE>L5m<35>I<AD>wl?-.ʲ<><CAB2><D3><DB>J8 <16>F<A7><01><><C3><EA> <14>B.-:2<><01>Ȕ<C0>!<21><><D0><CE>/A<>#b<><62>_m%<25>I<CC>(<28><0F><>$|<7C>PZ[<5B><><AF><F7>1<A0>G<BD>{^<5E>#<1A><><B5><AE><F2>o><3E>3<D7><33>m<F5>w?'<27>cx<63><78><AC>[<5B>^<5E>:W<>k/<2F>`'=<3D><><FF><><D6A5><C6>W<>(<15>gQ<67><51><8F>bf<62>v7U<37>z<8E><7A>M<E8>3<FE><33><B5><91>+؍<>K<91>:<3A><18>4|G<>Ct<><74>A<>+K<><4B>ʨ<FF>{@<40><><A9>Ɩ <0B>[0<>5<F8><35><ED><F0><FD>E<>|yn4MIEND<4E>B`<60><>PNG

IHDR<01><00><00>ӳ{<02>PLTE<54><45><FF><00><><F9><F9><F9><FF><00><><FF><FF><FF><FD>mmm<00><><FF><FF><FF><FF><FF><FF><FF><00><><FF><FF><FF><F0><F0><F0><FE><FE><FE><F6><00><><FC><00><><FF><FF><FF><FF><FF><FF><DA><00><><C2><C2><C2><F4><F4><F4><FF><FF><FF><FF><FF><FF><F4><F4><F4><F7><F7><F7><FF><00><><B3><B3><B3><FD><00><><E2><E2B0B0><B0><FF><FF><FF><FF><FF><FF><FB><FB><FB><E7><E7><E7><FE><FE><FE><FF><00><><ED><00><><CF><00><><FD><FD><FD><F6><F6><F6><ED><ED><ED><FB><FB><FB><E7><E7><E7><FA><FA><FA><E1><E19292><92><FE><FE><FE><FE><FE><FE><C1><C1><C1><98>ttt<74><74><E1><E1><E1><D0><00><>󻻻<F3><F3BBBBBB><A1><A1><A1><80><80><80><FD><FD><FD><D4>bbb<62><62><FF><FF><FF><D5><D5><D5><F8><F8><F8><DC><DC><DC><FA><FA><FA><FB><FB><FB><E9><E9><E9><FB><FB><FB><FD><FD><FD><FD><FD><FD><D1><D1><D1><F2><F2><F2><FC><FC><FC><F8><F8><F8><EB><EB><EB><FC><FC><FC><B6><B6><B6><C6><C6><C6><E5><E5><E5><EE><EE><EE><F5><F5><F5><FD>eeeggg<67><67>𶶶<F0><F0B6B6B6><E0><E0><E0><F7><F7><F7><FA><FA><FA><E9><E9><E9><E5><E5><E5><FA><FA><FA><F8><F8><F8><CB><CB><CB><FF><FF><FF><84><84><84><F1>xxx<78><78><F7><F7><F7><DD><DD><DD><F9><F9><F9><C8><C8><C8><D2><D2><D2><EC><EC><EC><FA><FA><FA><DE><DE><DE><E2><E2><E2><E6><E6><E6>󛛛<F3><F39B9B9B><A8><A8><A8><A5><A5><A5><DC><DC><DC><EE><EE><EE><FF><FF><FF><F1><F1><F1><C9><C9><C9><F0><F0><F0><FF><FF><FF><FF><FF><FF><DE><DE><DE>Ƽ<C6><C6BC><BC><BC><EB><EB><EB><D6><D6><D6><D0><D0><D0><E2><E2><E2><F9><F9><F9><F4><F4><F4><E2><E2><E2><EC><EC><EC><F5><F5><F5><B4><B4><B4><FF><FF><FF><FD><FD><FD><FB><FB><FB><FC><FC><FC><FA><FA><FA><E6><00><><E4><E4><E4><FC><FC><FC><F7><F7><F7><B0><B0><B0><99><99><99><FD><FD><FD><EC><EC><EC><FC><FC><FC><C1><C1><C1><E9><E9><E9><FF><FF><FF><DA><DA><DA><F0><F0><F0><F0><F0><F0><F5><F5><F5><F1><F1><F1><FE><FE><FE><F8><F8><F8><FE><FE><FE><8E><8E><8E><E2><E2><E2><FB><FB><FB><F9><F9><F9><DC><DC><DC><FF><FF><FF><F2><F2><F2><FA><FA><FA><9F><9F><9F><ED><ED><ED><F7><F7><F7><F6><F6><F6><E8><E8><E8><F3><F3><F3><FA><FA><FA><F5><F5><F5><F5><F5><F5><A6><A6><A6><CB><CB><CB><FA><FA><FA><F8><F8><F8><D3><D3><D3><EB><EB><EB><FA><FA><FA><EB><EBAAAA><AA><F3><F3><F3><ED><ED><ED><A2><A2><A2><CF><CF><CF><DA><DA><DA>֢<D6><D6A2><A2><A2><EB><EB><EB><E2><E2><E2><F9>UUU<55><55><CD><CD><CD><FF><FF><FF><D6><D6><D6><E3><E3><E3><E1><E1><E1><EA><EA><EA><FC><FC><FC><FF><FF><FF><F6><F6><F6><FB><FB><FB><F3><F3><F3><F4><F4><F4><CC><CC><CC><FF><FF><FF><FF><FF><FF><F9><F9><F9><F5><F5><F5><FF><FF><FF><F2><F2><F2><FD><00><><D9><D9><D9><FC><FC><FC><FB><FB><FB><FC><FC><FC>鿿<E9><E9BFBF><BF><FB><FB><FB><EA><EA><EA><E9><E9><E9><FE><FE><FE><FF><FF>rO<72><00>tRNS<00><><0F>#<10><>_
/<2F><><A9><15><03>oS<><53>?<3F><>C<> kD<6B><44><AF>OS_<08><><A0><A5><9A><B2>6<><36>>4!~a <0B>@1<1E>_'o<12>n<C4>ҋ<A2><D28B><91>M<80><4D><86>3<93>BQj<51><6A>p&%!l<><6C>"Xqr;<3B><1D> A[<5B><`<60>am}4<>3/0I<30><04>PCM!6(*gK&YQ<59>GDP,<0E><>`<60>{VP<56>-<19>x<EA>)h<>7<DD>e1]<5D><><F4>W<><57>$<24><>1<18>b<83>zSܕcO<><4F>]<5D><><8F><15>U;Zi<N#<23> ) 86pV<70><56><E0>:h<>#<23>0Z<30>Q<>JN<4A><4E>EDT<44><54>~<7E><>^-IDATx^읇#Ǚ<><C799>b' 4A$Ah<06> )<0E>p<C3>3<86><M<>F9Y9X<39><58>,<2C>r<DB>i<CE><69><9D>ھ<F6><DABE>|<7C>s<9B><73>t9<74><39>s<9C><73>޿<F9>X<E0> k<><6B>jv<6A>@<40>l_<6C><5F>I<92><49>*~h<><68><0E>><14><>'y<>"<22><><80><E2><10><><91>؆<DD>K 64<36>Y<D6>*.v<>@<40><><1F><>c.};<3B><><87>tN%<02>DI<18><><AA><98> !Z<1D>Џ5L<35>H<F1>2<A3>6 <20><1F>ɯ<83><C9AF>"<22> <0B>-b<>E,,)<29>ʏ<00> B<05><><18>>m<19><><B9><AA><C3>n<1C><>6pm<70>R<9F>O
wm@<40><><B0>V<CC>#?<3F>'C<>ȑZ#<23><>q<8E><71><18><>b<><62>|$<24>:<3A>)<29><>/E<>%<25><>nR<>q<B9>C<97>hn<><6E>%<25>i<F5>̓<D3><CC93><AD><BA><B6>}l<>m
?i<>d<FF>d<E2>"<22>,<2C><19><16>`<60>H<AC>"r.z<><7A><A1><BC><8B>~<7E><><FD>(b<>Q<F0>U&<26><><1D>)<29>5<96><35>X#<23><><95><A7><14><>EM<45><4D><AA>R<<3C>*p[<18>[%.<2E>O<A9>̣<C9><CCA3>k7<6B>lIo<49><6F><03><><A8><FD><93>J<DF>F<08> <0B>lV!̡ăuH<75>`<60><03><><BC><99><80><13><03>&<26>,<2C>z<16><>Rk$<15><><11>|$<24>l<F6><6C><8A>Xb<58><62><FC><A2><E2><6A>dU<08><>?Σ$H<><48><B5><19>W<A9><57>$U<>'<27><1F><>H<C5>E3*խ<><D5AD><BA><80>U\}<7D><><EA><FD>(<28>
<18>zhVk}g<>u<C7>Rk$<15><>%<25>|<7C>T<89>|<7C><>ck<63>獳"<10><><E3><9E>D<B1><44><E7><1D><>_W+<2B><><8B><AE>.Q<><51><F2>)<29>@<12><><AB>ƽ<93>H<08><><A2><C0>b<CD>s<04><>l<D4><01>T<8E><54><B4>D<B7><44><FF>R<04>2Xm<58>#a <0A><><DD>3lY<6C><59>z<CE>j<CC><6A><B9><8E>㒚#!<21> 4<>J<><4A>8<C4>(<00><>c<F2>v<><76><99>t]<5D>a<><61>T<98><13><01><> <09><><D2>D ΅<><CE85><E0>Q?^-<2D><>_^$:\<5C><><FF>V <09>$<24><>N|<7C>=(v<>Z'q<>6<8F>Z<B9>׆<F0><D786><87>B5V<35><56><EC>!y<><79><86>3<BC><33>K<DF><4B>㱿b<E3B1BF>v4<76><34>x<><78><F0><EB><11>R]al<61><6C>!<21><>I<FE>o<DB>P<87>@<40>t<C5><74>Vy<><79><94><11>L<E0><4C>٪ml<6D>ڿI<DABF>Ub|[*<2A><>lke'*<2A>Wd<57><1A><>d<DD><64><E0><18>D<EF>ӝ}\W<><57>_Wߝ<57><DF9D><B4><F9>r<A4>N<D0>?<3F><><99><1D>۲X%<25><>0u<30><75>oui*<2A><>JV<18><>Ʀ<80>b%<25>}<7D><><17>i5I<35>YlN<6C>E-w<17>ς<D0>f_W3m<33>I<><49><E5><E0><85><C4><FD><93>-<2D>m<8C><6D><18><>Q)<29>S <0B><>k<D6><B4>TC7<><37>m<><"<22><>܌<F4>b<87>T|<7C><>'<27><>$<24>Ҙ<B5><D298><9F><A3><F3>R&><3E><>O p<0F><><9C><F5><BA><9A><BE><F9>6<EA><1E><16><><0F><><E7>t<BD><74><B1><A8>S<A5><53>N\<5C>ׯL<D7AF><4C>m<EE><6D>\<5C><02><12><><D1>r@<40>3<>u<9E>T
b7<FA><D3>t.5.q<><71><A9>3<C8>r0<72>=<3D>8T<38><54><><7F>i<AA>J<AD>\<5C><>6uF
<94><B2>R<B8>32^<5E><1A><><><C5AA><8A><F3><0E>x<B1><78>I<E2> <09><>F<D2>8O{%8<><38>kJ<6B><4A>MS<4D>ȴd<>BEd<45><64><E6><D1><E8>W<EF><57>CY<43><59>O:/O<>N/<2F>I<97><10>_=<3D><>xFE<46><45>! <20>=<3D><>i:o<>~<1B><><92> y<>?<3F><>'<27><>'<27><>[͓[͓[͓[͓[ͭ<><CDAD><96>.<2E>U><3E>$<24>P<F7>Ʀ<96>c%<25>]<5D><>\c<><63>:<3A>| <09>,e<>S<AF>Z,<2C>o<91><6F>Xr<58><72><ED><E4>X<CB>!<21>R<EB><52><16><><0F>@<40>Z<E1>v<F8> <07>0<87><30>>?<3F>*<2A><> <0A><<3C><><F0>|<10><><14><>N6<4E>0<FE><30>;{<1D>a<>d<><64>2<05><>v+D<><44>^t<><74><E0><E0>[q!<08>۞V}<7D><>f<F8><66>ۨϏ<DBA8><CF8F><8E>Y<D7><59>eॗ<65><E0A597>)Vy<56>l|" f<>U<F7><03>q<B2><71>@<40><>Ǽ<88>4Y-<02><1A>Y<B3><59>-!<21>6a<36><61><93>B:o%<25>J<><4A>I<><49><B1>UQ|<7C>U<A3>K<C6>O<04>`<60><>=\ <0B><><12><>:<08>0<EB><30><BE>x <16><>Pa<50><61><F3>u<CC>@<40><>!<21><>K<BB><4B>P<>d<CF>xhw1><3E>$j΍<6A><CE8D>v<17><>Zd<5A><64><10>x<99><78><F1>S<D5>UA<08>&[UR<01>d<DF><64>7<FD>ø<F0><C3B8>z<C2>k<B7><6B>/<03><><04>r<F0>U^<07><><AC><1D><><A0><A3>w:I.<2E><18><><EB>c>q<71>.!<13>zS<7A>r&<26><><AB>2<D5>)Wg<57> <09><>R -<2D>i<CE>Q 8<><38><BF><E7>Pa\О<>U%<25><69><DDA1>U<10>_=<05><>p<><70> <1C>Lu<4C><75>(<28><>N<>?<3F><><86>0?<3F>Æ:]<5D>ά<BD><CEAC><E4><14>t<CF>B%<25>U|<7C><><99><FA><F9>NsorN<72><4E>f<B9><66> <04>,<2C>P !<12>v"
Y<AC>6<BC>hL<EF>_<AD>@@<40>b<85><62>s<11>c<03><><B6>qg<1A>v4|<7C><>|0lϟ<6C><CF9F><D0>$S<><53>9<F5><39><8D><8E><62><CAB1>j#<23><><8E>~<7E><><9E><83><C1>?o<><6F>}<1E><><91><91>}7sAPm:IV<49>=n<><6E><95>
!<21><><F4>{<7B><>{<7B><>h<DD><68>Eࢪ<45>8<01>s<00>u<00><>oL<6F><18><>T<C8>$<24><><F1>;V<><56><DD><FA>s<1B><>cq<63>D<07>3<A6><33><F0><F8> <0C><07>3.D<06>B<AB><14><><AB><E9><FD>B4<00>&<26>V'<27><> T<1D> `<60><01><>D<BD>6<><36><FF><99>Ϸ<9A>q<F3>y<FD>j<F9>8V<38><56><9D><89>*<2A><><03>X%<25><><04>@s<>\<5C>jrN<72>$<24>|<7C>=5<02>Ά '<27>mU<6D><14>i<AB><69>K<AB><4B>i<02>%C<><43>I<C9>:ssaƅ`*`<60><1D>=<19>l<FA><6C>)><3E>u՘MeuS<1B><><9A><9B>I<A8>_<F2>O<CE><4F>L<88><4C>_<A3>}<7D>o&<26><><1C>jz<6A><7A><FF>p<><70><9D><E8>{<02><><A8><A4><D6>lu<6C>:O<><4F><F1><C1><AE><AB>)<29>s<AB>%Q@<40><>$<24><]f<> <12><>xO%<25><>PCbhr2<72><32><A3><D5><F4><00><><BC><9F>PK<50><4B><B7>p<EB>f5<66>Në3^o<><6F><AB><F9><A9>]<5D>e<EA>J<B2><4A><CA><EA>i<A4>B<D0><42>464<13><>^t<02><EF><7F><75>U֌:G4'<27><><BF>22Y<32>p<EA><70><CE><EB>u<CC>G'/Py<50>4?<3F><><A1>.<1D><>SB<53>P_><3E><12><><1B>I 1t3Γ<33>B<F7>ɭ<E4>ɭ<E6>ɭ<E6>ɭ<E6>V<E6><56>V<E4><56>V<E4><56>V<E4><56>Vs<56><73><06>]<5D><>!<21>67(<28><>g <0B><><AF><A4><A5>y<8A><79>@<40><> 4>Q<><51> <20><>V<D5>F<AB>}^Xׇ<58>ڼ<EC><DABC><88>j<D5><6A><1E>e<16>26 L<><4C><9E>%<25><>Y<F2>G<B4>h <0B><><FB>l<1A>C<89>}<7D>)<29><><
<88>!<21>E<DA><45><A0><F4>E<C7>P<BD>ZWZ<57><5A><99>V+<11>@†<10>R 5{@ou<18>ɐ<C990>4<><34><15>&<26><00><><84>H<B4><48><01>6<AC>e<F7>y V<13><>݀<03><56><C5A5><D6><C1><12>cqZ<71>ޒ<84>r<A9><72>J<><4A>yB<79><42>y<07><><11>Fz<46><0F>FN<>$<24><10>Hb<><62><C8><10>*+<2B>jՏq<D58F>э<F2><D18D> ګ<1D>kݿU<DDBF>X<E0><58>l<>e<01><02><><EC><C4><1F>1<C4><31><93><1A>d<08>0d^<5E>-<2D>B%<25><><89>}<0F> <0C><><9C>{Y<><59><17>%r<>*<2A>j5Ak5<6B>u<10><>"<22>,<2C>:~<7E>Ҹ<E9>Y<E1><59>~
h<99><F7><FB><03>SA<53>~<7E><>6<1E> <0C><>fu<66>lՇf<D587><66>{ȵQtATH<54>Z<D0>k<1D><><C0>ƭ/_<><5F><B0>S<D5><53><9F>n<BC><6E><E1>
<B1>u']b<>]|m`<60>B<AB><42>ā<F1><C481><C1><CF>J,O$<24><>du]<5D>Zs<> <0A>FL<46>:<3A><><A9><C4><F9><FA>a<9B><61><F5><F8><8B>Ǚ<8B><0E><>T4<54>o<CF>~by?wp<77>j滥<6A>A<D6><41><9C><81>(<28>x<80>]<5D>†<10><><A6><FA>f<AA><66><D5>~an֧/<2F><><9E><A9>^<5E>d<C8>ڲ<D5>c<1F><><D8><00>Շ,!<21><16>1<D0><31>i&<26>xi_VK@ip<69>̓9<03><><AF>Vi%a; <0B><18>L?<3F>0J<1F>*<2A><><B9>Ū5<C5AA><1C><>U<B8><0F><><B7>'<27><><C1>x^<5E><>6<1E>V[<5B>^ <16>{<7B>eU<65><55><99>|<7C>:0<>=0<><30><87>d۫o<DBAB><6F><10>*J<1F>q%<25>[<5B><><AD>Y<F5>N<C3><4E>.sQ<73>L<84>ud<75>[2<><32>9<>I<FE><49>:W<>n<C1><6E><97><D4><C8><FF><12><>m<1E>Xl<>ڃ<A5>6<>!l<>Nl<4E><6C>V<D9>էKU<4B><55><BC>jV<6A>\J%<25>Uߊ<55><DF8A>B<DF><42>LcKf<17>b<E1><15>>a<1A>=<3D>b<D2>~<1F>R]aG%[<5B><><9D><FA>js@<40><i<>[Х*^.d;UI<55>R+<2B>OD<>2e<32>ܶ<CA> <20><>Q<A1><51>N3<4E>4"1<><31><A3><1F><><D2><F8>g<E8>0<A3><30><E0>u<16>\<5C><14>I}<7D><><DC><C1>wFV<46><56>4y/D<><44>j<DC><6A>j<DC><6A>jn5On5On5On5On5<6E><35><B7>h<B6>,ҷUr<55><72>]<5D><16>]L^<5E><><BF><97>%J<><4A>D<BB><44><83>iɭ<><C9AD>G<>ԝ ߴ<>/<00>%='q<>å)<29><><C8><D9>:<3A><>Q<8F><<3C>X<BF>.<2E><>'<27><><F4>[<5B>@<40>P<12><><9F><01>v<C4><05><><B0><A1><88>>/9<>MطݘU<DD98>>yɲX<C9B2>@}<7D> <0A> <0C><>F<EB><46>t<01>g^<5E><>vO\<5C><>Ӹwv<77>p<82><70><1F>z3<7A><0F>K5i<05>!$P><3E>ā<94><02><><80>'<06><11><56><C69B><AC>L<A2>2r<18><>@<40>UM<55><4D>K<C9><4B>Z<FA><5A><AF><F5><89>6<1B><><05>tw<74>맟¦b<><62>m<84>1<DF>h|<7C>|<7C>]}~<7E>0<1A><>MjA<00><><A2><02>(J<><00><><8A><DD>JP68<07>C&yr<79><72>׉e}<7D>j<1A>_c<5F>J<CB>?<3F>I0<49><30>k<AF><6B>>š<>W<AB><57><1E><> <09><><C6><FB><8B><99>|<7C>B<A1>ޝ<BE>."TEXd<58> <0A> <0C>8<D4><38>!cw<06>*E(<06>J)<29><><CA>!<21>[W"<22>j_<15><><D4>ТeX_<58><5F>XB;<3B><><1B>o<AF><6F>O0~?<3F>:P<>C<BD> (.<2E><><B2><ED>[<5B><11><><8E><91>!Wq<57>%<25><1D>*le<6C><65>Y)E<><^<5E>K<88>Z<E5>T<B9>60<36>.<2E><><F0>#<23><><AB>A\<5C><><FD>5;Rm<52>tkd<6B>/8<>)5~<7E><><82><BF>^0<> #<23>Ckg<><67><06>e<><65>y)<29><><8D><B2>Ͷ<B1><CDB6>Ժ<91><00><36><<3C>(?<3F><>&<26><><C9>u<75>A<EE><41>V<E1><56><9F>m0^h<12>.<2E>t<1E>xR*<2A><>a<D7><61>'<27>:,<2C>H<A5>|<7C>ō<><C58D><96> l5z<35>;8+e<>#b'#|<7C>}2<>w(|Kc<4B>J<96> <0A>l6 <0A><03><><80><B6>w<AE><77>^<5E>Տ<82>o<8C><18>i<97><69>3H<> <0A>R <18><>̔9<>,Y<>gP<67>ְ:N <0C>[5S<15><><C3><F6>R<89><52>!<21><><A2>[)<29><>]<16><><80>i}`<00><><FA>m<BA><1D><>N<B8>4Х<34><D0A5><B9>v<E3>`|;f<1E>(<28><>F<B4>lt<6C><04><>L<A2>8<D4><38>÷Z#<23>AO%<25><>Y)N<>U<B9>5Y<35><10>e<D1><65>d<BC>J<96>E<0F>3dZذ<><D8B0><92><<3C>x<C8><78><B7><C7><F1>ɝ<03><><F1>e <14>@<40>Pڧ<><0F><>F<CE>TR <0A><>2S<32>·<A1><C2B7>Φ/u<>Z<88>~<7E><>C<9A>3<><33><8D>X<D4>z<CA><7A><BC>U<0F><><0E>x<E2>\2<>s<8D><03><><F1>e <14>D<95><44>D.<2E><><E7><8D>fBO&en<65>'i<><69>R%<25><06>?Fy<46>VsS~$u<><75>m<AE><6D>w()<29><>r<B4><72>o<>0*D<><44><81><ED>i!3<>:On[B<>!sʇB<CA87>p>ݣHT<48>1<D9><31> ;<3B>8M<38>jnʏ<6E><0E>Ӥ<91><D3A4><EF>qp<> 1h<31>^<5E><<3C><><<3C><><<3C><><B9>j<DC><6A>j<DC><6A>j<DC><6A>j<DC><6A>jn<6A><6E><D5><DC><DF>q<96>(qp<71>Ok<4F><6B><AA>}<7D><><B8>I?TY8H<38><48>mh<6D>yK<79>̝u5<75><35><8F><CD><07>I<CE>t<9C>e<F7>nQBޗ`<60>R<B5><52>`<60><1A>E<B7>P<C0> <0A>ڦ<AD><DAA6><F6><98>x<><78><0F><><AB>><3E>><3E><><12><>yt<79>{?|<7C><>'j)<29><><94><02><>}YU<59><55><DB>U<><55><F9>{<7B>@V<><56>/<2F>J1<4A>F+<01><10><>7䀉[OW<4F>O[<5B><> <18><><F8><B9>y<89><79><8D>UY<55><59><1F><><AA><95>!?B<><42>D%<25>D<><44>Wj<57>>-Ai6x<36>z)<29><><BB>U R<><52><BD><F9><AA>7 d<><64><1A>@<11>g<B5><67><11><><EB>\<5C>so<73>)<14>a<9C>4<CF>zf<1C>[<5B>W+<2B><><81>><3E><><B9> <0C><>P<FF><50>><3E>
|<1F><>qL<71><4C>G8<>v<8F><76><E2><B8>ȣ<EA><C8A3>l<98>j<B4><6A><90>2Z<32><11>t<C6><74>+<2B><15>V<8C><56>A<D4>6g<<3C>/<2F><>Q <10>H<08><>SrΣ<><CEA3><1A><>d}<7D><>Y<F9>q<8F><71>g]<5D>sY]<5D>;]F<>C<0E>@5<08>Y<BC><59>Ֆ<D3>5<8D>C<CE>3<A9>8o<38>)k<>1'<27><>d6<64>>T *<2A>ʆ<CB><CA86>Uz(<28>m)<29><><FB>CD `<60><>He/<2F>.<2E>:<3A><>zN<><4E>9pgo &N<04>C<9D>׃<A6>އ<8C>><3E>W<B6><57>հ_<D5B0><5F>Hj<48><6A>)<29>Xe6F<36><00>7p<37>m<92>-<2D>`'<27>c<D6><63><86>.<2E><0F><><AB>AZ=<14><><8D>^<5E>e8<65><38>F<C2>;<<3C><><9D><CB>J1{<1D><><F3>+8'<27>ɪ'<27>և\A<>*<2A><1E><><D2>[<5B> <0B><>R$U<><55>Y)V<> <0A>AyɃ<79>w)<29>Ec#<<3C>T<D5><54><87><83>\vW<<3C>U1<55>CDo<44><6F>Yo<7F><13>]<5D>wm<77>aw<61><77>:B<18> :'<27>Z+<>v<17>}<7D><>|<7C>0<1C><>q<><71><86>1<>P<8E>΃<AA>*<2A><>u<03><>T<8D><54>7 <20>F3<46><33>9<B1><39><BD>A}$<24><><81>f<E5>+<2B>o<EE><6F><8D><07>[<5B><><C5>I<BD>5<14><>ʰ<F7>޽x(&<26><1F><13><>i<00><>ʼY<><03><>:c<>Pp*<06><>b<><62>¸J<><4A><88>j<91>V7l<>jtsNk<><6B>v<9C><76><97><CB><07>[<5B>fy3<79><33>g]<1B><><EA><F7><F7><82><F5>u<BE><75><9C><15><0F><><B9>g<E6>J<E7><4A>E<8C>0)Vił<69><C582>ù<A2><C3B9><E8><C1><83>\vW<<3C>Ug<55>t<04>e<A7>~B<42>[<5B><><10><>A<E0><0F><><86><89>H<D9>J<1B><>'<27>.<2E><>n<><6E>& 1Ԕ<31><D494> <09><>o%gͱ_<><5F>N<10>
<A6><9B><94>5<EA>.W<><1A><>3y/D<><44>d<EF>yr<79><72><AB><<3C><><<3C><><<3C><><<3C><><<3C><><B9>j<DC>ܪ{<7B><><95><BE><AD>waw<61>:6<>dJ<64>;&<26><><08>3<ED>p tl<74><6C><8C>as<08><><1C><><9F><B2>W_U<5F><55><DF>T<C4>_'9{?<3F>a<F0><61><AB>Ԭ<><D4AC><C3><C4>l/0<><30><AB>dHgqll<6C>c<B1><63><E6><FF>8<CF>R<C4>y<82><79><16><><80>m=ˢ<>_<9A>ͺ<8C><CDBA>[Է71<37>x"<06>"<22><14>S<C6>IfV<66><56>r<FB><72><F1>x3<78>3y<33>)h<68> <0A><><D4>h<C7>ՠ<CC><D5A0>0<88><30><8B>?<3F>r<D1><72><D9>5<>x<97><78><9A><FB><B0>_<FE> -<2D><><DA><C6>j<C8><6A><D5><F5><03><><19> <0A><><F5>чoO:<3A><>$<24><><9B>XBXJ<><4A>ѣ<EA>1<90><31><1A><><E3>#ֈu7<75>`<60>zu2<75><32>{<7B><>\;<3B><><75>9@<40>0<A8><30>V$2X<32><58><9D>S<9B><53><DF><F8><E2>&<26><><FA>Ba<><61>[<5B>O<EF>~<7E><>j<D1>N2ߠȪ/<2F><1E><><8E>jz_<7A><00><>nA<><41><01><><DE><E9><7F><A7><BF>~<13><> <0B>u<DA><08>h@GL<47>O<FC> <0B><>?T<><54><05>f<V<><56><85><98><F7>e<D7><65>@<40><><B5>*<00>-}<7D>e<F1><06>@<1F> <0A>0Zt <0B>/~<7E><><BF><86><9D><BC>Xm0<6D>*<2A><><E6><8E>*<2A><>H'\<5C><><01><><AB><AC><B2>u<AC><75>S<EB>E<EC><45>m<02>Lֻ<><D6BB>6<D1><1F><><B3><D0><E5>;+{l<02><><19><><AF><AB>?u*<2A><><A9><99>_<><5F> Ni-:<3A>I@,;<3B>]<5D><><FF><D3>W<C9>Y<B2>` *<2A><14><>߀n<00>SO<53><4F>~<7E>n<8F><6E><E7><B6>W<E4>P<FD>.<1E><>c<><63><FC><12><>Z<B0>T<1E>u<C4><75><A7>Po^ǃ7<C783><37><F3><E3>w<FC><17>B<89>RB<52>W<E3>_m<5F>dj<64><03><><18><><85><D8><FD><87>B<11><><DE>6<FF>:<3A><>*<2A><>H<DA><48><17><01>]<5D><><FF><B3><E8><A7>d<CC>Q><05>{R<><52><AD><AE><AB><C9><EB><C9>t<BA>n(<28><>z<CF>!S<>7o
<D7><EF><04><>Ie<49><65><AE><8E>w<00>3]<5D><><62><13><>8<C7>5|<7C>i<C6><69>Ϡ<9D><CFA0>R<EA><00>JkʱZ<CAB1>RO+<2B>8<>U&<26>:]<5D>Z<95>ieR<65><52><89><1E><I<><49>~<7E>|<7C>d<D1><64><95>,<2C>j<83><6A><F5>{<7B><10>;<3B>7<C3><37>U<00>݌<E8>X<CF>B<7F><42><88>`<60><><9D><D1><F8>[<5B>u5~<1F>=z<>q굵Ű<EAB5B5>޹e<00><><CB>b<BC>c5<63><35><FA>o<C9><6F><D6>{;<3B><><D1><EE><F6>ߩ<80>@;<3B><><02>n*T<> ĵ2<C4B5><><DCA8>0<8A>'<27>Y-?
<95>j<93>[<5B>Z<E5><5A>j<EB><6A><B5><C0>ӭ<81>v<BA><76><FF>i<E7>-<2D><>*rD{<7B>mL-,L<>=<3D><>y<15><>m<9F><1A>x<1F><><8B>c:<3A><><B1>We<57><65><F5><CA><76><D2B1>ń<>
<C0><BA>"dF<64><46><C9><D8>8[<5B>T}ӵF<1B>-<2D>I<F9><49>V<DE><56>lV[P<><50><C1><97><B3>)DV C<>8ݪ}|kZ<6B><5A> <0B> <0C><><06>{<0F><><B1><95>Y<C9>|<7C><1D>xrr<72><72>xa<78><61><F2>G_<47><5F><D4>><3E>(<28><>J<F3>M<CB>ޗ7<DE97><37><1C><>Z@<14><>5<B2>a^<5E><>\G<>z<98><7A>s<AF><73><AA>ρU<CF81><55>*<2A>rM<72>e<CF>zT<>^<5E><17><>ͦX=><3E>$
bi><3E>U&X<>Qoybb<62>G<B9><47>k<F8><07>8<CD> <20>
<C5>Ҙ<17><><F3><8D>n).Ս<><D58D><A4><F2><9C>o<> <11><>^M<>m<0E>d<E1>Z<B3><5A><83>i<F3>$s<><73>o<AA>o<96><6F>*{<7B>4<BB><34><EC>eLb<4C>Lٳ"<02>"mx:<3A>`:m<>k<C9>[<1B>geT<65><54><15>ެ)<29><><9D>'0*T<><54>B<9B><42>{!<1C><>I<EE> <0B>'<27><>'<27><>'<27><>'<27><>[͓[͓[͓[͓[]<5D>Z<98><5A><88>j Q<>.e<> '/<2F><>y<AE>vQ<76>71<37>(Z&<1C><><86>X<D2><58>?(_<><5F>Z<9A><5A><94><03><>){t<>ڀm<DA80>Z<><5A><ED>W<C0>Ϗ<D1>)<29><>-C<><01><15><><D3><F2> jq<6A>n<E1><>"<22>Iv<49><76><8B>UL<55>!h<><68><A2><D9><EA9BBF><EE><F1><A9>s<DD>k<E7><6B>AcrN<72><4E><82>佚ф<E4BD9A><D184><80>VE4<45>0<F6>y<FA>X<98><58>~<7E>4zʸV㳰%<25><>,<2C><><E9><B9>)f<15><><F8>qt<71>p<C3>u<98>~<7E>  <0B><><DE><F8><8D><A9>*<2A><><FD>^<5E><>0:<3A><><E5><FD>ܲ<E9>3<F6>3<FF><33><0F>J<CF><4A>O<>(<28><1B><><B7><F6>ZB?K<>^ <20>v]<18>un<75><6E>l<><6C><E7><FA>W<F4><57><1F><03>i0<69>p6<70><36>[착<>C_5X<35>#<05>[<5B><>wX3<58>b<E1><62><CE>R<C4>{<7B><><F9><CE>NK<4E>A<41><7F><EE><05><>e S<><53><AB>e<D3>|<7C><><1B>w<B9><77><F1>x<C7><78><E2><BA>s<DE><73>o><3E>P\儔ԕ6<D495>;nV<6E>m<>f<AF>I$<24><><E0><13><>V͓J-<00>J%֌<><D68C>0<8E><30>Uw<55><59>S<C9><53><0F><>n<>u<91><75>m<D2><FF><E897AE><C6>xz<78><15>˗V<CB97>ƫ<9F>I<DA>vn<1D>W<F4><57>_<DA>qL<71>Z<9D><5A><D8><C7>"_<>X<97>z<AE><7A><1A><> 8<>]Ap<41><70><97><89><83>?<3F><>C<B6><17><00><><8E>5<9E>4<C8><34>3<B7><33>zw(<28>{7e<37>*Ȳ`۰<>!A<>Q<D4>:<3A>KUn<><6E><08><><BF>z<14>]<5D>1y<31>V<86><56><84>Ga<47><61>C<FA><43>m0<6D>PY
ٚUx6TT&<07>hV<68>9V<18>
<FE><EE><DF>Ӭ<9E><A0> 1[<5B>X<F7>z<AE>Z<87><5A><9C><CB><D5><10>9<D0>e<AA>r<A2>q<9B>J<F3><4A><B8>ND<4E>/<2F><><F9>g<B9><67>X<FE><58>*9o<39><6F><97>N6<4E>D<AB><44>` <0F>{<7B><><E0>I<AA>%<15>M<CB>z9—<39>T<1E>Q<FB><51><8E><9F><E0><96><88>7f<>\"j<><6A>_3<5F><33><D9><FE>~xB<78>'<27><><80>ܷ<F9><DCB7>Y<88><59>]*KЌ<4B>%"<22><><FA>5<E7>"<22><>qxq~<7E><11><>ƕ=<3D><><05><>j<A8><01><>S<BA>>j<18>V<A4><56>&~]2<>xz<1B>F<C0><46><8F><B8><D5>1X<31><58>_y<12><>D<06><><#N<><4E><92><0E>RB<52><42>}K<><4B><F4><CF>/<2F><><9D>i<1D><>y<8A><79><86><F9><BF> !V^<11><>˿e<CBBF>J<B2><4A><1A>}/Fk<46><6B>A<F1><41>7<FA><37><9F> <20><>S<><53><A9>+.<2E>(ec<><63><8D>J:<12>z<98><7A><F0><83>W<F3>Z<08><><9A>몖w<01><><EF>Q<D9><1F><><FE><1B><12>~a<><61><DB><D2><EA>̈́<D8>p<F6>6,e5<65><35>,<2C>+<2B><><A2><96>,<2C><><FD><FB><1F><><AD><1B><>t<FF>v<B1>%O^O<><4F>O}<7D>ן -O<><4F>7>e<><65>kC<6B>6<13>wa<1D>_<F4><5F>C<7F> <0A><>|<7C><><08>9<9B><39><91>*<2A><><95><1F><1C>W<><57><C6>A<B8>)<29>U<D7>Jg<4A>8<<3C>Z<FD><5A><80>x^?<3F><><84>2<BE>u<B2><75>Y<AD><59><FD><ED><B3>*^?<3F><>ڇKC<4B>Z<>[<5B><><82><FF><A9>0.<2E><><92>C<E0><43>@m<><6D><BE><E7><11>$-<2D><>/~<7E>|<7C>Y<8F><59>[e<>w<10>eQ<00><><FD>׶&c<><0F>O<CA>4s|<7C><>c<9C><63>J<A7><4A><E5>ws<77><73>X<>8/<2F><><F1><9A>6<CE>/ ڼ;<3B>'F<>LN^<19>8]<5D><1A>ead<61>Z 1'<27><><00><19><><1F>^<5E><04><><DA><1A><><FB>L<87><1E>sBd<42>%<08>+M<><4D>`<60><>SK<53><4B><38><D7A4><B2><F7><AB>*<2A><>)gl<67>#<23>3"<22><10><67>S <19><><14><><8B>qtcxx<78><78>|H><3E><><96><AC>=<3D><18>:<3A><><04><13><>m<CE>j<CA><6A><D5><E5><AC><DF><FF>U<D5><55><DF><F2>v<F3>q<A3>y<EC><79>s<8F>ܒ<A9>Lgl<67>C6+[F<>SWg<><67><85>9<93><39><F5>wV3<56>1<BC>A <09> <0C>N<8F><4E>D<DF><<3C><><CD><FB><AB>$5e<35>(s<><73><84><FA><8D><A1>[<1C> ۨb<02><><FA><97><B3>aF.<15><>]<5D>K<B1><4B><A1>IEND<4E>B`<60> <tr>
<td class="{classes_level}">{name}</td>
<td class="{classes_level} big">{classes_bar}</td>
<td class="{classes_level} small"><div align="right">{classes_tested_percent}</div></td>
<td class="{classes_level} small"><div align="right">{classes_number}</div></td>
<td class="{methods_level} big">{methods_bar}</td>
<td class="{methods_level} small"><div align="right">{methods_tested_percent}</div></td>
<td class="{methods_level} small"><div align="right">{methods_number}</div></td>
<td class="{methods_level} small">{crap}</td>
<td class="{lines_level} big">{lines_bar}</td>
<td class="{lines_level} small"><div align="right">{lines_executed_percent}</div></td>
<td class="{lines_level} small"><div align="right">{lines_number}</div></td>
</tr>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="{charset}">
<title>Code Coverage for {full_path}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<header>
<div class="container">
<div class="row">
<div class="span12">
<ul class="breadcrumb">
{breadcrumbs}
</ul>
</div>
</div>
</div>
</header>
<div class="container">
<table class="table table-bordered">
<thead>
<tr>
<td>&nbsp;</td>
<td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
</tr>
<tr>
<td>&nbsp;</td>
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
<td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
</tr>
</thead>
<tbody>
{items}
</tbody>
</table>
<footer>
<h4>Legend</h4>
<p>
<span class="danger"><strong>Low</strong>: 0% to {low_upper_bound}%</span>
<span class="warning"><strong>Medium</strong>: {low_upper_bound}% to {high_lower_bound}%</span>
<span class="success"><strong>High</strong>: {high_lower_bound}% to 100%</span>
</p>
<p>
<small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {version}</a> using <a href="http://www.php.net/" target="_top">PHP {php_version}</a>{generator} at {date}.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
</body>
</html>
/*!
* Bootstrap v2.2.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover{color:#808080}.text-warning{color:#c09853}a.text-warning:hover{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover{color:#2d6987}.text-success{color:#468847}a.text-success:hover{color:#356635}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success td{background-color:#dff0d8}.table tbody tr.error td{background-color:#f2dede}.table tbody tr.warning td{background-color:#fcf8e3}.table tbody tr.info td{background-color:#d9edf7}.table-hover tbody tr.success:hover td{background-color:#d0e9c6}.table-hover tbody tr.error:hover td{background-color:#ebcccc}.table-hover tbody tr.warning:hover td{background-color:#faf2cc}.table-hover tbody tr.info:hover td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999}.dropdown-menu .disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret{border-top-color:#555;border-bottom-color:#555}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media .pull-left{margin-right:10px}.media .pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}
/*!
* Bootstrap Responsive v2.2.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/@-ms-viewport{width:device-width}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}
body {
padding-top: 10px;
}
.popover {
width: 600px;
}
.table td {
padding-top: 3px;
padding-bottom: 3px;
}
.table-condensed td {
padding-top: 0;
padding-bottom: 0;
}
.table .progress {
margin-bottom: inherit;
}
.table-borderless th, .table-borderless td {
border: 0 !important;
}
.table tbody td.success, li.success, span.success {
background-color: #dff0d8;
}
.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
background-color: #f2dede;
}
.table tbody td.warning, li.warning, span.warning {
background-color: #fcf8e3;
}
.table tbody td.info {
background-color: #d9edf7;
}
td.big {
width: 100px;
}
td.small {
}
td.codeLine {
font-family: monospace;
white-space: pre;
}
td span.comment {
color: #888a85;
}
td span.default {
color: #2e3436;
}
td span.html {
color: #888a85;
}
td span.keyword {
color: #2e3436;
font-weight: bold;
}
pre span.string {
color: #2e3436;
}
span.success, span.warning, span.danger {
margin-right: 2px;
padding-left: 10px;
padding-right: 10px;
text-align: center;
}
#classCoverageDistribution, #classComplexity {
height: 200px;
width: 475px;
}
<tr>
<td class="{lines_level}">{icon}{name}</td>
<td class="{lines_level} big">{lines_bar}</td>
<td class="{lines_level} small"><div align="right">{lines_executed_percent}</div></td>
<td class="{lines_level} small"><div align="right">{lines_number}</div></td>
<td class="{methods_level} big">{methods_bar}</td>
<td class="{methods_level} small"><div align="right">{methods_tested_percent}</div></td>
<td class="{methods_level} small"><div align="right">{methods_number}</div></td>
<td class="{classes_level} big">{classes_bar}</td>
<td class="{classes_level} small"><div align="right">{classes_tested_percent}</div></td>
<td class="{classes_level} small"><div align="right">{classes_number}</div></td>
</tr>
<tr>
<td class="{methods_level}" colspan="4">{name}</td>
<td class="{methods_level} big">{methods_bar}</td>
<td class="{methods_level} small"><div align="right">{methods_tested_percent}</div></td>
<td class="{methods_level} small"><div align="right">{methods_number}</div></td>
<td class="{methods_level} small">{crap}</td>
<td class="{lines_level} big">{lines_bar}</td>
<td class="{lines_level} small"><div align="right">{lines_executed_percent}</div></td>
<td class="{lines_level} small"><div align="right">{lines_number}</div></td>
</tr>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="{charset}">
<title>Code Coverage for {full_path}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<header>
<div class="container">
<div class="row">
<div class="span12">
<ul class="breadcrumb">
{breadcrumbs}
</ul>
</div>
</div>
</div>
</header>
<div class="container">
<table class="table table-bordered">
<thead>
<tr>
<td>&nbsp;</td>
<td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
</tr>
<tr>
<td>&nbsp;</td>
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
</tr>
</thead>
<tbody>
{items}
</tbody>
</table>
<table class="table table-borderless table-condensed">
<tbody>
{lines}
</tbody>
</table>
<footer>
<h4>Legend</h4>
<p>
<span class="success"><strong>Executed</strong></span>
<span class="danger"><strong>Not Executed</strong></span>
<span class="warning"><strong>Dead Code</strong></span>
</p>
<p>
<small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {version}</a> using <a href="http://www.php.net/" target="_top">PHP {php_version}</a>{generator} at {date}.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">$('.popin').popover({trigger: 'hover'});</script>
</body>
</html>
/*!
* Bootstrap.js by @fat & @mdo
* Copyright 2012 Twitter, Inc.
* http://www.apache.org/licenses/LICENSE-2.0.txt
*/
!function($){"use strict";$(function(){$.support.transition=function(){var transitionEnd=function(){var name,el=document.createElement("bootstrap"),transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(name in transEndEventNames)if(void 0!==el.style[name])return transEndEventNames[name]}();return transitionEnd&&{end:transitionEnd}}()})}(window.jQuery),!function($){"use strict";var dismiss='[data-dismiss="alert"]',Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.prototype.close=function(e){function removeElement(){$parent.trigger("closed").remove()}var $parent,$this=$(this),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),e&&e.preventDefault(),$parent.length||($parent=$this.hasClass("alert")?$this:$this.parent()),$parent.trigger(e=$.Event("close")),e.isDefaultPrevented()||($parent.removeClass("in"),$.support.transition&&$parent.hasClass("fade")?$parent.on($.support.transition.end,removeElement):removeElement())};var old=$.fn.alert;$.fn.alert=function(option){return this.each(function(){var $this=$(this),data=$this.data("alert");data||$this.data("alert",data=new Alert(this)),"string"==typeof option&&data[option].call($this)})},$.fn.alert.Constructor=Alert,$.fn.alert.noConflict=function(){return $.fn.alert=old,this},$(document).on("click.alert.data-api",dismiss,Alert.prototype.close)}(window.jQuery),!function($){"use strict";var Button=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.button.defaults,options)};Button.prototype.setState=function(state){var d="disabled",$el=this.$element,data=$el.data(),val=$el.is("input")?"val":"html";state+="Text",data.resetText||$el.data("resetText",$el[val]()),$el[val](data[state]||this.options[state]),setTimeout(function(){"loadingText"==state?$el.addClass(d).attr(d,d):$el.removeClass(d).removeAttr(d)},0)},Button.prototype.toggle=function(){var $parent=this.$element.closest('[data-toggle="buttons-radio"]');$parent&&$parent.find(".active").removeClass("active"),this.$element.toggleClass("active")};var old=$.fn.button;$.fn.button=function(option){return this.each(function(){var $this=$(this),data=$this.data("button"),options="object"==typeof option&&option;data||$this.data("button",data=new Button(this,options)),"toggle"==option?data.toggle():option&&data.setState(option)})},$.fn.button.defaults={loadingText:"loading..."},$.fn.button.Constructor=Button,$.fn.button.noConflict=function(){return $.fn.button=old,this},$(document).on("click.button.data-api","[data-toggle^=button]",function(e){var $btn=$(e.target);$btn.hasClass("btn")||($btn=$btn.closest(".btn")),$btn.button("toggle")})}(window.jQuery),!function($){"use strict";var Carousel=function(element,options){this.$element=$(element),this.options=options,"hover"==this.options.pause&&this.$element.on("mouseenter",$.proxy(this.pause,this)).on("mouseleave",$.proxy(this.cycle,this))};Carousel.prototype={cycle:function(e){return e||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval)),this},to:function(pos){var $active=this.$element.find(".item.active"),children=$active.parent().children(),activePos=children.index($active),that=this;if(!(pos>children.length-1||0>pos))return this.sliding?this.$element.one("slid",function(){that.to(pos)}):activePos==pos?this.pause().cycle():this.slide(pos>activePos?"next":"prev",$(children[pos]))},pause:function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&$.support.transition.end&&(this.$element.trigger($.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){return this.sliding?void 0:this.slide("next")},prev:function(){return this.sliding?void 0:this.slide("prev")},slide:function(type,next){var e,$active=this.$element.find(".item.active"),$next=next||$active[type](),isCycling=this.interval,direction="next"==type?"left":"right",fallback="next"==type?"first":"last",that=this;if(this.sliding=!0,isCycling&&this.pause(),$next=$next.length?$next:this.$element.find(".item")[fallback](),e=$.Event("slide",{relatedTarget:$next[0]}),!$next.hasClass("active")){if($.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(e),e.isDefaultPrevented())return;$next.addClass(type),$next[0].offsetWidth,$active.addClass(direction),$next.addClass(direction),this.$element.one($.support.transition.end,function(){$next.removeClass([type,direction].join(" ")).addClass("active"),$active.removeClass(["active",direction].join(" ")),that.sliding=!1,setTimeout(function(){that.$element.trigger("slid")},0)})}else{if(this.$element.trigger(e),e.isDefaultPrevented())return;$active.removeClass("active"),$next.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return isCycling&&this.cycle(),this}}};var old=$.fn.carousel;$.fn.carousel=function(option){return this.each(function(){var $this=$(this),data=$this.data("carousel"),options=$.extend({},$.fn.carousel.defaults,"object"==typeof option&&option),action="string"==typeof option?option:options.slide;data||$this.data("carousel",data=new Carousel(this,options)),"number"==typeof option?data.to(option):action?data[action]():options.interval&&data.cycle()})},$.fn.carousel.defaults={interval:5e3,pause:"hover"},$.fn.carousel.Constructor=Carousel,$.fn.carousel.noConflict=function(){return $.fn.carousel=old,this},$(document).on("click.carousel.data-api","[data-slide]",function(e){var href,$this=$(this),$target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")),options=$.extend({},$target.data(),$this.data());$target.carousel(options),e.preventDefault()})}(window.jQuery),!function($){"use strict";var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.collapse.defaults,options),this.options.parent&&(this.$parent=$(this.options.parent)),this.options.toggle&&this.toggle()};Collapse.prototype={constructor:Collapse,dimension:function(){var hasWidth=this.$element.hasClass("width");return hasWidth?"width":"height"},show:function(){var dimension,scroll,actives,hasData;if(!this.transitioning){if(dimension=this.dimension(),scroll=$.camelCase(["scroll",dimension].join("-")),actives=this.$parent&&this.$parent.find("> .accordion-group > .in"),actives&&actives.length){if(hasData=actives.data("collapse"),hasData&&hasData.transitioning)return;actives.collapse("hide"),hasData||actives.data("collapse",null)}this.$element[dimension](0),this.transition("addClass",$.Event("show"),"shown"),$.support.transition&&this.$element[dimension](this.$element[0][scroll])}},hide:function(){var dimension;this.transitioning||(dimension=this.dimension(),this.reset(this.$element[dimension]()),this.transition("removeClass",$.Event("hide"),"hidden"),this.$element[dimension](0))},reset:function(size){var dimension=this.dimension();return this.$element.removeClass("collapse")[dimension](size||"auto")[0].offsetWidth,this.$element[null!==size?"addClass":"removeClass"]("collapse"),this},transition:function(method,startEvent,completeEvent){var that=this,complete=function(){"show"==startEvent.type&&that.reset(),that.transitioning=0,that.$element.trigger(completeEvent)};this.$element.trigger(startEvent),startEvent.isDefaultPrevented()||(this.transitioning=1,this.$element[method]("in"),$.support.transition&&this.$element.hasClass("collapse")?this.$element.one($.support.transition.end,complete):complete())},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var old=$.fn.collapse;$.fn.collapse=function(option){return this.each(function(){var $this=$(this),data=$this.data("collapse"),options="object"==typeof option&&option;data||$this.data("collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})},$.fn.collapse.defaults={toggle:!0},$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.collapse.data-api","[data-toggle=collapse]",function(e){var href,$this=$(this),target=$this.attr("data-target")||e.preventDefault()||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),option=$(target).data("collapse")?"toggle":$this.data();$this[$(target).hasClass("in")?"addClass":"removeClass"]("collapsed"),$(target).collapse(option)})}(window.jQuery),!function($){"use strict";function clearMenus(){$(toggle).each(function(){getParent($(this)).removeClass("open")})}function getParent($this){var $parent,selector=$this.attr("data-target");return selector||(selector=$this.attr("href"),selector=selector&&/#/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),$parent.length||($parent=$this.parent()),$parent}var toggle="[data-toggle=dropdown]",Dropdown=function(element){var $el=$(element).on("click.dropdown.data-api",this.toggle);$("html").on("click.dropdown.data-api",function(){$el.parent().removeClass("open")})};Dropdown.prototype={constructor:Dropdown,toggle:function(){var $parent,isActive,$this=$(this);if(!$this.is(".disabled, :disabled"))return $parent=getParent($this),isActive=$parent.hasClass("open"),clearMenus(),isActive||$parent.toggleClass("open"),$this.focus(),!1},keydown:function(e){var $this,$items,$parent,isActive,index;if(/(38|40|27)/.test(e.keyCode)&&($this=$(this),e.preventDefault(),e.stopPropagation(),!$this.is(".disabled, :disabled"))){if($parent=getParent($this),isActive=$parent.hasClass("open"),!isActive||isActive&&27==e.keyCode)return $this.click();$items=$("[role=menu] li:not(.divider):visible a",$parent),$items.length&&(index=$items.index($items.filter(":focus")),38==e.keyCode&&index>0&&index--,40==e.keyCode&&$items.length-1>index&&index++,~index||(index=0),$items.eq(index).focus())}}};var old=$.fn.dropdown;$.fn.dropdown=function(option){return this.each(function(){var $this=$(this),data=$this.data("dropdown");data||$this.data("dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})},$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).on("click.dropdown.data-api touchstart.dropdown.data-api",clearMenus).on("click.dropdown touchstart.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("touchstart.dropdown.data-api",".dropdown-menu",function(e){e.stopPropagation()}).on("click.dropdown.data-api touchstart.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.dropdown.data-api touchstart.dropdown.data-api",toggle+", [role=menu]",Dropdown.prototype.keydown)}(window.jQuery),!function($){"use strict";var Modal=function(element,options){this.options=options,this.$element=$(element).delegate('[data-dismiss="modal"]',"click.dismiss.modal",$.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};Modal.prototype={constructor:Modal,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var that=this,e=$.Event("show");this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");that.$element.parent().length||that.$element.appendTo(document.body),that.$element.show(),transition&&that.$element[0].offsetWidth,that.$element.addClass("in").attr("aria-hidden",!1),that.enforceFocus(),transition?that.$element.one($.support.transition.end,function(){that.$element.focus().trigger("shown")}):that.$element.focus().trigger("shown")}))},hide:function(e){e&&e.preventDefault(),e=$.Event("hide"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),$(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),$.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal())},enforceFocus:function(){var that=this;$(document).on("focusin.modal",function(e){that.$element[0]===e.target||that.$element.has(e.target).length||that.$element.focus()})},escape:function(){var that=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(e){27==e.which&&that.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var that=this,timeout=setTimeout(function(){that.$element.off($.support.transition.end),that.hideModal()},500);this.$element.one($.support.transition.end,function(){clearTimeout(timeout),that.hideModal()})},hideModal:function(){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(callback){var animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;this.$backdrop=$('<div class="modal-backdrop '+animate+'" />').appendTo(document.body),this.$backdrop.click("static"==this.options.backdrop?$.proxy(this.$element[0].focus,this.$element[0]):$.proxy(this.hide,this)),doAnimate&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),doAnimate?this.$backdrop.one($.support.transition.end,callback):callback()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),$.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one($.support.transition.end,$.proxy(this.removeBackdrop,this)):this.removeBackdrop()):callback&&callback()}};var old=$.fn.modal;$.fn.modal=function(option){return this.each(function(){var $this=$(this),data=$this.data("modal"),options=$.extend({},$.fn.modal.defaults,$this.data(),"object"==typeof option&&option);data||$this.data("modal",data=new Modal(this,options)),"string"==typeof option?data[option]():options.show&&data.show()})},$.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},$.fn.modal.Constructor=Modal,$.fn.modal.noConflict=function(){return $.fn.modal=old,this},$(document).on("click.modal.data-api",'[data-toggle="modal"]',function(e){var $this=$(this),href=$this.attr("href"),$target=$($this.attr("data-target")||href&&href.replace(/.*(?=#[^\s]+$)/,"")),option=$target.data("modal")?"toggle":$.extend({remote:!/#/.test(href)&&href},$target.data(),$this.data());e.preventDefault(),$target.modal(option).one("hide",function(){$this.focus()})})}(window.jQuery),!function($){"use strict";var Tooltip=function(element,options){this.init("tooltip",element,options)};Tooltip.prototype={constructor:Tooltip,init:function(type,element,options){var eventIn,eventOut;this.type=type,this.$element=$(element),this.options=this.getOptions(options),this.enabled=!0,"click"==this.options.trigger?this.$element.on("click."+this.type,this.options.selector,$.proxy(this.toggle,this)):"manual"!=this.options.trigger&&(eventIn="hover"==this.options.trigger?"mouseenter":"focus",eventOut="hover"==this.options.trigger?"mouseleave":"blur",this.$element.on(eventIn+"."+this.type,this.options.selector,$.proxy(this.enter,this)),this.$element.on(eventOut+"."+this.type,this.options.selector,$.proxy(this.leave,this))),this.options.selector?this._options=$.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(options){return options=$.extend({},$.fn[this.type].defaults,options,this.$element.data()),options.delay&&"number"==typeof options.delay&&(options.delay={show:options.delay,hide:options.delay}),options},enter:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);return self.options.delay&&self.options.delay.show?(clearTimeout(this.timeout),self.hoverState="in",this.timeout=setTimeout(function(){"in"==self.hoverState&&self.show()},self.options.delay.show),void 0):self.show()},leave:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);return this.timeout&&clearTimeout(this.timeout),self.options.delay&&self.options.delay.hide?(self.hoverState="out",this.timeout=setTimeout(function(){"out"==self.hoverState&&self.hide()},self.options.delay.hide),void 0):self.hide()},show:function(){var $tip,inside,pos,actualWidth,actualHeight,placement,tp;if(this.hasContent()&&this.enabled){switch($tip=this.tip(),this.setContent(),this.options.animation&&$tip.addClass("fade"),placement="function"==typeof this.options.placement?this.options.placement.call(this,$tip[0],this.$element[0]):this.options.placement,inside=/in/.test(placement),$tip.detach().css({top:0,left:0,display:"block"}).insertAfter(this.$element),pos=this.getPosition(inside),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,inside?placement.split(" ")[1]:placement){case"bottom":tp={top:pos.top+pos.height,left:pos.left+pos.width/2-actualWidth/2};break;case"top":tp={top:pos.top-actualHeight,left:pos.left+pos.width/2-actualWidth/2};break;case"left":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth};break;case"right":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width}}$tip.offset(tp).addClass(placement).addClass("in")}},setContent:function(){var $tip=this.tip(),title=this.getTitle();$tip.find(".tooltip-inner")[this.options.html?"html":"text"](title),$tip.removeClass("fade in top bottom left right")},hide:function(){function removeWithAnimation(){var timeout=setTimeout(function(){$tip.off($.support.transition.end).detach()},500);$tip.one($.support.transition.end,function(){clearTimeout(timeout),$tip.detach()})}var $tip=this.tip();return $tip.removeClass("in"),$.support.transition&&this.$tip.hasClass("fade")?removeWithAnimation():$tip.detach(),this},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("data-original-title"))&&$e.attr("data-original-title",$e.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(inside){return $.extend({},inside?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var title,$e=this.$element,o=this.options;return title=$e.attr("data-original-title")||("function"==typeof o.title?o.title.call($e[0]):o.title)},tip:function(){return this.$tip=this.$tip||$(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);self[self.tip().hasClass("in")?"hide":"show"]()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var old=$.fn.tooltip;$.fn.tooltip=function(option){return this.each(function(){var $this=$(this),data=$this.data("tooltip"),options="object"==typeof option&&option;data||$this.data("tooltip",data=new Tooltip(this,options)),"string"==typeof option&&data[option]()})},$.fn.tooltip.Constructor=Tooltip,$.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover",title:"",delay:0,html:!1},$.fn.tooltip.noConflict=function(){return $.fn.tooltip=old,this}}(window.jQuery),!function($){"use strict";var Popover=function(element,options){this.init("popover",element,options)};Popover.prototype=$.extend({},$.fn.tooltip.Constructor.prototype,{constructor:Popover,setContent:function(){var $tip=this.tip(),title=this.getTitle(),content=this.getContent();$tip.find(".popover-title")[this.options.html?"html":"text"](title),$tip.find(".popover-content")[this.options.html?"html":"text"](content),$tip.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var content,$e=this.$element,o=this.options;return content=$e.attr("data-content")||("function"==typeof o.content?o.content.call($e[0]):o.content)},tip:function(){return this.$tip||(this.$tip=$(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var old=$.fn.popover;$.fn.popover=function(option){return this.each(function(){var $this=$(this),data=$this.data("popover"),options="object"==typeof option&&option;data||$this.data("popover",data=new Popover(this,options)),"string"==typeof option&&data[option]()})},$.fn.popover.Constructor=Popover,$.fn.popover.defaults=$.extend({},$.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"></div></div></div>'}),$.fn.popover.noConflict=function(){return $.fn.popover=old,this}}(window.jQuery),!function($){"use strict";function ScrollSpy(element,options){var href,process=$.proxy(this.process,this),$element=$(element).is("body")?$(window):$(element);this.options=$.extend({},$.fn.scrollspy.defaults,options),this.$scrollElement=$element.on("scroll.scroll-spy.data-api",process),this.selector=(this.options.target||(href=$(element).attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=$("body"),this.refresh(),this.process()}ScrollSpy.prototype={constructor:ScrollSpy,refresh:function(){var $targets,self=this;this.offsets=$([]),this.targets=$([]),$targets=this.$body.find(this.selector).map(function(){var $el=$(this),href=$el.data("target")||$el.attr("href"),$href=/^#\w/.test(href)&&$(href);return $href&&$href.length&&[[$href.position().top+self.$scrollElement.scrollTop(),href]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){self.offsets.push(this[0]),self.targets.push(this[1])})},process:function(){var i,scrollTop=this.$scrollElement.scrollTop()+this.options.offset,scrollHeight=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,maxScroll=scrollHeight-this.$scrollElement.height(),offsets=this.offsets,targets=this.targets,activeTarget=this.activeTarget;if(scrollTop>=maxScroll)return activeTarget!=(i=targets.last()[0])&&this.activate(i);for(i=offsets.length;i--;)activeTarget!=targets[i]&&scrollTop>=offsets[i]&&(!offsets[i+1]||offsets[i+1]>=scrollTop)&&this.activate(targets[i])},activate:function(target){var active,selector;this.activeTarget=target,$(this.selector).parent(".active").removeClass("active"),selector=this.selector+'[data-target="'+target+'"],'+this.selector+'[href="'+target+'"]',active=$(selector).parent("li").addClass("active"),active.parent(".dropdown-menu").length&&(active=active.closest("li.dropdown").addClass("active")),active.trigger("activate")}};var old=$.fn.scrollspy;$.fn.scrollspy=function(option){return this.each(function(){var $this=$(this),data=$this.data("scrollspy"),options="object"==typeof option&&option;data||$this.data("scrollspy",data=new ScrollSpy(this,options)),"string"==typeof option&&data[option]()})},$.fn.scrollspy.Constructor=ScrollSpy,$.fn.scrollspy.defaults={offset:10},$.fn.scrollspy.noConflict=function(){return $.fn.scrollspy=old,this},$(window).on("load",function(){$('[data-spy="scroll"]').each(function(){var $spy=$(this);$spy.scrollspy($spy.data())})})}(window.jQuery),!function($){"use strict";var Tab=function(element){this.element=$(element)};Tab.prototype={constructor:Tab,show:function(){var previous,$target,e,$this=this.element,$ul=$this.closest("ul:not(.dropdown-menu)"),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$this.parent("li").hasClass("active")||(previous=$ul.find(".active:last a")[0],e=$.Event("show",{relatedTarget:previous}),$this.trigger(e),e.isDefaultPrevented()||($target=$(selector),this.activate($this.parent("li"),$ul),this.activate($target,$target.parent(),function(){$this.trigger({type:"shown",relatedTarget:previous})})))},activate:function(element,container,callback){function next(){$active.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),element.addClass("active"),transition?(element[0].offsetWidth,element.addClass("in")):element.removeClass("fade"),element.parent(".dropdown-menu")&&element.closest("li.dropdown").addClass("active"),callback&&callback()}var $active=container.find("> .active"),transition=callback&&$.support.transition&&$active.hasClass("fade");transition?$active.one($.support.transition.end,next):next(),$active.removeClass("in")}};var old=$.fn.tab;$.fn.tab=function(option){return this.each(function(){var $this=$(this),data=$this.data("tab");data||$this.data("tab",data=new Tab(this)),"string"==typeof option&&data[option]()})},$.fn.tab.Constructor=Tab,$.fn.tab.noConflict=function(){return $.fn.tab=old,this},$(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(e){e.preventDefault(),$(this).tab("show")})}(window.jQuery),!function($){"use strict";var Typeahead=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.typeahead.defaults,options),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=$(this.options.menu),this.shown=!1,this.listen()};Typeahead.prototype={constructor:Typeahead,select:function(){var val=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(val)).change(),this.hide()},updater:function(item){return item},show:function(){var pos=$.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:pos.top+pos.height,left:pos.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(){var items;return this.query=this.$element.val(),!this.query||this.query.length<this.options.minLength?this.shown?this.hide():this:(items=$.isFunction(this.source)?this.source(this.query,$.proxy(this.process,this)):this.source,items?this.process(items):this)},process:function(items){var that=this;return items=$.grep(items,function(item){return that.matcher(item)}),items=this.sorter(items),items.length?this.render(items.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(item){return~item.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(items){for(var item,beginswith=[],caseSensitive=[],caseInsensitive=[];item=items.shift();)item.toLowerCase().indexOf(this.query.toLowerCase())?~item.indexOf(this.query)?caseSensitive.push(item):caseInsensitive.push(item):beginswith.push(item);return beginswith.concat(caseSensitive,caseInsensitive)},highlighter:function(item){var query=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return item.replace(RegExp("("+query+")","ig"),function($1,match){return"<strong>"+match+"</strong>"})},render:function(items){var that=this;return items=$(items).map(function(i,item){return i=$(that.options.item).attr("data-value",item),i.find("a").html(that.highlighter(item)),i[0]}),items.first().addClass("active"),this.$menu.html(items),this},next:function(){var active=this.$menu.find(".active").removeClass("active"),next=active.next();next.length||(next=$(this.$menu.find("li")[0])),next.addClass("active")},prev:function(){var active=this.$menu.find(".active").removeClass("active"),prev=active.prev();prev.length||(prev=this.$menu.find("li").last()),prev.addClass("active")},listen:function(){this.$element.on("blur",$.proxy(this.blur,this)).on("keypress",$.proxy(this.keypress,this)).on("keyup",$.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",$.proxy(this.keydown,this)),this.$menu.on("click",$.proxy(this.click,this)).on("mouseenter","li",$.proxy(this.mouseenter,this))},eventSupported:function(eventName){var isSupported=eventName in this.$element;return isSupported||(this.$element.setAttribute(eventName,"return;"),isSupported="function"==typeof this.$element[eventName]),isSupported},move:function(e){if(this.shown){switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()}},keydown:function(e){this.suppressKeyPressRepeat=~$.inArray(e.keyCode,[40,38,9,13,27]),this.move(e)},keypress:function(e){this.suppressKeyPressRepeat||this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},blur:function(){var that=this;setTimeout(function(){that.hide()},150)},click:function(e){e.stopPropagation(),e.preventDefault(),this.select()},mouseenter:function(e){this.$menu.find(".active").removeClass("active"),$(e.currentTarget).addClass("active")}};var old=$.fn.typeahead;$.fn.typeahead=function(option){return this.each(function(){var $this=$(this),data=$this.data("typeahead"),options="object"==typeof option&&option;data||$this.data("typeahead",data=new Typeahead(this,options)),"string"==typeof option&&data[option]()})},$.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',minLength:1},$.fn.typeahead.Constructor=Typeahead,$.fn.typeahead.noConflict=function(){return $.fn.typeahead=old,this},$(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(e){var $this=$(this);$this.data("typeahead")||(e.preventDefault(),$this.typeahead($this.data()))})}(window.jQuery),!function($){"use strict";var Affix=function(element,options){this.options=$.extend({},$.fn.affix.defaults,options),this.$window=$(window).on("scroll.affix.data-api",$.proxy(this.checkPosition,this)).on("click.affix.data-api",$.proxy(function(){setTimeout($.proxy(this.checkPosition,this),1)},this)),this.$element=$(element),this.checkPosition()};Affix.prototype.checkPosition=function(){if(this.$element.is(":visible")){var affix,scrollHeight=$(document).height(),scrollTop=this.$window.scrollTop(),position=this.$element.offset(),offset=this.options.offset,offsetBottom=offset.bottom,offsetTop=offset.top,reset="affix affix-top affix-bottom";"object"!=typeof offset&&(offsetBottom=offsetTop=offset),"function"==typeof offsetTop&&(offsetTop=offset.top()),"function"==typeof offsetBottom&&(offsetBottom=offset.bottom()),affix=null!=this.unpin&&scrollTop+this.unpin<=position.top?!1:null!=offsetBottom&&position.top+this.$element.height()>=scrollHeight-offsetBottom?"bottom":null!=offsetTop&&offsetTop>=scrollTop?"top":!1,this.affixed!==affix&&(this.affixed=affix,this.unpin="bottom"==affix?position.top-scrollTop:null,this.$element.removeClass(reset).addClass("affix"+(affix?"-"+affix:"")))}};var old=$.fn.affix;$.fn.affix=function(option){return this.each(function(){var $this=$(this),data=$this.data("affix"),options="object"==typeof option&&option;data||$this.data("affix",data=new Affix(this,options)),"string"==typeof option&&data[option]()})},$.fn.affix.Constructor=Affix,$.fn.affix.defaults={offset:0},$.fn.affix.noConflict=function(){return $.fn.affix=old,this},$(window).on("load",function(){$('[data-spy="affix"]').each(function(){var $spy=$(this),data=$spy.data();data.offset=data.offset||{},data.offsetBottom&&(data.offset.bottom=data.offsetBottom),data.offsetTop&&(data.offset.top=data.offsetTop),$spy.affix(data)})})}(window.jQuery);/*
HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}</style>";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
/*
Highcharts JS v2.3.5 (2012-12-19)
(c) 2009-2012 Torstein Hønsi
License: www.highcharts.com/license
*/
(function(){function x(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function ia(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}function z(a,b){return parseInt(a,b||10)}function ja(a){return typeof a==="string"}function Y(a){return typeof a==="object"}function Ia(a){return Object.prototype.toString.call(a)==="[object Array]"}function Da(a){return typeof a==="number"}function ka(a){return K.log(a)/K.LN10}function aa(a){return K.pow(10,a)}function ta(a,b){for(var c=a.length;c--;)if(a[c]===
b){a.splice(c,1);break}}function r(a){return a!==A&&a!==null}function w(a,b,c){var d,e;if(ja(b))r(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(r(b)&&Y(b))for(d in b)a.setAttribute(d,b[d]);return e}function la(a){return Ia(a)?a:[a]}function n(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!=="undefined"&&c!==null)return c}function I(a,b){if(Ea&&b&&b.opacity!==A)b.filter="alpha(opacity="+b.opacity*100+")";x(a.style,b)}function T(a,b,c,d,e){a=C.createElement(a);
b&&x(a,b);e&&I(a,{padding:0,border:Q,margin:0});c&&I(a,c);d&&d.appendChild(a);return a}function ba(a,b){var c=function(){};c.prototype=new a;x(c.prototype,b);return c}function Ja(a,b,c,d){var e=N.lang,f=a;b===-1?(b=(a||0).toString(),a=b.indexOf(".")>-1?b.split(".")[1].length:0):a=isNaN(b=M(b))?2:b;var b=a,c=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=f<0?"-":"",a=String(z(f=M(+f||0).toFixed(b))),g=a.length>3?a.length%3:0;return e+(g?a.substr(0,g)+d:"")+a.substr(g).replace(/(\d{3})(?=\d)/g,
"$1"+d)+(b?c+M(f-a).toFixed(b).slice(2):"")}function ua(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function hb(a,b,c,d){var e,c=n(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function Ab(a,b){var c=b||[[Bb,[1,2,5,10,20,25,50,100,200,500]],[ib,[1,2,5,10,15,30]],[Va,[1,2,5,10,15,30]],[Ka,[1,2,3,4,6,8,12]],[ma,[1,2]],[Wa,[1,2]],[La,[1,2,3,4,6]],[va,null]],d=
c[c.length-1],e=D[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d=c[g],e=D[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+D[c[g+1][0]])/2)break;e===D[va]&&a<5*e&&(f=[1,2,5]);e===D[va]&&a<5*e&&(f=[1,2,5]);c=hb(a/e,f);return{unitRange:e,count:c,unitName:d[0]}}function Cb(a,b,c,d){var e=[],f={},g=N.global.useUTC,h,i=new Date(b),j=a.unitRange,k=a.count;if(r(b)){j>=D[ib]&&(i.setMilliseconds(0),i.setSeconds(j>=D[Va]?0:k*U(i.getSeconds()/k)));if(j>=D[Va])i[Db](j>=D[Ka]?0:k*U(i[jb]()/k));if(j>=D[Ka])i[Eb](j>=D[ma]?
0:k*U(i[kb]()/k));if(j>=D[ma])i[lb](j>=D[La]?1:k*U(i[Ma]()/k));j>=D[La]&&(i[Fb](j>=D[va]?0:k*U(i[Xa]()/k)),h=i[Ya]());j>=D[va]&&(h-=h%k,i[Gb](h));if(j===D[Wa])i[lb](i[Ma]()-i[mb]()+n(d,1));b=1;h=i[Ya]();for(var d=i.getTime(),l=i[Xa](),m=i[Ma](),i=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;d<c;)e.push(d),j===D[va]?d=Za(h+b*k,0):j===D[La]?d=Za(h,l+b*k):!g&&(j===D[ma]||j===D[Wa])?d=Za(h,l,m+b*k*(j===D[ma]?1:7)):(d+=j*k,j<=D[Ka]&&d%D[ma]===i&&(f[d]=ma)),b++;e.push(d)}e.info=x(a,{higherRanks:f,totalRange:j*
k});return e}function Hb(){this.symbol=this.color=0}function Ib(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0?a.ss_i-c.ss_i:d});for(e=0;e<c;e++)delete a[e].ss_i}function Fa(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function wa(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Ga(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Na(a){$a||($a=T(ga));a&&$a.appendChild(a);$a.innerHTML=
""}function Oa(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else L.console&&console.log(c)}function da(a){return parseFloat(a.toPrecision(14))}function xa(a,b){Pa=n(a,b.animation)}function Jb(){var a=N.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";Za=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,n(c,1),n(g,0),n(h,0),n(i,0))).getTime()};jb=b+"Minutes";kb=b+"Hours";mb=b+"Day";Ma=b+"Date";Xa=b+"Month";Ya=b+"FullYear";Db=c+"Minutes";Eb=c+"Hours";lb=c+"Date";
Fb=c+"Month";Gb=c+"FullYear"}function ya(){}function Qa(a,b,c){this.axis=a;this.pos=b;this.type=c||"";this.isNew=!0;c||this.addLabel()}function nb(a,b){this.axis=a;if(b)this.options=b,this.id=b.id;return this}function Kb(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.stack=e;this.percent=f==="percent";this.alignOptions={align:b.align||(g?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(g?"middle":c?"bottom":"top"),y:n(b.y,g?4:c?14:-6),x:n(b.x,
g?c?-6:6:0)};this.textAlign=b.textAlign||(g?c?"right":"left":"center")}function ob(){this.init.apply(this,arguments)}function pb(a,b){var c=b.borderWidth,d=b.style,e=z(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=a.renderer.label("",0,0,b.shape,null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).hide().add();V||this.label.shadow(b.shadow);this.shared=
b.shared}function qb(a,b){var c=V?"":b.chart.zoomType;this.zoomX=/x/.test(c);this.zoomY=/y/.test(c);this.options=b;this.chart=a;this.init(a,b.tooltip)}function rb(a){this.init(a)}function sb(){this.init.apply(this,arguments)}var A,C=document,L=window,K=Math,u=K.round,U=K.floor,za=K.ceil,s=K.max,O=K.min,M=K.abs,W=K.cos,Z=K.sin,Aa=K.PI,ab=Aa*2/360,na=navigator.userAgent,Lb=L.opera,Ea=/msie/i.test(na)&&!Lb,Ra=C.documentMode===8,bb=/AppleWebKit/.test(na),cb=/Firefox/.test(na),Mb=/(Mobile|Android|Windows Phone)/.test(na),
oa="http://www.w3.org/2000/svg",ca=!!C.createElementNS&&!!C.createElementNS(oa,"svg").createSVGRect,Sb=cb&&parseInt(na.split("Firefox/")[1],10)<4,V=!ca&&!Ea&&!!C.createElement("canvas").getContext,Sa,Ba=C.documentElement.ontouchstart!==A,Nb={},tb=0,$a,N,db,Pa,ub,D,pa=function(){},Ha=[],ga="div",Q="none",vb="rgba(192,192,192,"+(ca?1.0E-4:0.002)+")",Bb="millisecond",ib="second",Va="minute",Ka="hour",ma="day",Wa="week",La="month",va="year",wb="stroke-width",Za,jb,kb,mb,Ma,Xa,Ya,Db,Eb,lb,Fb,Gb,$={};L.Highcharts=
{};db=function(a,b,c){if(!r(b)||isNaN(b))return"Invalid date";var a=n(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[kb](),g=d[mb](),h=d[Ma](),i=d[Xa](),j=d[Ya](),k=N.lang,l=k.weekdays,b={a:l[g].substr(0,3),A:l[g],d:ua(h),e:h,b:k.shortMonths[i],B:k.months[i],m:ua(i+1),y:j.toString().substr(2,2),Y:j,H:ua(f),I:ua(f%12||12),l:f%12||12,M:ua(d[jb]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:ua(d.getSeconds()),L:ua(u(b%1E3),3)};for(e in b)for(;a.indexOf("%"+e)!==-1;)a=a.replace("%"+e,b[e]);return c?a.substr(0,1).toUpperCase()+
a.substr(1):a};Hb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};D=ia(Bb,1,ib,1E3,Va,6E4,Ka,36E5,ma,864E5,Wa,6048E5,La,26784E5,va,31556952E3);ub={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]==="M"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<=
c.length/f)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}};(function(a){L.HighchartsAdapter=L.HighchartsAdapter||a&&{init:function(b){var c=a.fx,d=c.step,
e,f=a.Tween,g=f&&f.propHooks;a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});a.each(["cur","_default","width","height"],function(a,b){var e=d,k,l;b==="cur"?e=c.prototype:b==="_default"&&f&&(e=g[b],b="set");(k=e[b])&&(e[b]=function(c){c=a?c:this;l=c.elem;return l.attr?l.attr(c.prop,b==="cur"?A:c.now):k.apply(this,arguments)})});e=function(a){var c=a.elem,d;if(!a.started)d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0;c.attr("d",b.step(a.start,a.end,a.pos,c.toD))};
f?g.d={set:e}:d.d=e;this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;e<f;e++)d[e]=c.call(a[e],a[e],e,a);return d},merge:function(){var b=arguments;return a.extend(!0,null,b[0],b[1],b[2],b[3])},offset:function(b){return a(b).offset()},
addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=C.removeEventListener?"removeEventListener":"detachEvent";C[e]&&!b[e]&&(b[e]=function(){});a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var f=a.Event(c),g="detached"+c,h;!Ea&&d&&(delete d.layerX,delete d.layerY);x(f,d);b[c]&&(b[g]=b[c],b[c]=null);a.each(["preventDefault","stopPropagation"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){b==="preventDefault"&&(h=!0)}}});a(b).trigger(f);b[g]&&(b[c]=b[g],b[g]=
null);e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;if(c.pageX===A)c.pageX=a.pageX,c.pageY=a.pageY;return c},animate:function(b,c,d){var e=a(b);if(c.d)b.toD=c.d,c.d=1;e.stop();e.animate(c,d)},stop:function(b){a(b).stop()}}})(L.jQuery);var ea=L.HighchartsAdapter,G=ea||{};ea&&ea.init.call(ea,ub);var eb=G.adapterRun,Tb=G.getScript,Ub=G.inArray,o=G.each,Ob=G.grep,Vb=G.offset,Ta=G.map,B=G.merge,J=G.addEvent,R=G.removeEvent,F=G.fireEvent,Pb=G.washMouseEvent,xb=
G.animate,fb=G.stop,G={enabled:!0,align:"center",x:0,y:15,style:{color:"#666",fontSize:"11px",lineHeight:"14px"}};N={colors:"#4572A7,#AA4643,#89A54E,#80699B,#3D96AE,#DB843D,#92A8CD,#A47D7C,#B5CA92".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),
decimalPoint:".",numericSymbols:"k,M,G,T,P,E".split(","),resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/2.3.5/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/2.3.5/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:5,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacingTop:10,spacingRight:10,spacingBottom:15,spacingLeft:10,style:{fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',
fontSize:"12px"},backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",y:15,style:{color:"#3E576F",fontSize:"16px"}},subtitle:{text:"",align:"center",y:30,style:{color:"#6D869F"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,shadow:!0,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0},select:{fillColor:"#FFFFFF",
lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:B(G,{enabled:!1,formatter:function(){return this.y},verticalAlign:"bottom",y:0}),cropThreshold:300,pointRange:0,showInLegend:!0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:"absolute",color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderWidth:1,borderColor:"#909090",borderRadius:5,navigation:{activeColor:"#3E576F",inactiveColor:"#CCC"},
shadow:!1,itemStyle:{cursor:"pointer",color:"#3E576F",fontSize:"12px"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:"absolute",width:"13px",height:"13px"},symbolWidth:16,symbolPadding:5,verticalAlign:"bottom",x:0,y:0},loading:{labelStyle:{fontWeight:"bold",position:"relative",top:"1em"},style:{position:"absolute",backgroundColor:"white",opacity:0.5,textAlign:"center"}},tooltip:{enabled:!0,backgroundColor:"rgba(255, 255, 255, .85)",borderWidth:2,borderRadius:5,
dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',shadow:!0,shared:V,snap:Mb?25:10,style:{color:"#333333",fontSize:"12px",padding:"5px",whiteSpace:"nowrap"}},credits:{enabled:!0,
text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"10px"}}};var X=N.plotOptions,ea=X.line;Jb();var qa=function(a){var b=[],c;(function(a){(c=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(a))?b=[z(c[1]),z(c[2]),z(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))&&(b=[z(c[1],16),z(c[2],16),z(c[3],
16),1])})(a);return{get:function(c){return b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"?b[3]:"rgba("+b.join(",")+")":a},brighten:function(a){if(Da(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=z(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},setOpacity:function(a){b[3]=a;return this}}};ya.prototype={init:function(a,b){this.element=b==="span"?T(b):C.createElementNS(oa,b);this.renderer=a;this.attrSetters={}},animate:function(a,b,c){b=n(b,Pa,!0);fb(this);if(b){b=B(b);if(c)b.complete=
c;xb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(),i=this.renderer,j,k=this.attrSetters,l=this.shadows,m,q,p=this;ja(a)&&r(b)&&(c=a,a={},a[c]=b);if(ja(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),p=w(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&&(p=parseFloat(p));else for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==A&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&&
(d="M 0 0");else if(c==="x"&&h==="text"){for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],w(f,"x")===w(g,"x")&&w(f,"x",d);this.rotation&&w(g,"transform","rotate("+this.rotation+" "+d+" "+z(a.y||w(g,"y"))+")")}else if(c==="fill")d=i.color(d,g,c);else if(h==="circle"&&(c==="x"||c==="y"))c={x:"cx",y:"cy"}[c]||c;else if(h==="rect"&&c==="r")w(g,{rx:d,ry:d}),j=!0;else if(c==="translateX"||c==="translateY"||c==="rotation"||c==="verticalAlign")j=q=!0;else if(c==="stroke")d=i.color(d,g,c);else if(c==="dashstyle")if(c=
"stroke-dasharray",d=d&&d.toLowerCase(),d==="solid")d=Q;else{if(d){d=d.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(",");for(e=d.length;e--;)d[e]=z(d[e])*a["stroke-width"];d=d.join(",")}}else if(c==="isTracker")this[c]=d;else if(c==="width")d=z(d);else if(c==="align")c="text-anchor",d={left:"start",center:"middle",right:"end"}[d];
else if(c==="title")e=g.getElementsByTagName("title")[0],e||(e=C.createElementNS(oa,"title"),g.appendChild(e)),e.textContent=d;c==="strokeWidth"&&(c="stroke-width");if(c==="stroke-width"&&d===0&&(bb||i.forExport))d=1.0E-6;this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(m||(this.symbolAttr(a),m=!0),j=!0);if(l&&/^(width|height|visibility|x|y|d|transform)$/.test(c))for(e=l.length;e--;)w(l[e],c,c==="height"?s(d-(l[e].cutHeight||0),0):d);if((c==="width"||c==="height")&&
h==="rect"&&d<0)d=0;this[c]=d;q&&this.updateTransform();c==="text"?(d!==this.textStr&&delete this.bBox,this.textStr=d,this.added&&i.buildText(this)):j||w(g,c,d)}return p},symbolAttr:function(a){var b=this;o("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=n(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path",a?"url("+this.renderer.url+"#"+a.id+")":Q)},crisp:function(a,b,c,d,e){var f,g=
{},h={},i,a=a||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;i=u(a)%2/2;h.x=U(b||this.x||0)+i;h.y=U(c||this.y||0)+i;h.width=U((d||this.width||0)-2*i);h.height=U((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},css:function(a){var b=this.element,b=a&&a.width&&b.nodeName.toLowerCase()==="text",c,d="",e=function(a,b){return"-"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=x(this.styles,a);V&&b&&delete a.width;if(Ea&&!ca)b&&delete a.width,
I(this.element,a);else{for(c in a)d+=c.replace(/([A-Z])/g,e)+":"+a[c]+";";this.attr({style:d})}b&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){if(Ba&&a==="click")this.element.ontouchstart=function(a){a.preventDefault();b()};this.element["on"+a]=b;return this},setRadialReference:function(a){this.element.radialReference=a;return this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},
htmlCss:function(a){var b=this.element;if(b=a&&b.tagName==="SPAN"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=x(this.styles,a);I(this.element,a);return this},htmlGetBBox:function(){var a=this.element,b=this.bBox;if(!b){if(a.nodeName==="text")a.style.position="absolute";b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}}return b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=
this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:0.5,right:1}[g],i=g&&g!=="left",j=this.shadows;if(c||d)I(b,{marginLeft:c,marginTop:d}),j&&o(j,function(a){I(a,{marginLeft:c+1,marginTop:d+1})});this.inverted&&o(b.childNodes,function(c){a.invertChild(c,b)});if(b.tagName==="SPAN"){var k,l,j=this.rotation,m,q=0,p=1,q=0,y;m=z(this.textWidth);var t=this.xCorr||0,H=this.yCorr||0,ra=[j,g,b.innerHTML,this.textWidth].join(",");k={};if(ra!==this.cTT){if(r(j))a.isSVG?(t=Ea?
"-ms-transform":bb?"-webkit-transform":cb?"MozTransform":Lb?"-o-transform":"",k[t]=k.transform="rotate("+j+"deg)"):(q=j*ab,p=W(q),q=Z(q),k.filter=j?["progid:DXImageTransform.Microsoft.Matrix(M11=",p,", M12=",-q,", M21=",q,", M22=",p,", sizingMethod='auto expand')"].join(""):Q),I(b,k);k=n(this.elemWidth,b.offsetWidth);l=n(this.elemHeight,b.offsetHeight);if(k>m&&/[ \-]/.test(b.textContent||b.innerText))I(b,{width:m+"px",display:"block",whiteSpace:"normal"}),k=m;m=a.fontMetrics(b.style.fontSize).b;t=
p<0&&-k;H=q<0&&-l;y=p*q<0;t+=q*m*(y?1-h:h);H-=p*m*(j?y?h:1-h:1);i&&(t-=k*h*(p<0?-1:1),j&&(H-=l*h*(q<0?-1:1)),I(b,{textAlign:g}));this.xCorr=t;this.yCorr=H}I(b,{left:e+t+"px",top:f+H+"px"});if(bb)l=b.offsetHeight;this.cTT=ra}}else this.alignOnAdd=!0},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.inverted,d=this.rotation,e=[];c&&(a+=this.attr("width"),b+=this.attr("height"));(a||b)&&e.push("translate("+a+","+b+")");c?e.push("rotate(90) scale(-1,1)"):d&&e.push("rotate("+
d+" "+(this.x||0)+" "+(this.y||0)+")");e.length&&w(this.element,"transform",e.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){a?(this.alignOptions=a,this.alignByTranslate=b,c||this.renderer.alignedObjects.push(this)):(a=this.alignOptions,b=this.alignByTranslate);var c=n(c,this.renderer),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),h={};if(d==="right"||d==="center")f+=(c.width-(a.width||0))/{right:1,center:2}[d];
h[b?"translateX":"x"]=u(f);if(e==="bottom"||e==="middle")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?"translateY":"y"]=u(g);this[this.placed?"animate":"attr"](h);this.placed=!0;this.alignAttr=h;return this},getBBox:function(){var a=this.bBox,b=this.renderer,c,d=this.rotation;c=this.element;var e=this.styles,f=d*ab;if(!a){if(c.namespaceURI===oa||b.forExport){try{a=c.getBBox?x({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(g){}if(!a||a.width<0)a={width:0,height:0}}else a=
this.htmlGetBBox();if(b.isSVG){b=a.width;c=a.height;if(Ea&&e&&e.fontSize==="11px"&&c===22.700000762939453)a.height=c=14;if(d)a.width=M(c*Z(f))+M(b*W(f)),a.height=M(c*W(f))+M(b*Z(f))}this.bBox=a}return a},show:function(){return this.attr({visibility:"visible"})},hide:function(){return this.attr({visibility:"hidden"})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=w(f,"zIndex"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==
void 0&&b.buildText(this);if(g)c.handleZ=!0,g=z(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a=e[c],b=w(a,"zIndex"),a!==f&&(z(b)>g||!r(g)&&r(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;F(this,"add");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d,e;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=null;fb(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(e=0;e<a.stops.length;e++)a.stops[e]=
a.stops[e].destroy();a.stops=null}a.safeRemoveChild(b);c&&o(c,function(b){a.safeRemoveChild(b)});ta(a.renderer.alignedObjects,a);for(d in a)delete a[d];return null},empty:function(){for(var a=this.element,b=a.childNodes,c=b.length;c--;)a.removeChild(b[c])},shadow:function(a,b,c){var d=[],e,f,g=this.element,h,i,j,k;if(a){i=n(a.width,3);j=(a.opacity||0.15)/i;k=this.parentInverted?"(-1,-1)":"("+n(a.offsetX,1)+", "+n(a.offsetY,1)+")";for(e=1;e<=i;e++){f=g.cloneNode(0);h=i*2+1-2*e;w(f,{isShadow:"true",
stroke:a.color||"black","stroke-opacity":j*e,"stroke-width":h,transform:"translate"+k,fill:Q});if(c)w(f,"height",s(w(f,"height")-h,0)),f.cutHeight=h;b?b.element.appendChild(f):g.parentNode.insertBefore(f,g);d.push(f)}this.shadows=d}return this}};var sa=function(){this.init.apply(this,arguments)};sa.prototype={Element:ya,init:function(a,b,c,d){var e=location,f;f=this.createElement("svg").attr({xmlns:oa,version:"1.1"});a.appendChild(f.element);this.isSVG=!0;this.box=f.element;this.boxWrapper=f;this.alignedObjects=
[];this.url=(cb||bb)&&C.getElementsByTagName("base").length?e.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"";this.defs=this.createElement("defs").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1);var g;if(cb&&a.getBoundingClientRect)this.subPixelFix=b=function(){I(a,{left:0,top:0});g=a.getBoundingClientRect();I(a,{left:za(g.left)-g.left+"px",top:za(g.top)-g.top+"px"})},b(),J(L,"resize",b)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=
this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Ga(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();this.subPixelFix&&R(L,"resize",this.subPixelFix);return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a);return b},draw:function(){},buildText:function(a){for(var b=a.element,c=n(a.textStr,"").toString().replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,
"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g),d=b.childNodes,e=/style="([^"]+)"/,f=/href="([^"]+)"/,g=w(b,"x"),h=a.styles,i=h&&h.width&&z(h.width),j=h&&h.lineHeight,k,h=d.length,l=[];h--;)b.removeChild(d[h]);i&&!a.added&&this.box.appendChild(b);c[c.length-1]===""&&c.pop();o(c,function(c,d){var h,y=0,t,c=c.replace(/<span/g,"|||<span").replace(/<\/span>/g,"</span>|||");h=c.split("|||");o(h,function(c){if(c!==""||h.length===1){var m={},n=C.createElementNS(oa,"tspan"),o;e.test(c)&&
(o=c.match(e)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),w(n,"style",o));f.test(c)&&(w(n,"onclick",'location.href="'+c.match(f)[1]+'"'),I(n,{cursor:"pointer"}));c=(c.replace(/<(.|\n)*?>/g,"")||" ").replace(/&lt;/g,"<").replace(/&gt;/g,">");n.appendChild(C.createTextNode(c));y?m.dx=3:m.x=g;if(!y){if(d){!ca&&a.renderer.forExport&&I(n,{display:"block"});t=L.getComputedStyle&&z(L.getComputedStyle(k,null).getPropertyValue("line-height"));if(!t||isNaN(t)){var r;if(!(r=j))if(!(r=k.offsetHeight))l[d]=b.getBBox?
b.getBBox().height:a.renderer.fontMetrics(b.style.fontSize).h,r=u(l[d]-(l[d-1]||0))||18;t=r}w(n,"dy",t)}k=n}w(n,m);b.appendChild(n);y++;if(i)for(var c=c.replace(/([^\^])-/g,"$1- ").split(" "),E=[];c.length||E.length;)delete a.bBox,r=a.getBBox().width,m=r>i,!m||c.length===1?(c=E,E=[],c.length&&(n=C.createElementNS(oa,"tspan"),w(n,{dy:j||16,x:g}),o&&w(n,"style",o),b.appendChild(n),r>i&&(i=r))):(n.removeChild(n.firstChild),E.unshift(c.pop())),c.length&&n.appendChild(C.createTextNode(c.join(" ").replace(/- /g,
"-")))}})})},button:function(a,b,c,d,e,f,g){var h=this.label(a,b,c),i=0,j,k,l,m,q,a={x1:0,y1:0,x2:0,y2:1},e=B(ia(wb,1,"stroke","#999","fill",ia("linearGradient",a,"stops",[[0,"#FFF"],[1,"#DDD"]]),"r",3,"padding",3,"style",ia("color","black")),e);l=e.style;delete e.style;f=B(e,ia("stroke","#68A","fill",ia("linearGradient",a,"stops",[[0,"#FFF"],[1,"#ACF"]])),f);m=f.style;delete f.style;g=B(e,ia("stroke","#68A","fill",ia("linearGradient",a,"stops",[[0,"#9BD"],[1,"#CDF"]])),g);q=g.style;delete g.style;
J(h.element,"mouseenter",function(){h.attr(f).css(m)});J(h.element,"mouseleave",function(){j=[e,f,g][i];k=[l,m,q][i];h.attr(j).css(k)});h.setState=function(a){(i=a)?a===2&&h.attr(g).css(q):h.attr(e).css(l)};return h.on("click",function(){d.call(h)}).attr(e).css(x({cursor:"default"},l))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=u(a[1])-b%2/2);a[2]===a[5]&&(a[2]=a[5]=u(a[2])+b%2/2);return a},path:function(a){var b={fill:Q};Ia(a)?b.d=a:Y(a)&&x(b,a);return this.createElement("path").attr(b)},circle:function(a,
b,c){a=Y(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(Y(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;return this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0})},rect:function(a,b,c,d,e,f){e=Y(a)?a.r:e;e=this.createElement("rect").attr({rx:e,ry:e,fill:Q});return e.attr(Y(a)?a:e.crisp(f,a,b,s(c,0),s(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[n(c,!0)?"animate":
"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return r(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:Q};arguments.length>1&&x(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(u(b),u(c),d,e,
f),i=/^url\((.*?)\)$/,j,k;h?(g=this.path(h),x(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&x(g,f)):i.test(a)&&(k=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(u((d-b[0])/2),u((e-b[1])/2)))},j=a.match(i)[1],a=Nb[j],g=this.image(j).attr({x:b,y:c}),a?k(g,a):(g.attr({width:0,height:0}),T("img",{onload:function(){k(g,Nb[j]=[this.width,this.height])},src:j})));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,
a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-1.0E-6,d=e.innerR,h=e.open,i=W(f),j=Z(f),k=W(g),g=Z(g),e=e.end-f<Aa?0:1;return["M",a+c*i,b+c*j,"A",c,c,
0,e,1,a+c*k,b+c*g,h?"M":"L",a+d*k,b+d*g,"A",d,d,0,e,0,a+d*i,b+d*j,h?"":"Z"]}},clipRect:function(a,b,c,d){var e="highcharts-"+tb++,f=this.createElement("clipPath").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d=this,e,f=/^rgba/,g,h,i,j,k,l,m,q=[];a&&a.linearGradient?g="linearGradient":a&&a.radialGradient&&(g="radialGradient");if(g){c=a[g];h=d.gradients;j=a.stops;b=b.radialReference;Ia(c)&&(a[g]=c={x1:c[0],y1:c[1],x2:c[2],y2:c[3],
gradientUnits:"userSpaceOnUse"});g==="radialGradient"&&b&&!r(c.gradientUnits)&&x(c,{cx:b[0]-b[2]/2+c.cx*b[2],cy:b[1]-b[2]/2+c.cy*b[2],r:c.r*b[2],gradientUnits:"userSpaceOnUse"});for(m in c)m!=="id"&&q.push(m,c[m]);for(m in j)q.push(j[m]);q=q.join(",");h[q]?a=h[q].id:(c.id=a="highcharts-"+tb++,h[q]=i=d.createElement(g).attr(c).add(d.defs),i.stops=[],o(j,function(a){f.test(a[1])?(e=qa(a[1]),k=e.get("rgb"),l=e.get("a")):(k=a[1],l=1);a=d.createElement("stop").attr({offset:a[0],"stop-color":k,"stop-opacity":l}).add(i);
i.stops.push(a)}));return"url("+d.url+"#"+a+")"}else return f.test(a)?(e=qa(a),w(b,c+"-opacity",e.get("a")),e.get("rgb")):(b.removeAttribute(c+"-opacity"),a)},text:function(a,b,c,d){var e=N.chart.style,f=V||!ca&&this.forExport;if(d&&!this.forExport)return this.html(a,b,c);b=u(n(b,0));c=u(n(c,0));a=this.createElement("text").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,fontSize:e.fontSize});f&&a.css({position:"absolute"});a.x=b;a.y=c;return a},html:function(a,b,c){var d=N.chart.style,e=this.createElement("span"),
f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){a!==g.innerHTML&&delete this.bBox;g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b==="align"&&(b="textAlign");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:u(b),y:u(c)}).css({position:"absolute",whiteSpace:"nowrap",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;if(h.isSVG)e.add=function(a){var b,c=h.box.parentNode,d=[];if(a){if(b=a.div,!b){for(;a;)d.push(a),a=a.parentGroup;o(d.reverse(),function(a){var d;
b=a.div=a.div||T(ga,{className:w(a.element,"class")},{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px"},b||c);d=b.style;x(a.attrSetters,{translateX:function(a){d.left=a+"px"},translateY:function(a){d.top=a+"px"},visibility:function(a,b){d[b]=a}})})}}else b=c;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};return e},fontMetrics:function(a){var a=z(a||11),a=a<24?a+4:u(a*1.2),b=u(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a;
a=y.element.style;H=(s===void 0||yb===void 0||p.styles.textAlign)&&y.getBBox();p.width=(s||H.width||0)+2*v;p.height=(yb||H.height||0)+2*v;zb=v+q.fontMetrics(a&&a.fontSize).b;if(z){if(!n)a=h?-zb:0,p.box=n=d?q.symbol(d,-ra*v,a,p.width,p.height):q.rect(-ra*v,a,p.width,p.height,0,w[wb]),n.add(p);n.attr(B({width:p.width,height:p.height},w));w=null}}function k(){var a=p.styles,a=a&&a.textAlign,b=v*(1-ra),c;c=h?0:zb;if(r(s)&&(a==="center"||a==="right"))b+={center:0.5,right:1}[a]*(s-H.width);(b!==y.x||c!==
y.y)&&y.attr({x:b,y:c});y.x=b;y.y=c}function l(a,b){n?n.attr(a,b):w[a]=b}function m(){y.add(p);p.attr({text:a,x:b,y:c});n&&r(e)&&p.attr({anchorX:e,anchorY:f})}var q=this,p=q.g(i),y=q.text("",0,0,g).attr({zIndex:1}),n,H,ra=0,v=3,s,yb,E,S,Qb=0,w={},zb,g=p.attrSetters,z;J(p,"add",m);g.width=function(a){s=a;return!1};g.height=function(a){yb=a;return!1};g.padding=function(a){r(a)&&a!==v&&(v=a,k());return!1};g.align=function(a){ra={left:0,center:0.5,right:1}[a];return!1};g.text=function(a,b){y.attr(b,a);
j();k();return!1};g[wb]=function(a,b){z=!0;Qb=a%2/2;l(b,a);return!1};g.stroke=g.fill=g.r=function(a,b){b==="fill"&&(z=!0);l(b,a);return!1};g.anchorX=function(a,b){e=a;l(b,a+Qb-E);return!1};g.anchorY=function(a,b){f=a;l(b,a-S);return!1};g.x=function(a){p.x=a;a-=ra*((s||H.width)+v);E=u(a);p.attr("translateX",E);return!1};g.y=function(a){S=p.y=u(a);p.attr("translateY",a);return!1};var C=p.css;return x(p,{css:function(a){if(a){var b={},a=B({},a);o("fontSize,fontWeight,fontFamily,color,lineHeight,width".split(","),
function(c){a[c]!==A&&(b[c]=a[c],delete a[c])});y.css(b)}return C.call(p,a)},getBBox:function(){return{width:H.width+2*v,height:H.height+2*v,x:H.x-v,y:H.y-v}},shadow:function(a){n&&n.shadow(a);return p},destroy:function(){R(p,"add",m);R(p.element,"mouseenter");R(p.element,"mouseleave");y&&(y=y.destroy());n&&(n=n.destroy());ya.prototype.destroy.call(p);p=q=j=k=l=m=null}})}};Sa=sa;var ha;if(!ca&&!V){ha={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ","absolute",";"];(b===
"shape"||b===ga)&&d.push("left:0;top:0;width:1px;height:1px;");Ra&&d.push("visibility: ",b===ga?"hidden":"visible");c.push(' style="',d.join(""),'"/>');if(b)c=b===ga||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=T(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();F(this,"add");return this},
updateTransform:ya.prototype.htmlUpdateTransform,attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,l=this.shadows,m,q=this.attrSetters,p=this;ja(a)&&r(b)&&(c=a,a={},a[c]=b);if(ja(a))c=a,p=c==="strokeWidth"||c==="stroke-width"?this.strokeweight:this[c];else for(c in a)if(d=a[c],m=!1,e=q[c]&&q[c].call(this,d,c),e!==!1&&d!==null){e!==A&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a),k=!0),m=
!0;else if(c==="d"){d=d||[];this.d=d.join(" ");e=d.length;for(m=[];e--;)m[e]=Da(d[e])?u(d[e]*10)-5:d[e]==="Z"?"x":d[e];d=m.join(" ")||"x";f.path=d;if(l)for(e=l.length;e--;)l[e].path=l[e].cutOff?this.cutOffPath(d,l[e].cutOff):d;m=!0}else if(c==="visibility"){if(l)for(e=l.length;e--;)l[e].style[c]=d;h==="DIV"&&(d=d==="hidden"?"-999em":0,c="top");g[c]=d;m=!0}else if(c==="zIndex")d&&(g[c]=d),m=!0;else if(c==="width"||c==="height")d=s(0,d),this[c]=d,this.updateClipping?(this[c]=d,this.updateClipping()):
g[c]=d,m=!0;else if(c==="x"||c==="y")this[c]=d,g[{x:"left",y:"top"}[c]]=d;else if(c==="class")f.className=d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,Da(d)&&(d+="px");else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||T(i.prepVML(["<stroke/>"]),null,null,f))[c]=d||"solid",this.dashstyle=d,m=!0;else if(c==="fill")if(h==="SPAN")g.color=d;else{if(h!=="IMG")f.filled=d!==Q?!0:!1,d=i.color(d,
f,c,this),c="fillcolor"}else if(h==="shape"&&c==="rotation")this[c]=d,f.style.left=-u(Z(d*ab)+1)+"px",f.style.top=u(W(d*ab))+"px";else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),m=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,m=!0;m||(Ra?f[c]=d:w(f,c,d))}return p},clip:function(a){var b=this,c,d=b.element,e=d.parentNode;a?(c=a.members,ta(c,b),c.push(b),b.destroyClip=function(){ta(c,b)},e&&e.className==="highcharts-tracker"&&!Ra&&I(d,{visibility:"hidden"}),
a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:Ra?"inherit":"rect(auto)"});return b.css(a)},css:ya.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Na(a)},destroy:function(){this.destroyClip&&this.destroyClip();return ya.prototype.destroy.apply(this)},empty:function(){for(var a=this.element.childNodes,b=a.length,c;b--;)c=a[b],c.parentNode.removeChild(c)},on:function(a,b){this.element["on"+a]=function(){var a=L.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,
b){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=z(a[c-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,l,m,q,p;k&&typeof k.value!=="string"&&(k="x");m=k;if(a){q=n(a.width,3);p=(a.opacity||0.15)/q;for(e=1;e<=3;e++){l=q*2+1-2*e;c&&(m=this.cutOffPath(k.value,l+0.5));j=['<shape isShadow="true" strokeweight="',l,'" filled="false" path="',m,'" coordsize="10 10" style="',f.style.cssText,'" />'];h=T(g.prepVML(j),null,
{left:z(i.left)+n(a.offsetX,1),top:z(i.top)+n(a.offsetY,1)});if(c)h.cutOff=l+1;j=['<stroke color="',a.color||"black",'" opacity="',p*e,'"/>'];T(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};ha=ba(ya,ha);var fa={Element:ha,isIE8:na.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(ga);e=d.element;e.style.position="relative";a.appendChild(d.element);this.box=e;this.boxWrapper=d;
this.setSize(b,c,!1);if(!C.namespaces.hcv)C.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),C.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=Y(a);return x(e,{members:[],left:f?a.x:a,top:f?a.y:b,width:f?a.width:c,height:f?a.height:d,getCSS:function(a){var b=a.inverted,c=this.top,d=this.left,e=d+this.width,
f=c+this.height,c={clip:"rect("+u(b?d:c)+"px,"+u(b?f:e)+"px,"+u(b?e:f)+"px,"+u(b?c:d)+"px)"};!b&&Ra&&a.element.nodeName!=="IMG"&&x(c,{width:e+"px",height:f+"px"});return c},updateClipping:function(){o(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=Q;a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern");if(i){var k,l,m=a.linearGradient||a.radialGradient,q,p,n,t,H,r="",a=a.stops,v,s=[],u=function(){h=['<fill colors="'+s.join(",")+'" opacity="',
n,'" o:opacity2="',p,'" type="',i,'" ',r,'focus="100%" method="any" />'];T(e.prepVML(h),null,null,b)};q=a[0];v=a[a.length-1];q[0]>0&&a.unshift([0,q[1]]);v[0]<1&&a.push([1,v[1]]);o(a,function(a,b){g.test(a[1])?(f=qa(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1);s.push(a[0]*100+"% "+k);b?(n=l,t=k):(p=l,H=k)});if(c==="fill")if(i==="gradient")c=m.x1||m[0]||0,a=m.y1||m[1]||0,q=m.x2||m[2]||0,m=m.y2||m[3]||0,r='angle="'+(90-K.atan((m-a)/(q-c))*180/Aa)+'"',u();else{var j=m.r,E=j*2,S=j*2,x=m.cx,A=m.cy,w=
b.radialReference,z,j=function(){w&&(z=d.getBBox(),x+=(w[0]-z.x)/z.width-0.5,A+=(w[1]-z.y)/z.height-0.5,E*=w[2]/z.width,S*=w[2]/z.height);r='src="'+N.global.VMLRadialGradientURL+'" size="'+E+","+S+'" origin="0.5,0.5" position="'+x+","+A+'" color2="'+H+'" ';u()};d.added?j():J(d,"add",j);j=t}else j=k}else if(g.test(a)&&b.tagName!=="IMG")f=qa(a),h=["<",c,' opacity="',f.get("a"),'"/>'],T(this.prepVML(h),null,null,b),j=f.get("rgb");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1;j=a}return j},
prepVML:function(a){var b=this.isIE8,a=a.join("");b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===-1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:");return a},text:sa.prototype.html,path:function(a){var b={coordsize:"10 10"};Ia(a)?b.d=a:Y(a)&&x(b,a);return this.createElement("shape").attr(b)},circle:function(a,b,c){return this.symbol("circle").attr({x:a-
c,y:b-c,width:2*c,height:2*c})},g:function(a){var b;a&&(b={className:"highcharts-"+a,"class":"highcharts-"+a});return this.createElement(ga).attr(b)},image:function(a,b,c,d,e){var f=this.createElement("img").attr({src:a});arguments.length>1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){if(Y(a))b=a.y,c=a.width,d=a.height,f=a.strokeWidth,a=a.x;var g=this.symbol("rect");g.r=e;return g.attr(g.crisp(f,a,b,s(c,0),s(d,0)))},invertChild:function(a,b){var c=b.style;I(a,{flip:"x",
left:z(c.width)-1,top:z(c.height)-1,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=W(f),d=Z(f),i=W(g),j=Z(g),k=e.innerR,l=0.08/h,m=k&&0.1/k||0;if(g-f===0)return["x"];else 2*Aa-g+f<l?i=-l:g-f<m&&(i=W(f+m));f=["wa",a-h,b-h,a+h,b+h,a+h*c,b+h*d,a+h*i,b+h*j];e.open&&!k&&f.push("e","M",a,b);f.push("at",a-k,b-k,a+k,b+k,a+k*i,b+k*j,a+k*c,b+k*d,"x","e");return f},circle:function(a,b,c,d){return["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){var f=
a+c,g=b+d,h;!r(e)||!e.r?f=sa.prototype.symbols.square.apply(0,arguments):(h=O(e.r,c,d),f=["M",a+h,b,"L",f-h,b,"wa",f-2*h,b,f,b+2*h,f-h,b,f,b+h,"L",f,g-h,"wa",f-2*h,g-2*h,f,g,f,g-h,f-h,g,"L",a+h,g,"wa",a,g-2*h,a+2*h,g,a+h,g,a,g-h,"L",a,b+h,"wa",a,b,a+2*h,b+2*h,a,b+h,a+h,b,"x","e"]);return f}}};ha=function(){this.init.apply(this,arguments)};ha.prototype=B(sa.prototype,fa);Sa=ha}var gb,Rb;if(V)gb=function(){oa="http://www.w3.org/1999/xhtml"},gb.prototype.symbols={},Rb=function(){function a(){var a=b.length,
d;for(d=0;d<a;d++)b[d]();b=[]}var b=[];return{push:function(c,d){b.length===0&&Tb(d,a);b.push(c)}}}();Sa=ha||gb||sa;Qa.prototype={addLabel:function(){var a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=this.pos,g=b.labels,h=a.tickPositions,d=e&&d&&e.length&&!g.step&&!g.staggerLines&&!g.rotation&&c.plotWidth/h.length||!d&&c.plotWidth/2,i=f===h[0],j=f===h[h.length-1],k=e&&r(e[f])?e[f]:f,e=this.label,h=h.info,l;a.isDatetimeAxis&&h&&(l=b.dateTimeLabelFormats[h.higherRanks[f]||h.unitName]);
this.isFirst=i;this.isLast=j;b=a.labelFormatter.call({axis:a,chart:c,isFirst:i,isLast:j,dateTimeLabelFormat:l,value:a.isLog?da(aa(k)):k});f=d&&{width:s(1,u(d-2*(g.padding||10)))+"px"};f=x(f,g.style);if(r(e))e&&e.attr({text:b}).css(f);else{d={align:g.align};if(Da(g.rotation))d.rotation=g.rotation;this.label=r(b)&&g.enabled?c.renderer.text(b,0,0,g.useHTML).attr(d).css(f).add(a.labelGroup):null}},getLabelSize:function(){var a=this.label,b=this.axis;return a?(this.labelBBox=a.getBBox())[b.horiz?"height":
"width"]:0},getLabelSides:function(){var a=this.axis.options.labels,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.align]-a.x;return[-a,b-a]},handleOverflow:function(a,b){var c=!0,d=this.axis,e=d.chart,f=this.isFirst,g=this.isLast,h=b.x,i=d.reversed,j=d.tickPositions;if(f||g){var k=this.getLabelSides(),l=k[0],k=k[1],e=e.plotLeft,m=e+d.len,j=(d=d.ticks[j[a+(f?1:-1)]])&&d.label.xy&&d.label.xy.x+d.getLabelSides()[f?0:1];f&&!i||g&&i?h+l<e&&(h=e-l,d&&h+k>j&&(c=!1)):h+k>m&&(h=m-k,d&&h+l<j&&(c=
!1));b.x=h}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,i=i.staggerLines,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):0);r(e.y)||
(b+=z(c.styles.lineHeight)*0.9-c.getBBox().height/2);i&&(b+=g/(h||1)%i*16);return{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine(["M",a,b,"L",a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b){var c=this.axis,d=c.options,e=c.chart.renderer,f=c.horiz,g=this.type,h=this.label,i=this.pos,j=d.labels,k=this.gridLine,l=g?g+"Grid":"grid",m=g?g+"Tick":"tick",q=d[l+"LineWidth"],p=d[l+"LineColor"],y=d[l+"LineDashStyle"],t=d[m+"Length"],l=d[m+"Width"]||0,o=d[m+"Color"],r=d[m+"Position"],m=this.mark,
v=j.step,s=!0,u=c.tickmarkOffset,E=this.getPosition(f,i,u,b),S=E.x,E=E.y,x=c.staggerLines;if(q){i=c.getPlotLinePath(i+u,q,b);if(k===A){k={stroke:p,"stroke-width":q};if(y)k.dashstyle=y;if(!g)k.zIndex=1;this.gridLine=k=q?e.path(i).attr(k).add(c.gridGroup):null}if(!b&&k&&i)k[this.isNew?"attr":"animate"]({d:i})}if(l&&t)r==="inside"&&(t=-t),c.opposite&&(t=-t),g=this.getMarkPath(S,E,t,l,f,e),m?m.animate({d:g}):this.mark=e.path(g).attr({stroke:o,"stroke-width":l}).add(c.axisGroup);if(h&&!isNaN(S))h.xy=E=
this.getLabelPosition(S,E,h,f,j,u,a,v),this.isFirst&&!n(d.showFirstLabel,1)||this.isLast&&!n(d.showLastLabel,1)?s=!1:!x&&f&&j.overflow==="justify"&&!this.handleOverflow(a,E)&&(s=!1),v&&a%v&&(s=!1),s?(h[this.isNew?"attr":"animate"](E),this.isNew=!1):h.attr("y",-9999)},destroy:function(){Ga(this,this.axis)}};nb.prototype={render:function(){var a=this,b=a.axis,c=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=r(j)&&r(i),l=e.value,m=e.dashStyle,q=a.svgElem,p=
[],y,t=e.color,o=e.zIndex,u=e.events,v=b.chart.renderer;b.isLog&&(j=ka(j),i=ka(i),l=ka(l));if(h){if(p=b.getPlotLinePath(l,h),d={stroke:t,"stroke-width":h},m)d.dashstyle=m}else if(k){if(j=s(j,b.min-d),i=O(i,b.max+d),p=b.getPlotBandPath(j,i,e),d={fill:t},e.borderWidth)d.stroke=e.borderColor,d["stroke-width"]=e.borderWidth}else return;if(r(o))d.zIndex=o;if(q)p?q.animate({d:p},null,q.onGetPath):(q.hide(),q.onGetPath=function(){q.show()});else if(p&&p.length&&(a.svgElem=q=v.path(p).attr(d).add(),u))for(y in e=
function(b){q.on(b,function(c){u[b].apply(a,[c])})},u)e(y);if(f&&r(f.text)&&p&&p.length&&b.width>0&&b.height>0){f=B({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=v.text(f.text,0,0).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:o}).css(f.style).add();b=[p[1],p[4],n(p[6],p[1])];p=[p[2],p[5],n(p[7],p[2])];c=Fa(b);k=Fa(p);g.align(f,!1,{x:c,y:k,width:wa(b)-c,height:wa(p)-k});g.show()}else g&&g.hide();return a},destroy:function(){ta(this.axis.plotLinesAndBands,
this);Ga(this,this.axis)}};Kb.prototype={destroy:function(){Ga(this,this.axis)},setTotal:function(a){this.cum=this.total=a},render:function(a){var b=this.options.formatter.call(this);this.label?this.label.attr({text:b,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(b,0,0).css(this.options.style).attr({align:this.textAlign,rotation:this.options.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,g=c.translate(this.percent?
100:this.total,0,0,0,1),c=c.translate(0),c=M(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?ca?"inherit":"visible":"hidden"})}};ob.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},
endOnTick:!1,gridLineColor:"#C0C0C0",labels:G,lineColor:"#C0D0E0",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#6D869F",fontWeight:"bold"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,
tickPixelInterval:72,showLastLabel:!0,labels:{align:"right",x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Y-values"},stackLabels:{enabled:!1,formatter:function(){return this.total},style:G.style}},defaultLeftAxisOptions:{labels:{align:"right",x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{align:"left",x:8,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{align:"center",x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{align:"center",
x:0,y:-5},title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c;this.xOrY=(this.isXAxis=c)?"x":"y";this.opposite=b.opposite;this.side=this.horiz?this.opposite?0:2:this.opposite?1:3;this.setOptions(b);var d=this.options,e=d.type,f=e==="datetime";this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.staggerLines=this.horiz&&d.labels.staggerLines;this.userOptions=b;this.minPixelPadding=0;this.chart=a;this.reversed=d.reversed;this.categories=d.categories;this.isLog=
e==="logarithmic";this.isLinked=r(d.linkedTo);this.isDatetimeAxis=f;this.tickmarkOffset=d.categories&&d.tickmarkPlacement==="between"?0.5:0;this.ticks={};this.minorTicks={};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;this.stacks={};this.min=this.max=null;var g,d=this.options.events;a.axes.push(this);a[c?"xAxis":"yAxis"].push(this);this.series=[];if(a.inverted&&c&&this.reversed===A)this.reversed=
!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;this.addPlotLine=this.addPlotBand=this.addPlotBandOrLine;for(g in d)J(this,g,d[g]);if(this.isLog)this.val2lin=ka,this.lin2val=aa},setOptions:function(a){this.options=B(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],B(N[this.isXAxis?"xAxis":"yAxis"],a))},defaultLabelFormatter:function(){var a=
this.axis,b=this.value,c=this.dateTimeLabelFormat,d=N.lang.numericSymbols,e=d&&d.length,f,g=a.isLog?b:a.tickInterval;if(a.categories)f=b;else if(c)f=db(c,b);else if(e&&g>=1E3)for(;e--&&f===A;)a=Math.pow(1E3,e+1),g>=a&&d[e]!==null&&(f=Ja(b/a,-1)+d[e]);f===A&&(f=b>=1E3?Ja(b,0):Ja(b,-1));return f},getSeriesExtremes:function(){var a=this,b=a.chart,c=a.stacks,d=[],e=[],f;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;o(a.series,function(g){if(g.visible||!b.options.chart.ignoreHiddenSeries){var h=g.options,
i,j,k,l,m,q,p,y,t,o=h.threshold,u,v=[],x=0;a.hasVisibleSeries=!0;if(a.isLog&&o<=0)o=h.threshold=null;if(a.isXAxis){if(h=g.xData,h.length)a.dataMin=O(n(a.dataMin,h[0]),Fa(h)),a.dataMax=s(n(a.dataMax,h[0]),wa(h))}else{var z,E,S,w=g.cropped,B=g.xAxis.getExtremes(),C=!!g.modifyValue;i=h.stacking;a.usePercentage=i==="percent";if(i)m=h.stack,l=g.type+n(m,""),q="-"+l,g.stackKey=l,j=d[l]||[],d[l]=j,k=e[q]||[],e[q]=k;if(a.usePercentage)a.dataMin=0,a.dataMax=99;h=g.processedXData;p=g.processedYData;u=p.length;
for(f=0;f<u;f++)if(y=h[f],t=p[f],i&&(E=(z=t<o)?k:j,S=z?q:l,r(E[y])?(E[y]=da(E[y]+t),t=[t,E[y]]):E[y]=t,c[S]||(c[S]={}),c[S][y]||(c[S][y]=new Kb(a,a.options.stackLabels,z,y,m,i)),c[S][y].setTotal(E[y])),t!==null&&t!==A&&(C&&(t=g.modifyValue(t)),w||(h[f+1]||y)>=B.min&&(h[f-1]||y)<=B.max))if(y=t.length)for(;y--;)t[y]!==null&&(v[x++]=t[y]);else v[x++]=t;if(!a.usePercentage&&v.length)a.dataMin=O(n(a.dataMin,v[0]),Fa(v)),a.dataMax=s(n(a.dataMax,v[0]),wa(v));if(r(o))if(a.dataMin>=o)a.dataMin=o,a.ignoreMinPadding=
!0;else if(a.dataMax<o)a.dataMax=o,a.ignoreMaxPadding=!0}}})},translate:function(a,b,c,d,e,f){var g=this.len,h=1,i=0,j=d?this.oldTransA:this.transA,d=d?this.oldMin:this.min,e=this.options.ordinal||this.isLog&&e;if(!j)j=this.transA;c&&(h*=-1,i=g);this.reversed&&(h*=-1,i-=h*g);b?(this.reversed&&(a=g-a),a=a/j+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),a=h*(a-d)*j+i+h*this.minPixelPadding+(f?j*this.pointRange/2:0));return a},getPlotLinePath:function(a,b,c){var d=this.chart,e=this.left,f=this.top,
g,h,i,a=this.translate(a,null,null,c),j=c&&d.oldChartHeight||d.chartHeight,k=c&&d.oldChartWidth||d.chartWidth,l;g=this.transB;c=h=u(a+g);g=i=u(j-a-g);if(isNaN(a))l=!0;else if(this.horiz){if(g=f,i=j-this.bottom,c<e||c>e+this.width)l=!0}else if(c=e,h=k-this.right,g<f||g>f+this.height)l=!0;return l?null:d.renderer.crispLine(["M",c,g,"L",h,i],b||0)},getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],c[5],c[1],c[2]):d=null;return d},getLinearTickPositions:function(a,
b,c){for(var d,b=da(U(b/a)*a),c=da(za(c/a)*a),e=[];b<=c;){e.push(b);b=da(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=u(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=U(b),h,i,j,k,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];f<c+1&&!l;f++){i=e.length;for(h=0;h<i&&!l;h++)j=ka(aa(f)*e[h]),j>b&&g.push(k),k>c&&(l=!0),k=j}else if(b=aa(b),c=aa(c),a=e[d?"minorTickInterval":
"tickInterval"],a=n(a==="auto"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=hb(a,null,K.pow(10,U(K.log(a)/K.LN10))),g=Ta(this.getLinearTickPositions(a,b,c),ka),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[],e;if(this.isLog){e=b.length;for(a=1;a<e;a++)d=d.concat(this.getLogTickPositions(c,b[a-1],b[a],!0))}else if(this.isDatetimeAxis&&
a.minorTickInterval==="auto")d=d.concat(Cb(Ab(c),this.min,this.max,a.startOfWeek));else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var a=this.options,b=this.min,c=this.max,d,e=this.dataMax-this.dataMin>=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===A&&!this.isLog)r(a.min)||r(a.max)?this.minRange=null:(o(this.series,function(a){i=a.xData;for(g=j=a.xIncrement?1:i.length-1;g>0;g--)if(h=i[g]-i[g-1],f===A||h<f)f=h}),this.minRange=O(f*5,
this.dataMax-this.dataMin));if(c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2;d=[b-d,n(a.min,b-d)];if(e)d[2]=this.dataMin;b=wa(d);c=[b+k,n(a.max,b+k)];if(e)c[2]=this.dataMax;c=Fa(c);c-b<k&&(d[0]=c-k,d[1]=n(a.min,c-k),b=wa(d))}this.min=b;this.max=c},setAxisTranslation:function(){var a=this.max-this.min,b=0,c,d=0,e=0,f=this.linkedParent,g=this.transA;if(this.isXAxis)f?(d=f.minPointOffset,e=f.pointRangePadding):o(this.series,function(a){var f=a.pointRange,g=a.options.pointPlacement,k=a.closestPointRange;
b=s(b,f);d=s(d,g?0:f/2);e=s(e,g==="on"?0:f);!a.noSharedTooltip&&r(k)&&(c=r(c)?O(c,k):k)}),this.minPointOffset=d,this.pointRangePadding=e,this.pointRange=b,this.closestPointRange=c;this.oldTransA=g;this.translationSlope=this.transA=g=this.len/(a+e||1);this.transB=this.horiz?this.left:this.bottom;this.minPixelPadding=g*d},setTickPositions:function(a){var b=this,c=b.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,l=d.tickInterval,
m=d.minTickInterval,q=d.tickPixelInterval,p=b.categories;h?(b.linkedParent=c[g?"xAxis":"yAxis"][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=n(c.min,c.dataMin),b.max=n(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&Oa(11,1)):(b.min=n(b.userMin,d.min,b.dataMin),b.max=n(b.userMax,d.max,b.dataMax));if(e)!a&&O(b.min,n(b.dataMin,b.min))<=0&&Oa(10,1),b.min=da(ka(b.min)),b.max=da(ka(b.max));if(b.range&&(b.userMin=b.min=s(b.min,b.max-b.range),b.userMax=b.max,a))b.range=null;b.adjustForMinRange();
if(!p&&!b.usePercentage&&!h&&r(b.min)&&r(b.max)&&(c=b.max-b.min)){if(!r(d.min)&&!r(b.userMin)&&k&&(b.dataMin<0||!b.ignoreMinPadding))b.min-=c*k;if(!r(d.max)&&!r(b.userMax)&&j&&(b.dataMax>0||!b.ignoreMaxPadding))b.max+=c*j}b.tickInterval=b.min===b.max||b.min===void 0||b.max===void 0?1:h&&!l&&q===b.linkedParent.options.tickPixelInterval?b.linkedParent.tickInterval:n(l,p?1:(b.max-b.min)*q/(b.len||1));g&&!a&&o(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(a);
b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval);if(!l&&b.tickInterval<m)b.tickInterval=m;if(!f&&!e&&(a=K.pow(10,U(K.log(b.tickInterval)/K.LN10)),!l))b.tickInterval=hb(b.tickInterval,null,a,d);b.minorTickInterval=d.minorTickInterval==="auto"&&b.tickInterval?b.tickInterval/5:d.minorTickInterval;b.tickPositions=i=d.tickPositions||i&&i.apply(b,[b.min,b.max]);if(!i)i=f?(b.getNonLinearTimeTicks||Cb)(Ab(b.tickInterval,
d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,b.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),b.tickPositions=i;if(!h)e=i[0],f=i[i.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&i.shift(),d.endOnTick?b.max=f:b.max+h<f&&i.pop(),i.length===1&&(b.min-=1.0E-9,b.max+=1.0E-9)},setMaxTicks:function(){var a=this.chart,b=a.maxTicks,c=this.tickPositions,d=this.xOrY;b||(b={x:0,y:0});if(!this.isLinked&&
!this.isDatetimeAxis&&c.length>b[d]&&this.options.alignTicks!==!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this.xOrY,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(e<a){for(;b.length<a;)b.push(da(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a-1);this.max=b[b.length-1]}if(r(d)&&a!==d)this.isDirty=!0}},setScale:function(){var a=
this.stacks,b,c,d,e;this.oldMin=this.min;this.oldMax=this.max;this.oldAxisLength=this.len;this.setAxisSize();e=this.len!==this.oldAxisLength;o(this.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)d=!0});if(e||d||this.isLinked||this.userMin!==this.oldUserMin||this.userMax!==this.oldUserMax)if(this.getSeriesExtremes(),this.setTickPositions(),this.oldUserMin=this.userMin,this.oldUserMax=this.userMax,!this.isDirty)this.isDirty=e||this.min!==this.oldMin||this.max!==this.oldMax;if(!this.isXAxis)for(b in a)for(c in a[b])a[b][c].cum=
a[b][c].total;this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=n(c,!0),e=x(e,{min:a,max:b});F(f,"setExtremes",e,function(){f.userMin=a;f.userMax=b;f.isDirtyExtremes=!0;c&&g.redraw(d)})},zoom:function(a,b){this.setExtremes(a,b,!1,A,{trigger:"zoom"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=b.offsetRight||0;this.left=n(b.left,a.plotLeft+c);this.top=n(b.top,a.plotTop);this.width=n(b.width,a.plotWidth-c+d);this.height=n(b.height,a.plotHeight);
this.bottom=a.chartHeight-this.height-this.top;this.right=a.chartWidth-this.width-this.left;this.len=s(this.horiz?this.width:this.height,0)},getExtremes:function(){var a=this.isLog;return{min:a?da(aa(this.min)):this.min,max:a?da(aa(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?aa(this.min):this.min,b=b?aa(this.max):this.max;c>a||a===null?a=c:b<a&&(a=b);return this.translate(a,0,1,0,1)},addPlotBandOrLine:function(a){a=
(new nb(this,a)).render();this.plotLinesAndBands.push(a);return a},getOffset:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i,j=0,k,l=0,m=d.title,q=d.labels,p=0,y=b.axisOffset,t=[-1,1,1,-1][h],H;a.hasData=b=a.hasVisibleSeries||r(a.min)&&r(a.max)&&!!e;a.showAxis=i=b||n(d.showEmpty,!0);if(!a.axisGroup)a.gridGroup=c.g("grid").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g("axis-labels").attr({zIndex:q.zIndex||
7}).add();if(b||a.isLinked)o(e,function(b){f[b]?f[b].addLabel():f[b]=new Qa(a,b)}),o(e,function(a){if(h===0||h===2||{1:"left",3:"right"}[h]===q.align)p=s(f[a].getLabelSize(),p)}),a.staggerLines&&(p+=(a.staggerLines-1)*16);else for(H in f)f[H].destroy(),delete f[H];if(m&&m.text){if(!a.axisTitle)a.axisTitle=c.text(m.text,0,0,m.useHTML).attr({zIndex:7,rotation:m.rotation||0,align:m.textAlign||{low:"left",middle:"center",high:"right"}[m.align]}).css(m.style).add(a.axisGroup),a.axisTitle.isNew=!0;if(i)j=
a.axisTitle.getBBox()[g?"height":"width"],l=n(m.margin,g?5:10),k=m.offset;a.axisTitle[i?"show":"hide"]()}a.offset=t*n(d.offset,y[h]);a.axisTitleMargin=n(k,p+l+(h!==2&&p&&t*d.labels[g?"y":"x"]));y[h]=s(y[h],a.axisTitleMargin+j+t*a.offset)},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d;this.lineTop=c=b.chartHeight-this.bottom-(c?this.height:0)+d;return b.renderer.crispLine(["M",e?this.left:f,e?c:this.top,"L",e?b.chartWidth-this.right:
f,e?c:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=z(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(this.side===2?i:0);return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.isLog,f=a.isLinked,
g=a.tickPositions,h=a.axisTitle,i=a.stacks,j=a.ticks,k=a.minorTicks,l=a.alternateBands,m=d.stackLabels,q=d.alternateGridColor,p=a.tickmarkOffset,n=d.lineWidth,t,H=b.hasRendered&&r(a.oldMin)&&!isNaN(a.oldMin),u=a.showAxis,v,s;if(a.hasData||f)if(a.minorTickInterval&&!a.categories&&o(a.getMinorTickPositions(),function(b){k[b]||(k[b]=new Qa(a,b,"minor"));H&&k[b].isNew&&k[b].render(null,!0);k[b].isActive=!0;k[b].render()}),g.length&&o(g.slice(1).concat([g[0]]),function(b,c){c=c===g.length-1?0:c+1;if(!f||
b>=a.min&&b<=a.max)j[b]||(j[b]=new Qa(a,b)),H&&j[b].isNew&&j[b].render(c,!0),j[b].isActive=!0,j[b].render(c)}),q&&o(g,function(b,c){if(c%2===0&&b<a.max)l[b]||(l[b]=new nb(a)),v=b+p,s=g[c+1]!==A?g[c+1]+p:a.max,l[b].options={from:e?aa(v):v,to:e?aa(s):s,color:q},l[b].render(),l[b].isActive=!0}),!a._addedPlotLB)o((d.plotLines||[]).concat(d.plotBands||[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0;o([j,k,l],function(a){for(var b in a)a[b].isActive?a[b].isActive=!1:(a[b].destroy(),delete a[b])});
if(n)t=a.getLinePath(n),a.axisLine?a.axisLine.animate({d:t}):a.axisLine=c.path(t).attr({stroke:d.lineColor,"stroke-width":n,zIndex:7}).add(a.axisGroup),a.axisLine[u?"show":"hide"]();if(h&&u)h[h.isNew?"attr":"animate"](a.getTitlePosition()),h.isNew=!1;if(m&&m.enabled){var x,E,d=a.stackTotalGroup;if(!d)a.stackTotalGroup=d=c.g("stack-labels").attr({visibility:"visible",zIndex:6}).add();d.translate(b.plotLeft,b.plotTop);for(x in i)for(E in b=i[x],b)b[E].render(d)}a.isDirty=!1},removePlotBandOrLine:function(a){for(var b=
this.plotLinesAndBands,c=b.length;c--;)b[c].id===a&&b[c].destroy()},setTitle:function(a,b){var c=this.chart,d=this.options,e=this.axisTitle;d.title=B(d.title,a);this.axisTitle=e&&e.destroy();this.isDirty=!0;n(b,!0)&&c.redraw()},redraw:function(){var a=this.chart;a.tracker.resetTracker&&a.tracker.resetTracker(!0);this.render();o(this.plotLinesAndBands,function(a){a.render()});o(this.series,function(a){a.isDirty=!0})},setCategories:function(a,b){var c=this.chart;this.categories=this.userOptions.categories=
a;o(this.series,function(a){a.translate();a.setTooltipPoints(!0)});this.isDirty=!0;n(b,!0)&&c.redraw()},destroy:function(){var a=this,b=a.stacks,c;R(a);for(c in b)Ga(b[c]),b[c]=null;o([a.ticks,a.minorTicks,a.alternateBands,a.plotLinesAndBands],function(a){Ga(a)});o("stackTotalGroup,axisLine,axisGroup,gridGroup,labelGroup,axisTitle".split(","),function(b){a[b]&&(a[b]=a[b].destroy())})}};pb.prototype={destroy:function(){o(this.crosshairs,function(a){a&&a.destroy()});if(this.label)this.label=this.label.destroy()},
move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden;x(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:g?(2*f.anchorX+c)/3:c,anchorY:g?(f.anchorY+d)/2:d});e.label.attr(f);if(g&&(M(a-f.x)>1||M(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){if(!this.isHidden){var a=this.chart.hoverPoints;this.label.hide();a&&o(a,function(a){a.setState()});this.chart.hoverPoints=null;this.isHidden=!0}},hideCrosshairs:function(){o(this.crosshairs,
function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f=0,g=0,h,a=la(a);c=a[0].tooltipPos;c||(o(a,function(a){h=a.series.yAxis;f+=a.plotX;g+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&h?h.top-d.plotTop:0)}),f/=a.length,g/=a.length,c=[e?d.plotWidth-g:f,this.shared&&!e&&a.length>1&&b?b.chartY-d.plotTop:e?d.plotHeight-f:g]);return Ta(c,u)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=n(this.options.distance,12),
j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,l;d<7&&(d=e+s(j,0)+i);d+a>e+g&&(d-=d+a-(e+g),k=c-b+f-i,l=!0);k<f+5&&(k=f+5,l&&c>=k&&c<=k+b&&(k=c+f+i));k+b>f+h&&(k=s(f,f+h-b-i));return{x:d,y:k}},refresh:function(a,b){function c(){var a=this.points||la(this),b=a[0].series,c;c=[b.tooltipHeaderFormatter(a[0].key)];o(a,function(a){b=a.series;c.push(b.tooltipFormatter&&b.tooltipFormatter(a)||a.point.tooltipFormatter(b.tooltipOptions.pointFormat))});c.push(f.footerFormat||"");return c.join("")}
var d=this.chart,e=this.label,f=this.options,g,h,i,j={},k,l=[];k=f.formatter||c;var j=d.hoverPoints,m,q=f.crosshairs;i=this.shared;h=this.getAnchor(a,b);g=h[0];h=h[1];i&&(!a.series||!a.series.noSharedTooltip)?(d.hoverPoints=a,j&&o(j,function(a){a.setState()}),o(a,function(a){a.setState("hover");l.push(a.getLabelConfig())}),j={x:a[0].category,y:a[0].y},j.points=l,a=a[0]):j=a.getLabelConfig();k=k.call(j);j=a.series;i=i||!j.isCartesian||j.tooltipOutsidePlot||d.isInsidePlot(g,h);k===!1||!i?this.hide():
(this.isHidden&&e.show(),e.attr({text:k}),m=f.borderColor||a.color||j.color||"#606060",e.attr({stroke:m}),e=(f.positioner||this.getPosition).call(this,e.width,e.height,{plotX:g,plotY:h}),this.move(u(e.x),u(e.y),g+d.plotLeft,h+d.plotTop),this.isHidden=!1);if(q){q=la(q);for(e=q.length;e--;)if(i=a.series[e?"yAxis":"xAxis"],q[e]&&i)if(i=i.getPlotLinePath(e?n(a.stackY,a.y):a.x,1),this.crosshairs[e])this.crosshairs[e].attr({d:i,visibility:"visible"});else{j={"stroke-width":q[e].width||1,stroke:q[e].color||
"#C0C0C0",zIndex:q[e].zIndex||2};if(q[e].dashStyle)j.dashstyle=q[e].dashStyle;this.crosshairs[e]=d.renderer.path(i).attr(j).add()}}F(d,"tooltipRefresh",{text:k,x:g+d.plotLeft,y:h+d.plotTop,borderColor:m})}};qb.prototype={normalizeMouseEvent:function(a){var b,c,d,a=a||L.event;if(!a.target)a.target=a.srcElement;a=Pb(a);d=a.touches?a.touches.item(0):a;this.chartPosition=b=Vb(this.chart.container);d.pageX===A?(c=a.x,b=a.y):(c=d.pageX-b.left,b=d.pageY-b.top);return x(a,{chartX:u(c),chartY:u(b)})},getMouseCoordinates:function(a){var b=
{xAxis:[],yAxis:[]},c=this.chart;o(c.axes,function(d){var e=d.isXAxis;b[e?"xAxis":"yAxis"].push({axis:d,value:d.translate(((c.inverted?!e:e)?a.chartX-c.plotLeft:d.top+d.len-a.chartY)-d.minPixelPadding,!0)})});return b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},onmousemove:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g||
!g.noSharedTooltip)){e=[];h=c.length;for(i=0;i<h;i++)if(c[i].visible&&c[i].options.enableMouseTracking!==!1&&!c[i].noSharedTooltip&&c[i].tooltipPoints&&c[i].tooltipPoints.length)b=c[i].tooltipPoints[k],b._dist=M(k-b[c[i].xAxis.tooltipPosName||"plotX"]),j=O(j,b._dist),e.push(b);for(h=e.length;h--;)e[h]._dist>j&&e.splice(h,1);if(e.length&&e[0].plotX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].plotX}if(g&&g.tracker&&(b=g.tooltipPoints[k])&&b!==f)b.onMouseOver()},resetTracker:function(a){var b=this.chart,
c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&&la(b)[0].plotX===A&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());this.hoverX=null}},setDOMEvents:function(){function a(){if(b.selectionMarker){var f={xAxis:[],yAxis:[]},g=b.selectionMarker.getBBox(),h=g.x-c.plotLeft,l=g.y-c.plotTop,m;e&&(o(c.axes,function(a){if(a.options.zoomEnabled!==!1){var b=a.isXAxis,d=c.inverted?!b:b,e=a.translate(d?h:c.plotHeight-l-
g.height,!0,0,0,1),d=a.translate((d?h+g.width:c.plotHeight-l)-2*a.minPixelPadding,!0,0,0,1);!isNaN(e)&&!isNaN(d)&&(f[b?"xAxis":"yAxis"].push({axis:a,min:O(e,d),max:s(e,d)}),m=!0)}}),m&&F(c,"selection",f,function(a){c.zoom(a)}));b.selectionMarker=b.selectionMarker.destroy()}if(c)I(d,{cursor:"auto"}),c.cancelClick=e,c.mouseIsDown=e=!1;R(C,"mouseup",a);Ba&&R(C,"touchend",a)}var b=this,c=b.chart,d=c.container,e,f=b.zoomX&&!c.inverted||b.zoomY&&c.inverted,g=b.zoomY&&!c.inverted||b.zoomX&&c.inverted;b.hideTooltipOnMouseMove=
function(a){a=Pb(a);b.chartPosition&&c.hoverSeries&&c.hoverSeries.isCartesian&&!c.isInsidePlot(a.pageX-b.chartPosition.left-c.plotLeft,a.pageY-b.chartPosition.top-c.plotTop)&&b.resetTracker()};b.hideTooltipOnMouseLeave=function(){b.resetTracker();b.chartPosition=null};d.onmousedown=function(d){d=b.normalizeMouseEvent(d);d.type.indexOf("touch")===-1&&d.preventDefault&&d.preventDefault();c.mouseIsDown=!0;c.cancelClick=!1;c.mouseDownX=b.mouseDownX=d.chartX;b.mouseDownY=d.chartY;J(C,"mouseup",a);Ba&&
J(C,"touchend",a)};var h=function(a){if(!a||!(a.touches&&a.touches.length>1)){var a=b.normalizeMouseEvent(a),d=a.type,h=a.chartX,l=a.chartY,m=!c.isInsidePlot(h-c.plotLeft,l-c.plotTop);if(d.indexOf("touch")===-1)a.returnValue=!1;d==="touchstart"&&(w(a.target,"isTracker")?c.runTrackerClick||a.preventDefault():!c.runChartClick&&!m&&a.preventDefault());if(m)h<c.plotLeft?h=c.plotLeft:h>c.plotLeft+c.plotWidth&&(h=c.plotLeft+c.plotWidth),l<c.plotTop?l=c.plotTop:l>c.plotTop+c.plotHeight&&(l=c.plotTop+c.plotHeight);
if(c.mouseIsDown&&d!=="touchstart"&&(e=Math.sqrt(Math.pow(b.mouseDownX-h,2)+Math.pow(b.mouseDownY-l,2)),e>10)){d=c.isInsidePlot(b.mouseDownX-c.plotLeft,b.mouseDownY-c.plotTop);if(c.hasCartesianSeries&&(b.zoomX||b.zoomY)&&d&&!b.selectionMarker)b.selectionMarker=c.renderer.rect(c.plotLeft,c.plotTop,f?1:c.plotWidth,g?1:c.plotHeight,0).attr({fill:b.options.chart.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add();if(b.selectionMarker&&f){var q=h-b.mouseDownX;b.selectionMarker.attr({width:M(q),
x:(q>0?0:q)+b.mouseDownX})}b.selectionMarker&&g&&(l-=b.mouseDownY,b.selectionMarker.attr({height:M(l),y:(l>0?0:l)+b.mouseDownY}));d&&!b.selectionMarker&&b.options.chart.panning&&c.pan(h)}if(!m)b.onmousemove(a);return m||!c.hasCartesianSeries}};if(!/Android 4\.0/.test(na))d.onmousemove=h;J(d,"mouseleave",b.hideTooltipOnMouseLeave);Ba||J(C,"mousemove",b.hideTooltipOnMouseMove);d.ontouchstart=function(a){if(b.zoomX||b.zoomY)d.onmousedown(a);h(a)};d.ontouchmove=h;d.ontouchend=function(){e&&b.resetTracker()};
d.onclick=function(a){var d=c.hoverPoint,e,f,a=b.normalizeMouseEvent(a);a.cancelBubble=!0;if(!c.cancelClick)d&&(w(a.target,"isTracker")||w(a.target.parentNode,"isTracker"))?(e=d.plotX,f=d.plotY,x(d,{pageX:b.chartPosition.left+c.plotLeft+(c.inverted?c.plotWidth-f:e),pageY:b.chartPosition.top+c.plotTop+(c.inverted?c.plotHeight-e:f)}),F(d.series,"click",x(a,{point:d})),d.firePointEvent("click",a)):(x(a,b.getMouseCoordinates(a)),c.isInsidePlot(a.chartX-c.plotLeft,a.chartY-c.plotTop)&&F(c,"click",a))}},
destroy:function(){var a=this.chart,b=a.container;if(a.trackerGroup)a.trackerGroup=a.trackerGroup.destroy();R(b,"mouseleave",this.hideTooltipOnMouseLeave);R(C,"mousemove",this.hideTooltipOnMouseMove);b.onclick=b.onmousedown=b.onmousemove=b.ontouchstart=b.ontouchend=b.ontouchmove=null;clearInterval(this.tooltipTimeout)},init:function(a,b){if(!a.trackerGroup)a.trackerGroup=a.renderer.g("tracker").attr({zIndex:9}).add();if(b.enabled)a.tooltip=new pb(a,b);this.setDOMEvents()}};rb.prototype={init:function(a){var b=
this,c=b.options=a.options.legend;if(c.enabled){var d=c.itemStyle,e=n(c.padding,8),f=c.itemMarginTop||0;b.baseline=z(d.fontSize)+3+f;b.itemStyle=d;b.itemHiddenStyle=B(d,c.itemHiddenStyle);b.itemMarginTop=f;b.padding=e;b.initialItemX=e;b.initialItemY=e-5;b.maxItemWidth=0;b.chart=a;b.itemHeight=0;b.lastLineHeight=0;b.render();J(b.chart,"endResize",function(){b.positionCheckboxes()})}},colorizeItem:function(a,b){var c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,
c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c});e&&e.attr({stroke:h});if(f){if(g)for(j in g=a.convertAttribs(g),g)d=g[j],d!==A&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=e,f.y=d},destroyItem:function(a){var b=a.checkbox;o(["legendItem","legendLine","legendSymbol",
"legendGroup"],function(b){a[b]&&a[b].destroy()});b&&Na(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()},positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight;if(b)c=b.translateY,o(this.allItems,function(e){var f=e.checkbox,g;f&&(g=c+f.y+(a||0)+3,I(f,{left:b.translateX+e.legendItemWidth+f.x-20+"px",top:g+"px",display:g>c-6&&g<c+d-6?"":Q}))})},renderItem:function(a){var p;var b=this,c=b.chart,
d=c.renderer,e=b.options,f=e.layout==="horizontal",g=e.symbolWidth,h=e.symbolPadding,i=b.itemStyle,j=b.itemHiddenStyle,k=b.padding,l=!e.rtl,m=e.width,q=e.itemMarginBottom||0,n=b.itemMarginTop,o=b.initialItemX,t=a.legendItem,r=a.series||a,u=r.options,v=u.showCheckbox,x=e.useHTML;if(!t&&(a.legendGroup=d.g("legend-item").attr({zIndex:1}).add(b.scrollGroup),r.drawLegendSymbol(b,a),a.legendItem=t=d.text(e.labelFormatter.call(a),l?g+h:-h,b.baseline,x).css(B(a.visible?i:j)).attr({align:l?"left":"right",
zIndex:2}).add(a.legendGroup),(x?t:a.legendGroup).on("mouseover",function(){a.setState("hover");t.css(b.options.itemHoverStyle)}).on("mouseout",function(){t.css(a.visible?i:j);a.setState()}).on("click",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent("legendItemClick",b,c):F(a,"legendItemClick",b,c)}),b.colorizeItem(a,a.visible),u&&v))a.checkbox=T("input",{type:"checkbox",checked:a.selected,defaultChecked:a.selected},e.itemCheckboxStyle,c.container),
J(a.checkbox,"click",function(b){F(a,"checkboxClick",{checked:b.target.checked},function(){a.select()})});d=t.getBBox();p=a.legendItemWidth=e.itemWidth||g+h+d.width+k+(v?20:0),e=p;b.itemHeight=g=d.height;if(f&&b.itemX-o+e>(m||c.chartWidth-2*k-o))b.itemX=o,b.itemY+=n+b.lastLineHeight+q,b.lastLineHeight=0;b.maxItemWidth=s(b.maxItemWidth,e);b.lastItemY=n+b.itemY+q;b.lastLineHeight=s(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=n+g+q,b.lastLineHeight=g);b.offsetWidth=
m||s(f?b.itemX-o:e,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,m=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup),a.clipRect=c.clipRect(0,0,9999,b.chartHeight),a.contentGroup.clip(a.clipRect);e=[];o(b.series,function(a){var b=a.options;
b.showInLegend&&(e=e.concat(a.legendItems||(b.legendType==="point"?a.data:a)))});Ib(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;o(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight;h=a.handleOverflow(h);if(l||m){g+=k;h+=k;if(i){if(g>0&&h>0)i[i.isNew?"attr":"animate"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius,
l||0).attr({stroke:j.borderColor,"stroke-width":l||0,fill:m||Q}).add(d).shadow(j.shadow),i.isNew=!0;i[f?"show":"hide"]()}a.legendWidth=g;a.legendHeight=h;o(e,function(b){a.positionItem(b)});f&&d.align(x({width:g,height:h},j),!0,b.spacingBox);b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+(e.verticalAlign==="top"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=n(i.animation,!0),k=
i.arrowSize||12,l=this.nav;e.layout==="horizontal"&&(f/=2);g&&(f=O(f,g));if(a>f){this.clipHeight=c=f-20;this.pageCount=za(a/c);this.currentPage=n(this.currentPage,1);this.fullHeight=a;h.attr({height:c});if(!l)this.nav=l=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,k,k).on("click",function(){b.scroll(-1,j)}).add(l),this.pager=d.text("",15,10).css(i.style).add(l),this.down=d.symbol("triangle-down",0,0,k,k).on("click",function(){b.scroll(1,j)}).add(l);b.scroll(0);a=f}else if(l)h.attr({height:c.chartHeight}),
l.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,h=f.inactiveColor,f=this.pager,i=this.padding;d>c&&(d=c);if(d>0)b!==A&&xa(b,this.chart),this.nav.attr({translateX:i,translateY:e+7,visibility:"visible"}),this.up.attr({fill:d===1?h:g}).css({cursor:d===1?"default":"pointer"}),f.attr({text:d+"/"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width,
fill:d===c?h:g}).css({cursor:d===c?"default":"pointer"}),e=-O(e*(d-1),this.fullHeight-e+i)+1,this.scrollGroup.animate({translateY:e}),f.attr({text:d+"/"+c}),this.currentPage=d,this.positionCheckboxes(e)}};sb.prototype={init:function(a,b){var c,d=a.series;a.series=null;c=B(N,a);c.series=a.series=d;var d=c.chart,e=d.margin,e=Y(e)?e:[e,e,e,e];this.optionsMarginTop=n(d.marginTop,e[0]);this.optionsMarginRight=n(d.marginRight,e[1]);this.optionsMarginBottom=n(d.marginBottom,e[2]);this.optionsMarginLeft=
n(d.marginLeft,e[3]);this.runChartClick=(e=d.events)&&!!e.click;this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f;this.index=Ha.length;Ha.push(this);d.reflow!==!1&&J(this,"load",this.initReflow);if(e)for(f in e)J(this,f,e[f]);this.xAxis=[];this.yAxis=[];this.animation=V?!1:n(d.animation,!0);this.pointCount=0;this.counters=new Hb;this.firstRender()},initSeries:function(a){var b=this.options.chart,b=new $[a.type||b.type||b.defaultSeriesType];
b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(xa(c,e),b=n(b,!0),F(e,"addSeries",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;b&&e.redraw()}));return d},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&o(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.tracker,e=this.legend,
f=this.isDirtyLegend,g,h=this.isDirtyBox,i=c.length,j=i,k=this.renderer,l=k.isHidden(),m=[];xa(a,this);for(l&&this.cloneRenderTo();j--;)if(a=c[j],a.isDirty&&a.options.stacking){g=!0;break}if(g)for(j=i;j--;)if(a=c[j],a.options.stacking)a.isDirty=!0;o(c,function(a){a.isDirty&&a.options.legendType==="point"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,o(b,function(a){a.setScale()});this.adjustTickAmounts();this.getMargins();
o(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,m.push(function(){F(a,"afterSetExtremes",a.getExtremes())});if(a.isDirty||h||g)a.redraw(),h=!0})}h&&this.drawChartBox();o(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.resetTracker&&d.resetTracker(!0);k.draw();F(this,"redraw");l&&this.cloneRenderTo(!0);o(m,function(a){a.call()})},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;if(!c)this.loadingDiv=c=T(ga,{className:"highcharts-loading"},
x(d.style,{left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+"px",height:this.plotHeight+"px",zIndex:10,display:Q}),this.container),this.loadingSpan=T("span",null,d.labelStyle,c);this.loadingSpan.innerHTML=a||b.lang.loading;if(!this.loadingShown)I(c,{opacity:0,display:""}),xb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&xb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){I(b,
{display:Q})}});this.loadingShown=!1},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;d<b.length;d++)if(b[d].options.id===a)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++){e=c[d].points||[];for(b=0;b<e.length;b++)if(e[b].id===a)return e[b]}return null},getAxes:function(){var a=this,b=this.options,c=b.xAxis||{},b=b.yAxis||{},c=la(c);o(c,function(a,b){a.index=b;a.isX=!0});b=la(b);o(b,function(a,b){a.index=b});c=c.concat(b);o(c,function(b){new ob(a,
b)});a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];o(this.series,function(b){a=a.concat(Ob(b.points,function(a){return a.selected}))});return a},getSelectedSeries:function(){return Ob(this.series,function(a){return a.selected})},showResetZoom:function(){var a=this,b=N.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,f=c.relativeTo==="chart"?null:"plotBox";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,
title:b.resetZoomTitle}).add().align(c.position,!1,a[f]);this.resetZoomButton.alignTo=f},zoomOut:function(){var a=this,b=a.resetZoomButton;F(a,"selection",{resetSelection:!0},function(){a.zoom()});if(b)a.resetZoomButton=b.destroy()},zoom:function(a){var b=this,c;!a||a.resetSelection?o(b.axes,function(a){c=a.zoom()}):o(a.xAxis.concat(a.yAxis),function(a){var e=a.axis;if(b.tracker[e.isXAxis?"zoomX":"zoomY"])c=e.zoom(a.min,a.max)});b.resetZoomButton||b.showResetZoom();c&&b.redraw(n(b.options.chart.animation,
b.pointCount<100))},pan:function(a){var b=this.xAxis[0],c=this.mouseDownX,d=b.pointRange/2,e=b.getExtremes(),f=b.translate(c-a,!0)+d,c=b.translate(c+this.plotWidth-a,!0)-d;(d=this.hoverPoints)&&o(d,function(a){a.setState()});b.series.length&&f>O(e.dataMin,e.min)&&c<s(e.dataMax,e.max)&&b.setExtremes(f,c,!0,!1,{trigger:"pan"});this.mouseDownX=a;I(this.container,{cursor:"move"})},setTitle:function(a,b){var c=this,d=c.options,e;c.chartTitleOptions=e=B(d.title,a);c.chartSubtitleOptions=d=B(d.subtitle,
b);o([["title",a,e],["subtitle",b,d]],function(a){var b=a[0],d=c[b],e=a[1],a=a[2];d&&e&&(c[b]=d=d.destroy());a&&a.text&&!d&&(c[b]=c.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,"class":"highcharts-"+b,zIndex:a.zIndex||4}).css(a.style).add().align(a,!1,c.spacingBox))})},getChartSize:function(){var a=this.options.chart,b=this.renderToClone||this.renderTo;this.containerWidth=eb(b,"width");this.containerHeight=eb(b,"height");this.chartWidth=s(0,n(a.width,this.containerWidth,600));this.chartHeight=
s(0,n(a.height,this.containerHeight>19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Na(b),delete this.renderToClone):(c&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),I(b,{position:"absolute",top:"-9999px",display:"block"}),C.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e="highcharts-"+tb++;if(ja(a))this.renderTo=
a=C.getElementById(a);a||Oa(13,!0);c=z(w(a,"data-highcharts-chart"));!isNaN(c)&&Ha[c]&&Ha[c].destroy();w(a,"data-highcharts-chart",this.index);a.innerHTML="";a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;this.container=a=T(ga,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},x({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0},b.style),this.renderToClone||a);this.renderer=
b.forExport?new sa(a,c,d,!0):new Sa(a,c,d);V&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.options.chart,b=a.spacingTop,c=a.spacingRight,d=a.spacingBottom,a=a.spacingLeft,e,f=this.legend,g=this.optionsMarginTop,h=this.optionsMarginLeft,i=this.optionsMarginRight,j=this.optionsMarginBottom,k=this.chartTitleOptions,l=this.chartSubtitleOptions,m=this.options.legend,q=n(m.margin,10),p=m.x,y=m.y,t=m.align,u=m.verticalAlign;this.resetMargins();e=this.axisOffset;if((this.title||this.subtitle)&&
!r(this.optionsMarginTop))if(l=s(this.title&&!k.floating&&!k.verticalAlign&&k.y||0,this.subtitle&&!l.floating&&!l.verticalAlign&&l.y||0))this.plotTop=s(this.plotTop,l+n(k.margin,15)+b);if(f.display&&!m.floating)if(t==="right"){if(!r(i))this.marginRight=s(this.marginRight,f.legendWidth-p+q+c)}else if(t==="left"){if(!r(h))this.plotLeft=s(this.plotLeft,f.legendWidth+p+q+a)}else if(u==="top"){if(!r(g))this.plotTop=s(this.plotTop,f.legendHeight+y+q+b)}else if(u==="bottom"&&!r(j))this.marginBottom=s(this.marginBottom,
f.legendHeight-y+q+d);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);this.hasCartesianSeries&&o(this.axes,function(a){a.getOffset()});r(h)||(this.plotLeft+=e[3]);r(g)||(this.plotTop+=e[0]);r(j)||(this.marginBottom+=e[2]);r(i)||(this.marginRight+=e[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||eb(d,"width"),h=c.height||eb(d,"height"),a=a?a.target:L;if(!b.hasUserSize&&g&&h&&(a===L||a===C)){if(g!==
b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){if(b.container)b.setSize(g,h,!1),b.hasUserSize=null},100);b.containerWidth=g;b.containerHeight=h}}var b=this,c=b.options.chart,d=b.renderTo,e;J(L,"resize",a);J(b,"destroy",function(){R(L,"resize",a)})},setSize:function(a,b,c){var d=this,e,f,g=d.resetZoomButton,h=d.title,i=d.subtitle,j;d.isResizing+=1;j=function(){d&&F(d,"endResize",null,function(){d.isResizing-=1})};xa(c,d);d.oldChartHeight=d.chartHeight;
d.oldChartWidth=d.chartWidth;if(r(a))d.chartWidth=e=s(0,u(a)),d.hasUserSize=!!e;if(r(b))d.chartHeight=f=s(0,u(b));I(d.container,{width:e+"px",height:f+"px"});d.renderer.setSize(e,f,c);d.plotWidth=e-d.plotLeft-d.marginRight;d.plotHeight=f-d.plotTop-d.marginBottom;d.maxTicks=null;o(d.axes,function(a){a.isDirty=!0;a.setScale()});o(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();a=d.spacingBox;h&&h.align(null,null,a);i&&i.align(null,null,a);g&&g.align&&g.align(null,
null,d[g.alignTo]);d.redraw(c);d.oldChartHeight=null;F(d,"resize");Pa===!1?j():setTimeout(j,Pa&&Pa.duration||500)},setChartSize:function(){var a=this.inverted,b=this.chartWidth,c=this.chartHeight,d=this.options.chart,e=d.spacingTop,f=d.spacingRight,g=d.spacingBottom,h=d.spacingLeft,i,j,k,l;this.plotLeft=i=u(this.plotLeft);this.plotTop=j=u(this.plotTop);this.plotWidth=k=s(0,u(b-i-this.marginRight));this.plotHeight=l=s(0,u(c-j-this.marginBottom));this.plotSizeX=a?l:k;this.plotSizeY=a?k:l;this.plotBorderWidth=
a=d.plotBorderWidth||0;this.spacingBox={x:h,y:e,width:b-h-f,height:c-e-g};this.plotBox={x:i,y:j,width:k,height:l};this.clipBox={x:a/2,y:a/2,width:this.plotSizeX-a,height:this.plotSizeY-a};o(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this.options.chart,b=a.spacingRight,c=a.spacingBottom,d=a.spacingLeft;this.plotTop=n(this.optionsMarginTop,a.spacingTop);this.marginRight=n(this.optionsMarginRight,b);this.marginBottom=n(this.optionsMarginBottom,c);this.plotLeft=
n(this.optionsMarginLeft,d);this.axisOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,n,p=this.plotLeft,o=this.plotTop,t=this.plotWidth,r=this.plotHeight,u=this.plotBox,v=this.clipRect,s=this.clipBox;n=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null,
null,null,c-n,d-n));else{e={fill:j||Q};if(i)e.stroke=a.borderColor,e["stroke-width"]=i;this.chartBackground=b.rect(n/2,n/2,c-n,d-n,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(u):this.plotBackground=b.rect(p,o,t,r,0).attr({fill:k}).add().shadow(a.plotShadow);if(l)h?h.animate(u):this.plotBGImage=b.image(l,p,o,t,r).add();v?v.animate({width:s.width,height:s.height}):this.clipRect=b.clipRect(s);if(m)g?g.animate(g.crisp(null,p,o,t,r)):this.plotBorder=b.rect(p,o,t,r,0,m).attr({stroke:a.plotBorderColor,
"stroke-width":m,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,c,d=a.options.series,e,f;o(["inverted","angular","polar"],function(g){c=$[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=$[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,d=d.credits,f;a.setTitle();a.legend=new rb(a);o(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null;
o(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox();a.hasCartesianSeries&&o(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g("series-group").attr({zIndex:3}).add();o(a.series,function(a){a.translate();a.setTooltipPoints();a.render()});e.items&&o(e.items,function(b){var d=x(e.style,b.style),f=z(d.left)+a.plotLeft,j=z(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,j).attr({zIndex:2}).css(d).add()});if(d.enabled&&
!a.credits)f=d.href,a.credits=c.text(d.text,0,0).on("click",function(){if(f)location.href=f}).attr({align:d.position.align,zIndex:8}).css(d.style).add().align(d.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;F(a,"destroy");Ha[a.index]=A;a.renderTo.removeAttribute("data-highcharts-chart");R(a);for(e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();o("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,tracker,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),
function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML="",R(d),f&&Na(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!ca&&L==L.top&&C.readyState!=="complete"||V&&!L.canvg?(V?Rb.push(function(){a.firstRender()},a.options.global.canvasToolsURL):C.attachEvent("onreadystatechange",function(){C.detachEvent("onreadystatechange",a.firstRender);C.readyState==="complete"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;if(a.isReadyToRender()){a.getContainer();
F(a,"init");if(Highcharts.RangeSelector&&b.rangeSelector.enabled)a.rangeSelector=new Highcharts.RangeSelector(a);a.resetMargins();a.setChartSize();a.propFromSeries();a.getAxes();o(b.series||[],function(b){a.initSeries(b)});if(Highcharts.Scroller&&(b.navigator.enabled||b.scrollbar.enabled))a.scroller=new Highcharts.Scroller(a);a.tracker=new qb(a,b);a.render();a.renderer.draw();c&&c.apply(a,[a]);o(a.callbacks,function(b){b.apply(a,[a])});a.cloneRenderTo(!0);F(a,"load")}}};sb.prototype.callbacks=[];
var Ua=function(){};Ua.prototype={init:function(a,b,c){var d=a.chart.counters;this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint)b=a.chart.options.colors,this.color=this.color||b[d.color++],d.wrapColor(b.length);a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=typeof a;this.config=a;if(d==="number"||a===null)this.y=a;else if(typeof a[0]==="number")this.x=a[0],this.y=a[1];else if(d==="object"&&typeof a.length!=="number"){x(this,a);this.options=
a;if(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}else if(typeof a[0]==="string")this.name=a[0],this.y=a[1];if(this.x===A)this.x=b===A?c.autoIncrement():b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),ta(b,this),!b.length))a.hoverPoints=null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)R(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a=
"graphic,tracker,dataLabel,dataLabelUpper,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series.chart,a=n(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=a;c.setState(a&&"select");b||o(d.getSelectedPoints(),
function(a){if(a.selected&&a!==c)a.selected=!1,a.setState(""),a.firePointEvent("unselect")})})},onMouseOver:function(){var a=this.series,b=a.chart,c=b.tooltip,d=b.hoverPoint;if(d&&d!==this)d.onMouseOut();this.firePointEvent("mouseOver");c&&(!c.shared||a.noSharedTooltip)&&c.refresh(this);this.setState("hover");b.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;if(!b||Ub(this,b)===-1)this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null},tooltipFormatter:function(a){var b=
this.series,c=b.tooltipOptions,d=a.match(/\{(series|point)\.[a-zA-Z]+\}/g),e=/[{\.}]/,f,g,h,i,j={y:0,open:0,high:0,low:0,close:0,percentage:1,total:1};c.valuePrefix=c.valuePrefix||c.yPrefix;c.valueDecimals=n(c.valueDecimals,c.yDecimals);c.valueSuffix=c.valueSuffix||c.ySuffix;for(i in d)g=d[i],ja(g)&&g!==a&&(h=(" "+g).split(e),f={point:this,series:b}[h[1]],h=h[2],f===this&&j.hasOwnProperty(h)?(f=j[h]?h:"value",f=(c[f+"Prefix"]||"")+Ja(this[h],n(c[f+"Decimals"],-1))+(c[f+"Suffix"]||"")):f=f[h],a=a.replace(g,
f));return a},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=h.length,j=e.chart,b=n(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a);Y(a)&&(e.getAttribs(),f&&f.attr(d.pointAttr[e.state]));for(g=0;g<i;g++)if(h[g]===d){e.xData[g]=d.x;e.yData[g]=d.toYData?d.toYData():d.y;e.options.data[g]=a;break}e.isDirty=!0;e.isDirtyData=!0;b&&j.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.chart,f,g=d.data,h=g.length;xa(b,e);a=n(a,!0);c.firePointEvent("remove",
null,function(){for(f=0;f<h;f++)if(g[f]===c){g.splice(f,1);d.options.data.splice(f,1);d.xData.splice(f,1);d.yData.splice(f,1);break}c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&e.redraw()})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a==="click"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});F(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=
B(this.series.options.point,this.options).events,b;this.events=a;for(b in a)J(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=X[d.type].marker&&d.options.marker,g=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,j=d.stateMarkerGraphic,k=d.chart,l=this.pointAttr,a=a||"";if(!(a===this.state||this.selected&&a!=="select"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled))){if(this.graphic)e=f&&this.graphic.symbolName&&l[a].r,
this.graphic.attr(B(l[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a&&h)e=h.radius,j?j.attr({x:b-e,y:c-e}):d.stateMarkerGraphic=j=k.renderer.symbol(d.symbol,b-e,c-e,2*e,2*e).attr(l[a]).add(d.markerGroup);if(j)j[a&&k.isInsidePlot(b,c)?"show":"hide"]()}this.state=a}}};var P=function(){};P.prototype={isCartesian:!0,type:"line",pointClass:Ua,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},init:function(a,b){var c,d;this.chart=
a;this.options=b=this.setOptions(b);this.bindAxes();x(this,{name:b.name,state:"",pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0});if(V)b.animation=!1;d=b.events;for(c in d)J(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1);if(this.isCartesian)a.hasCartesianSeries=!0;a.series.push(this);Ib(a.series,function(a,b){return(a.options.index||0)-(b.options.index||0)});o(a.series,
function(a,b){a.index=b;a.name=a.name||"Series "+(b+1)})},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&o(["xAxis","yAxis"],function(e){o(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]===A&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0})})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=n(b,a.pointStart,0);this.pointInterval=n(this.pointInterval,a.pointInterval,1);this.xIncrement=b+this.pointInterval;return b},getSegments:function(){var a=-1,b=[],
c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else o(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type],e=a.data;a.data=null;c=B(d,c.series,a);c.data=a.data=e;this.tooltipOptions=B(b.tooltip,c.tooltip);d.marker===null&&delete c.marker;return c},getColor:function(){var a=this.options,
b=this.chart.options.colors,c=this.chart.counters;this.color=a.color||!a.colorByPoint&&b[c.color++]||"gray";c.wrapColor(b.length)},getSymbol:function(){var a=this.options.marker,b=this.chart,c=b.options.symbols,b=b.counters;this.symbol=a.symbol||c[b.symbol++];if(/^url/.test(this.symbol))a.radius=0;b.wrapSymbol(c.length)},drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options.symbolWidth,e=this.chart.renderer,f=this.legendGroup,a=a.baseline,g;if(b.lineWidth){g={"stroke-width":b.lineWidth};
if(b.dashStyle)g.dashstyle=b.dashStyle;this.legendLine=e.path(["M",0,a-4,"L",d,a-4]).attr(g).add(f)}if(c&&c.enabled)b=c.radius,this.legendSymbol=e.symbol(this.symbol,d/2-b,a-4-b,2*b,2*b).add(f)},addPoint:function(a,b,c,d){var e=this.options,f=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xData,k=this.yData,l=g&&g.shift||0,m=e.data,q=this.pointClass.prototype;xa(d,i);if(g&&c)g.shift=l+1;if(h){if(c)h.shift=l+1;h.isArea=!0}b=n(b,!0);d={series:this};q.applyOptions.apply(d,[a]);j.push(d.x);k.push(q.toYData?
q.toYData.call(d):d.y);m.push(a);e.legendType==="point"&&this.generatePoints();c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),j.shift(),k.shift(),m.shift()));this.getAttribs();this.isDirtyData=this.isDirty=!0;b&&i.redraw()},setData:function(a,b){var c=this.points,d=this.options,e=this.initialColor,f=this.chart,g=null,h=this.xAxis,i,j=this.pointClass.prototype;this.xIncrement=null;this.pointRange=h&&h.categories?1:d.pointRange;if(r(e))f.counters.color=e;var e=[],k=[],l=a?a.length:[],m=(i=this.pointArrayMap)&&
i.length;if(l>(d.turboThreshold||1E3)){for(i=0;g===null&&i<l;)g=a[i],i++;if(Da(g)){j=n(d.pointStart,0);d=n(d.pointInterval,1);for(i=0;i<l;i++)e[i]=j,k[i]=a[i],j+=d;this.xIncrement=j}else if(Ia(g))if(m)for(i=0;i<l;i++)d=a[i],e[i]=d[0],k[i]=d.slice(1,m+1);else for(i=0;i<l;i++)d=a[i],e[i]=d[0],k[i]=d[1]}else for(i=0;i<l;i++)d={series:this},j.applyOptions.apply(d,[a[i]]),e[i]=d.x,k[i]=j.toYData?j.toYData.call(d):d.y;this.requireSorting&&e.length>1&&e[1]<e[0]&&Oa(15);ja(k[0])&&Oa(14,!0);this.data=[];this.options.data=
a;this.xData=e;this.yData=k;for(i=c&&c.length||0;i--;)c[i]&&c[i].destroy&&c[i].destroy();if(h)h.minRange=h.userMinRange;this.isDirty=this.isDirtyData=f.isDirtyBox=!0;n(b,!0)&&f.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=n(a,!0);if(!c.isRemoving)c.isRemoving=!0,F(c,"remove",null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData,d=b.length,e=0,f=d,g,h,i=this.xAxis,j=this.options,k=j.cropThreshold,
l=this.isCartesian;if(l&&!this.isDirty&&!i.isDirty&&!this.yAxis.isDirty&&!a)return!1;if(l&&this.sorted&&(!k||d>k||this.forceCrop))if(a=i.getExtremes(),i=a.min,k=a.max,b[d-1]<i||b[0]>k)b=[],c=[];else if(b[0]<i||b[d-1]>k){for(a=0;a<d;a++)if(b[a]>=i){e=s(0,a-1);break}for(;a<d;a++)if(b[a]>k){f=a+1;break}b=b.slice(e,f);c=c.slice(e,f);g=!0}for(a=b.length-1;a>0;a--)if(d=b[a]-b[a-1],d>0&&(h===A||d<h))h=d;this.cropped=g;this.cropStart=e;this.processedXData=b;this.processedYData=c;if(j.pointRange===null)this.pointRange=
h||1;this.closestPointRange=h},generatePoints:function(){var a=this.options.data,b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,j=this.hasGroupedData,k,l=[],m;if(!b&&!j)b=[],b.length=a.length,b=this.data=b;for(m=0;m<g;m++)i=h+m,j?l[m]=(new f).init(this,[d[m]].concat(la(e[m]))):(b[i]?k=b[i]:a[i]!==A&&(b[i]=k=(new f).init(this,a[i],d[m])),l[m]=k);if(b&&(g!==(c=b.length)||j))for(m=0;m<c;m++)if(m===h&&!j&&(m+=g),b[m])b[m].destroyElements(),
b[m].plotX=A;this.data=b;this.points=l},translate:function(){this.processedXData||this.processData();this.generatePoints();for(var a=this.chart,b=this.options,c=b.stacking,d=this.xAxis,e=d.categories,f=this.yAxis,g=this.points,h=g.length,i=!!this.modifyValue,j,k=f.series,l=k.length,m=b.pointPlacement==="between";l--;)if(k[l].visible){k[l]===this&&(j=!0);break}for(l=0;l<h;l++){var k=g[l],q=k.x,p=k.y,o=k.low,t=f.stacks[(p<b.threshold?"-":"")+this.stackKey];k.plotX=d.translate(q,0,0,0,1,m);if(c&&this.visible&&
t&&t[q])o=t[q],q=o.total,o.cum=o=o.cum-p,p=o+p,j&&(o=n(b.threshold,f.min)),f.isLog&&o<=0&&(o=null),c==="percent"&&(o=q?o*100/q:0,p=q?p*100/q:0),k.percentage=q?k.y*100/q:0,k.total=k.stackTotal=q,k.stackY=p;k.yBottom=r(o)?f.translate(o,0,1,0,1):null;i&&(p=this.modifyValue(p,k));k.plotY=typeof p==="number"?u(f.translate(p,0,1,0,1)*10)/10:A;k.clientX=a.inverted?a.plotHeight-k.plotX:k.plotX;k.category=e&&e[k.x]!==A?e[k.x]:k.x}this.getSegments()},setTooltipPoints:function(a){var b=[],c,d,e=(c=this.xAxis)?
c.tooltipLen||c.len:this.chart.plotSizeX,f=c&&c.tooltipPosName||"plotX",g,h,i=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints=null;o(this.segments||this.points,function(a){b=b.concat(a)});c&&c.reversed&&(b=b.reverse());a=b.length;for(h=0;h<a;h++){g=b[h];c=b[h-1]?d+1:0;for(d=b[h+1]?s(0,U((g[f]+(b[h+1]?b[h+1][f]:e))/2)):e;c>=0&&c<=d;)i[c++]=g}this.tooltipPoints=i}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,d=this.xAxis,e=d&&d.options.type==="datetime",
f;if(e&&!c)for(f in D)if(D[f]>=d.closestPointRange){c=b.dateTimeLabelFormats[f];break}return b.headerFormat.replace("{point.key}",e&&Da(a)?db(c,a):a).replace("{series.name}",this.name).replace("{series.color}",this.color)},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&F(this,"mouseOver");this.setState("hover");a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();
this&&a.events.mouseOut&&F(this,"mouseOut");c&&!a.stickyTracking&&!c.shared&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!Y(e))e=X[b.type].animation;h="_sharedClip"+e.duration+e.easing;if(a)a=c[h],e=c[h+"m"],a||(c[h]=a=d.clipRect(x(f,{width:0})),c[h+"m"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?c.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey=
h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+"m"].animate({width:c.plotSizeX+99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()},e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group,d=this.trackerGroup;c&&this.options.clip!==!1&&(c.clip(a.clipRect),d&&d.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+"m"]=a[b+"m"].destroy())},100)},drawPoints:function(){var a,b=this.points,c=
this.chart,d,e,f,g,h,i,j,k,l=this.options.marker,m,o=this.markerGroup;if(l.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g=b[f],d=g.plotX,e=g.plotY,k=g.graphic,i=g.marker||{},a=l.enabled&&i.enabled===A||i.enabled,m=c.isInsidePlot(d,e,c.inverted),a&&e!==A&&!isNaN(e))if(a=g.pointAttr[g.selected?"select":""],h=a.r,i=n(i.symbol,this.symbol),j=i.indexOf("url")===0,k)k.attr({visibility:m?ca?"inherit":"visible":"hidden"}).animate(x({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{}));else{if(m&&
(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(o)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=n(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=X[a.type].marker?a.options.marker:a.options,c=b.states,d=c.hover,e,f=a.color,g={stroke:f,fill:f},h=a.points||[],i=[],j,k=a.pointAttrToOptions,l;a.options.marker?(d.radius=d.radius||b.radius+2,d.lineWidth=
d.lineWidth||b.lineWidth+1):d.color=d.color||qa(d.color||f).brighten(d.brightness).get();i[""]=a.convertAttribs(b,g);o(["hover","select"],function(b){i[b]=a.convertAttribs(c[b],i[""])});a.pointAttr=i;for(f=h.length;f--;){g=h[f];if((b=g.options&&g.options.marker||g.options)&&b.enabled===!1)b.radius=0;e=a.options.colorByPoint;if(g.options)for(l in k)r(b[k[l]])&&(e=!0);if(e){b=b||{};j=[];c=b.states||{};e=c.hover=c.hover||{};if(!a.options.marker)e.color=qa(e.color||g.color).brighten(e.brightness||d.brightness).get();
j[""]=a.convertAttribs(x({color:g.color},b),i[""]);j.hover=a.convertAttribs(c.hover,i.hover,j[""]);j.select=a.convertAttribs(c.select,i.select,j[""])}else j=i;g.pointAttr=j}},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\/533/.test(na),d,e,f=a.data||[],g,h,i;F(a,"destroy");R(a);o(["xAxis","yAxis"],function(b){if(i=a[b])ta(i.series,a),i.isDirty=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout);
o("area,graph,dataLabelsGroup,group,markerGroup,tracker,trackerGroup".split(","),function(b){a[b]&&(d=c&&b==="group"?"hide":"destroy",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;ta(b.series,a);for(h in a)delete a[h]},drawDataLabels:function(){var a=this,b=a.options.dataLabels,c=a.points,d,e,f,g;if(b.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(b),g=a.plotGroup("dataLabelsGroup","data-labels",a.visible?"visible":"hidden",b.zIndex||6),e=b,o(c,function(c){var i,j=c.dataLabel,
k,l=!0;d=c.options&&c.options.dataLabels;i=e.enabled||d&&d.enabled;if(j&&!i)c.dataLabel=j.destroy();else if(i){i=b.rotation;b=B(e,d);f=b.formatter.call(c.getLabelConfig(),b);b.style.color=n(b.color,b.style.color,a.color,"black");if(j)j.attr({text:f}),l=!1;else if(r(f)){j={fill:b.backgroundColor,stroke:b.borderColor,"stroke-width":b.borderWidth,r:b.borderRadius||0,rotation:i,padding:b.padding,zIndex:1};for(k in j)j[k]===A&&delete j[k];j=c.dataLabel=a.chart.renderer[i?"text":"label"](f,0,-999,null,
null,null,b.useHTML).attr(j).css(b.style).add(g).shadow(b.shadow)}j&&a.alignDataLabel(c,j,b,null,l)}})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=n(a.plotX,-999),a=n(a.plotY,-999),i=b.getBBox(),d=x({x:g?f.plotWidth-a:h,y:u(g?f.plotHeight-h:a),width:0,height:0},d);x(c,{width:i.width,height:i.height});c.rotation?(d={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](d)):(b.align(c,null,d),d=b.alignAttr);b.attr({visibility:c.crop===!1||f.isInsidePlot(d.x,
d.y)||f.isInsidePlot(h,a,g)?f.renderer.isSVG?"inherit":"visible":"hidden"})},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;o(a,function(e,f){var g=e.plotX,h=e.plotY,i;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?"L":"M"),d&&f&&(i=a[f-1],d==="right"?c.push(i.plotX,h):d==="center"?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];o(a.segments,function(e){c=a.getSegmentPath(e);
e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints=d;return a.graphPath=b},drawGraph:function(){var a=this.options,b=this.graph,c=this.group,d=a.lineColor||this.color,e=a.lineWidth,f=a.dashStyle,g=this.getGraphPath();if(b)fb(b),b.animate({d:g});else if(e){b={stroke:d,"stroke-width":e,zIndex:1};if(f)b.dashstyle=f;this.graph=this.chart.renderer.path(g).attr(b).add(c).shadow(a.shadow)}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};o(["group","trackerGroup","markerGroup"],
function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;J(c,"resize",a);J(b,"destroy",function(){R(c,"resize",a)});a();b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],g=this.chart,h=this.xAxis,i=this.yAxis;f||(this[a]=f=g.renderer.g(b).attr({visibility:c,zIndex:d||0.1}).add(e));f.translate(h?h.left:g.plotLeft,i?i.top:g.plotTop);return f},render:function(){var a=this.chart,b,c=this.options,d=c.animation&&!!this.animate,e=this.visible?"visible":"hidden",f=c.zIndex,g=this.hasRendered,
h=a.seriesGroup;b=this.plotGroup("group","series",e,f,h);this.markerGroup=this.plotGroup("markerGroup","markers",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=a.inverted;this.drawGraph&&this.drawGraph();this.drawPoints();this.drawDataLabels();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&&(b.clip(a.clipRect),this.trackerGroup&&this.trackerGroup.clip(a.clipRect));d?this.animate():g||this.afterAnimate();this.isDirty=
this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:this.xAxis.left,translateY:this.yAxis.top}));this.translate();this.setTooltipPoints(!0);this.render();b&&F(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph,d=b.states,b=b.lineWidth,a=a||"";if(this.state!==a)this.state=a,d[a]&&d[a].enabled===!1||(a&&(b=d[a].lineWidth||b+1),c&&!c.dashstyle&&
c.attr({"stroke-width":b},a?0:500))},setVisible:function(a,b){var c=this.chart,d=this.legendItem,e=this.group,f=this.tracker,g=this.dataLabelsGroup,h=this.markerGroup,i,j=this.points,k=c.options.chart.ignoreHiddenSeries;i=this.visible;i=(this.visible=a=a===A?!i:a)?"show":"hide";if(e)e[i]();if(h)h[i]();if(f)f[i]();else if(j)for(e=j.length;e--;)if(f=j[e],f.tracker)f.tracker[i]();if(c.hoverSeries===this)this.onMouseOut();if(g)g[i]();d&&c.legend.colorizeItem(this,a);this.isDirty=!0;this.options.stacking&&
o(c.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});if(k)c.isDirtyBox=!0;b!==!1&&c.redraw();F(this,i)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===A?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;F(this,a?"select":"unselect")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.renderer,h=f.options.tooltip.snap,i=a.tracker,j=b.cursor,
j=j&&{cursor:j},k=a.singlePoints,l=this.isCartesian&&this.plotGroup("trackerGroup",null,"visible",b.zIndex||1,f.trackerGroup),m,n=function(){if(f.hoverSeries!==a)a.onMouseOver()},o=function(){if(!b.stickyTracking)a.onMouseOut()};if(e&&!c)for(m=e+1;m--;)d[m]==="M"&&d.splice(m+1,0,d[m+1]-h,d[m+2],"L"),(m&&d[m]==="M"||m===e)&&d.splice(m,0,"L",d[m-2]+h,d[m-1]);for(m=0;m<k.length;m++)e=k[m],d.push("M",e.plotX-h,e.plotY,"L",e.plotX+h,e.plotY);if(i)i.attr({d:d});else if(a.tracker=i=g.path(d).attr({isTracker:!0,
"stroke-linejoin":"round",visibility:a.visible?"visible":"hidden",stroke:vb,fill:c?vb:Q,"stroke-width":b.lineWidth+(c?0:2*h)}).on("mouseover",n).on("mouseout",o).css(j).add(l),Ba)i.on("touchstart",n)}};G=ba(P);$.line=G;X.area=B(ea,{threshold:0});G=ba(P,{type:"area",getSegmentPath:function(a){var b=P.prototype.getSegmentPath.call(this,a),c=[].concat(b),d,e=this.options;b.length===3&&c.push("L",b[1],b[2]);if(e.stacking&&!this.closedStacks)for(d=a.length-1;d>=0;d--)d<a.length-1&&e.step&&c.push(a[d+1].plotX,
a[d].yBottom),c.push(a[d].plotX,a[d].yBottom);else this.closeSegment(c,a);this.areaPath=this.areaPath.concat(c);return b},closeSegment:function(a,b){var c=this.yAxis.getThreshold(this.options.threshold);a.push("L",b[b.length-1].plotX,c,"L",b[0].plotX,c)},drawGraph:function(){this.areaPath=[];P.prototype.drawGraph.apply(this);var a=this.areaPath,b=this.options,c=this.area;c?c.animate({d:a}):this.area=this.chart.renderer.path(a).attr({fill:n(b.fillColor,qa(this.color).setOpacity(b.fillOpacity||0.75).get()),
zIndex:0}).add(this.group)},drawLegendSymbol:function(a,b){b.legendSymbol=this.chart.renderer.rect(0,a.baseline-11,a.options.symbolWidth,12,2).attr({zIndex:3}).add(b.legendGroup)}});$.area=G;X.spline=B(ea);fa=ba(P,{type:"spline",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,j,k;if(f&&g){a=f.plotY;j=g.plotX;var g=g.plotY,l;h=(1.5*d+f.plotX)/2.5;i=(1.5*e+a)/2.5;j=(1.5*d+j)/2.5;k=(1.5*e+g)/2.5;l=(k-i)*(j-d)/(j-h)+e-k;i+=l;k+=l;i>a&&i>e?(i=s(a,e),k=2*e-i):i<a&&i<e&&(i=O(a,
e),k=2*e-i);k>g&&k>e?(k=s(g,e),i=2*e-k):k<g&&k<e&&(k=O(g,e),i=2*e-k);b.rightContX=j;b.rightContY=k}c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=["M",d,e];return b}});$.spline=fa;X.areaspline=B(X.area);var Ca=G.prototype,fa=ba(fa,{type:"areaspline",closedStacks:!0,getSegmentPath:Ca.getSegmentPath,closeSegment:Ca.closeSegment,drawGraph:Ca.drawGraph});$.areaspline=fa;X.column=B(ea,{borderColor:"#FFFFFF",borderWidth:1,borderRadius:0,groupPadding:0.2,
marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},threshold:0});fa=ba(P,{type:"column",tooltipOutsidePlot:!0,pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",r:"borderRadius"},init:function(){P.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type===
a.type)b.isDirty=!0})},translate:function(){var a=this,b=a.chart,c=a.options,d=c.stacking,e=c.borderWidth,f=0,g=a.xAxis,h=a.yAxis,i=g.reversed,j={},k,l;P.prototype.translate.apply(a);c.grouping===!1?f=1:o(b.series,function(b){var c=b.options;if(b.type===a.type&&b.visible&&a.options.group===c.group)c.stacking?(k=b.stackKey,j[k]===A&&(j[k]=f++),l=j[k]):c.grouping!==!1&&(l=f++),b.columnIndex=l});var m=a.points,g=M(g.transA)*(g.ordinalSlope||c.pointRange||g.closestPointRange||1),q=g*c.groupPadding,p=
(g-2*q)/f,y=c.pointWidth,t=r(y)?(p-y)/2:p*c.pointPadding,u=n(y,p-2*t),x=za(s(u,1+2*e)),v=t+(q+((i?f-(a.columnIndex||0):a.columnIndex)||0)*p-g/2)*(i?-1:1),z=a.translatedThreshold=h.getThreshold(c.threshold),w=n(c.minPointLength,5);o(m,function(c){var f=O(s(-999,c.plotY),h.len+999),g=n(c.yBottom,z),i=c.plotX+v,j=za(O(f,g)),k=za(s(f,g)-j),l=h.stacks[(c.y<0?"-":"")+a.stackKey];d&&a.visible&&l&&l[c.x]&&l[c.x].setOffset(v,x);M(k)<w&&w&&(k=w,j=M(j-z)>w?g-w:z-(f<=z?w:0));c.barX=i;c.pointWidth=u;c.shapeType=
"rect";c.shapeArgs=f=b.renderer.Element.prototype.crisp.call(0,e,i,j,x,k);e%2&&(f.y-=1,f.height+=1);c.trackerArgs=M(k)<3&&B(c.shapeArgs,{height:6,y:j-3})})},getSymbol:pa,drawLegendSymbol:G.prototype.drawLegendSymbol,drawGraph:pa,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;o(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==A&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(fb(g),g.animate(B(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected?"select":""]).add(a.group).shadow(b.shadow,
null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){for(var a=this,b=a.chart,c=b.renderer,d,e,f=+new Date,g=a.options,h=(d=g.cursor)&&{cursor:d},i=a.isCartesian&&a.plotGroup("trackerGroup",null,"visible",g.zIndex||1,b.trackerGroup),j,k,l=a.points,m,n=l.length,o=function(c){j=c.relatedTarget||c.fromElement;if(b.hoverSeries!==a&&w(j,"isTracker")!==f)a.onMouseOver();l[c.target._i].onMouseOver()},r=function(b){if(!g.stickyTracking&&(j=b.relatedTarget||b.toElement,
w(j,"isTracker")!==f))a.onMouseOut()};n--;)if(m=l[n],e=m.tracker,d=m.trackerArgs||m.shapeArgs,k=m.plotY,k=!a.isCartesian||k!==A&&!isNaN(k),delete d.strokeWidth,m.y!==null&&k){if(e)e.attr(d);else if(m.tracker=e=c[m.shapeType](d).attr({isTracker:f,fill:vb,visibility:a.visible?"visible":"hidden"}).on("mouseover",o).on("mouseout",r).css(h).add(m.group||i),Ba)e.on("touchstart",o);e.element._i=n}},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.below||a.plotY>n(this.translatedThreshold,
f.plotSizeY),i=this.options.stacking||c.inside;if(a.shapeArgs&&(d=B(a.shapeArgs),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!i))g?(d.x+=h?0:d.width,d.width=0):(d.y+=h?d.height:0,d.height=0);c.align=n(c.align,!g||i?"center":h?"right":"left");c.verticalAlign=n(c.verticalAlign,g||i?"middle":h?"top":"bottom");P.prototype.alignDataLabel.call(this,a,b,c,d,e)},animate:function(a){var b=this,c=b.points,d=b.options;if(!a)o(c,function(a){var c=a.graphic,a=a.shapeArgs,
g=b.yAxis,h=d.threshold;c&&(c.attr({height:0,y:r(h)?g.getThreshold(h):g.translate(g.getExtremes().min,0,1,0,1)}),c.animate({height:a.height,y:a.y},d.animation))}),b.animate=null},remove:function(){var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type===a.type)b.isDirty=!0});P.prototype.remove.apply(a,arguments)}});$.column=fa;X.bar=B(X.column);Ca=ba(fa,{type:"bar",inverted:!0});$.bar=Ca;X.scatter=B(ea,{lineWidth:0,states:{hover:{lineWidth:0}},tooltip:{headerFormat:'<span style="font-size: 10px; color:{series.color}">{series.name}</span><br/>',
pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>"}});Ca=ba(P,{type:"scatter",sorted:!1,requireSorting:!1,translate:function(){var a=this;P.prototype.translate.apply(a);o(a.points,function(b){b.shapeType="circle";b.shapeArgs={x:b.plotX,y:b.plotY,r:a.chart.options.tooltip.snap}})},drawTracker:function(){for(var a=this,b=a.options.cursor,b=b&&{cursor:b},c=a.points,d=c.length,e,f=a.markerGroup,g=function(b){a.onMouseOver();if(b.target._i!==A)c[b.target._i].onMouseOver()};d--;)if(e=c[d].graphic)e.element._i=
d;if(a._hasTracking)a._hasTracking=!0;else if(f.attr({isTracker:!0}).on("mouseover",g).on("mouseout",function(){if(!a.options.stickyTracking)a.onMouseOut()}).css(b),Ba)f.on("touchstart",g)},setTooltipPoints:pa});$.scatter=Ca;X.pie=B(ea,{borderColor:"#FFFFFF",borderWidth:1,center:["50%","50%"],colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},legendType:"point",marker:null,size:"75%",showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}}});
pa={type:"pie",isCartesian:!1,pointClass:ba(Ua,{init:function(){Ua.prototype.init.apply(this,arguments);var a=this,b;x(a,{visible:a.visible!==!1,name:n(a.name,"Slice")});b=function(){a.slice()};J(a,"select",b);J(a,"unselect",b);return a},setVisible:function(a){var b=this.series,c=b.chart,d=this.tracker,e=this.dataLabel,f=this.connector,g=this.shadowGroup,h;h=(this.visible=a=a===A?!this.visible:a)?"show":"hide";this.group[h]();if(d)d[h]();if(e)e[h]();if(f)f[h]();if(g)g[h]();this.legendItem&&c.legend.colorizeItem(this,
a);if(!b.isDirty&&b.options.ignoreHiddenPoint)b.isDirty=!0,c.redraw()},slice:function(a,b,c){var d=this.series.chart,e=this.slicedTranslation;xa(c,d);n(b,!0);a=this.sliced=r(a)?a:!this.sliced;a={translateX:a?e[0]:d.plotLeft,translateY:a?e[1]:d.plotTop};this.group.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),requireSorting:!1,pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:function(){this.initialColor=this.chart.counters.color},animate:function(){var a=
this,b=a.startAngleRad;o(a.points,function(c){var d=c.graphic,c=c.shapeArgs;d&&(d.attr({r:a.center[3]/2,start:b,end:b}),d.animate({r:c.r,start:c.start,end:c.end},a.options.animation))});a.animate=null},setData:function(a,b){P.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();n(b,!0)&&this.chart.redraw()},getCenter:function(){var a=this.options,b=this.chart,c=b.plotWidth,d=b.plotHeight,a=a.center.concat([a.size,a.innerSize||0]),e=O(c,d),f;return Ta(a,function(a,b){return(f=
/%$/.test(a))?[c,d,e,e][b]*z(a)/100:a})},translate:function(){this.generatePoints();var a=0,b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g=this.chart,h,i,j,k=this.startAngleRad=Aa/180*((c.startAngle||0)%360-90),l=this.points,m=2*Aa,n=c.dataLabels.distance,o=c.ignoreHiddenPoint,r,t=l.length,s;this.center=f=this.getCenter();this.getX=function(a,b){j=K.asin((a-f[1])/(f[2]/2+n));return f[0]+(b?-1:1)*W(j)*(f[2]/2+n)};for(r=0;r<t;r++)s=l[r],a+=o&&!s.visible?0:s.y;for(r=0;r<t;r++){s=l[r];c=a?
s.y/a:0;h=u((k+b*m)*1E3)/1E3;if(!o||s.visible)b+=c;i=u((k+b*m)*1E3)/1E3;s.shapeType="arc";s.shapeArgs={x:f[0],y:f[1],r:f[2]/2,innerR:f[3]/2,start:h,end:i};j=(i+h)/2;j>0.75*m&&(j-=2*Aa);s.slicedTranslation=Ta([W(j)*d+g.plotLeft,Z(j)*d+g.plotTop],u);h=W(j)*f[2]/2;i=Z(j)*f[2]/2;s.tooltipPos=[f[0]+h*0.7,f[1]+i*0.7];s.half=j<m/4?0:1;s.angle=j;s.labelPos=[f[0]+h+W(j)*n,f[1]+i+Z(j)*n,f[0]+h+W(j)*e,f[1]+i+Z(j)*e,f[0]+h,f[1]+i,n<0?"center":s.half?"right":"left",j];s.percentage=c*100;s.total=a}this.setTooltipPoints()},
render:function(){this.getAttribs();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();this.drawDataLabels();this.options.animation&&this.animate&&this.animate();this.isDirty=!1},drawPoints:function(){var a=this,b=a.chart,c=b.renderer,d,e,f,g=a.options.shadow,h,i;o(a.points,function(j){e=j.graphic;i=j.shapeArgs;f=j.group;h=j.shadowGroup;if(g&&!h)h=j.shadowGroup=c.g("shadow").attr({zIndex:4}).add();if(!f)f=j.group=c.g("point").attr({zIndex:5}).add();d=j.sliced?j.slicedTranslation:
[b.plotLeft,b.plotTop];f.translate(d[0],d[1]);h&&h.translate(d[0],d[1]);e?e.animate(i):j.graphic=e=c.arc(i).setRadialReference(a.center).attr(x(j.pointAttr[""],{"stroke-linejoin":"round"})).add(j.group).shadow(g,h);j.visible===!1&&j.setVisible(!1)})},drawDataLabels:function(){var a=this.data,b,c=this.chart,d=this.options.dataLabels,e=n(d.connectorPadding,10),f=n(d.connectorWidth,1),g,h,i=n(d.softConnector,!0),j=d.distance,k=this.center,l=k[2]/2,m=k[1],q=j>0,p=[[],[]],r,t,s,u=2,v,x=function(a,b){return b.y-
a.y},z=function(a,b){a.sort(function(a,c){return(c.angle-a.angle)*b})};if(d.enabled||this._hasPointLabels){P.prototype.drawDataLabels.apply(this);o(a,function(a){a.dataLabel&&p[a.half].push(a)});for(a=p[0][0]&&p[0][0].dataLabel&&(p[0][0].dataLabel.getBBox().height||21);u--;){var w=[],A=[],B=p[u],C=B.length,D;z(B,u-0.5);if(j>0){for(v=m-l-j;v<=m+l+j;v+=a)w.push(v);s=w.length;if(C>s){h=[].concat(B);h.sort(x);for(v=C;v--;)h[v].rank=v;for(v=C;v--;)B[v].rank>=s&&B.splice(v,1);C=B.length}for(v=0;v<C;v++){b=
B[v];h=b.labelPos;b=9999;for(t=0;t<s;t++)g=M(w[t]-h[1]),g<b&&(b=g,D=t);if(D<v&&w[v]!==null)D=v;else for(s<C-v+D&&w[v]!==null&&(D=s-C+v);w[D]===null;)D++;A.push({i:D,y:w[D]});w[D]=null}A.sort(x)}for(v=0;v<C;v++){b=B[v];h=b.labelPos;g=b.dataLabel;s=b.visible===!1?"hidden":"visible";r=h[1];if(j>0){if(t=A.pop(),D=t.i,t=t.y,r>t&&w[D+1]!==null||r<t&&w[D-1]!==null)t=r}else t=r;r=d.justify?k[0]+(u?-1:1)*(l+j):this.getX(D===0||D===w.length-1?r:t,u);g.attr({visibility:s,align:h[6]})[g.moved?"animate":"attr"]({x:r+
d.x+({left:e,right:-e}[h[6]]||0),y:t+d.y-10});g.moved=!0;if(q&&f)g=b.connector,h=i?["M",r+(h[6]==="left"?5:-5),t,"C",r,t,2*h[2]-h[4],2*h[3]-h[5],h[2],h[3],"L",h[4],h[5]]:["M",r+(h[6]==="left"?5:-5),t,"L",h[2],h[3],"L",h[4],h[5]],g?(g.animate({d:h}),g.attr("visibility",s)):b.connector=g=this.chart.renderer.path(h).attr({"stroke-width":f,stroke:d.connectorColor||b.color||"#606060",visibility:s,zIndex:3}).translate(c.plotLeft,c.plotTop).add()}}}},alignDataLabel:pa,drawTracker:fa.prototype.drawTracker,
drawLegendSymbol:G.prototype.drawLegendSymbol,getSymbol:function(){}};pa=ba(P,pa);$.pie=pa;x(Highcharts,{Axis:ob,CanVGRenderer:gb,Chart:sb,Color:qa,Legend:rb,MouseTracker:qb,Point:Ua,Tick:Qa,Tooltip:pb,Renderer:Sa,Series:P,SVGRenderer:sa,VMLRenderer:ha,arrayMin:Fa,arrayMax:wa,charts:Ha,dateFormat:db,pathAnim:ub,getOptions:function(){return N},hasBidiBug:Sb,isTouchDevice:Mb,numberFormat:Ja,seriesTypes:$,setOptions:function(a){N=B(N,a);Jb();return N},addEvent:J,removeEvent:R,createElement:T,discardElement:Na,
css:I,each:o,extend:x,map:Ta,merge:B,pick:n,splat:la,extendClass:ba,pInt:z,wrap:function(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);a.unshift(d);return c.apply(this,a)}},svg:ca,canvas:V,vml:!ca&&!V,product:"Highcharts",version:"2.3.5"})})();
/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
//@ sourceMappingURL=jquery.min.map
*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;
return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&&gt(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l)
}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===b.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="{charset}">
<title>Dashboard for {full_path}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<header>
<div class="container">
<div class="row">
<div class="span12">
<ul class="breadcrumb">
{breadcrumbs}
</ul>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row">
<div class="span6">
<h2>Class Coverage Distribution</h2>
<div id="classCoverageDistribution"></div>
</div>
<div class="span6">
<h2>Class Complexity</h2>
<div id="classComplexity"></div>
</div>
</div>
<div class="row">
<div class="span6">
<h2>Top Project Risks</h2>
<ul>
{top_project_risks}
</ul>
</div>
<div class="span6">
<h2>Least Tested Methods</h2>
<ul>
{least_tested_methods}
</ul>
</div>
</div>
<footer>
<p>
<small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {version}</a> using <a href="http://www.php.net/" target="_top">PHP {php_version}</a>{generator} at {date}.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/highcharts.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var classCoverageDistribution = new Highcharts.Chart({
chart: {
renderTo: 'classCoverageDistribution',
type: 'column'
},
title: {text: ''},
legend: {enabled: false},
credits: {enabled: false},
tooltip: {enabled: false},
xAxis: {
labels: {style: {fontSize: '8px'}},
categories: [
'0%','0-10%','10-20%','20-30%','30-40%','40-50%','50-60%','60-70%','70-80%','80-90%','90-100%','100%'
]
},
yAxis: {
title: '',
labels: {style: {fontSize: '8px'}},
},
series: [{
data: {ccd_values}
}],
});
var classComplexity = new Highcharts.Chart({
chart: {
renderTo: 'classComplexity',
type: 'scatter'
},
title: {text: ''},
legend: {enabled: false},
credits: {enabled: false},
xAxis: {
title: {text: 'Code Coverage (in percent)'},
labels: {enabled: true},
},
yAxis: {
title: {text: 'Cyclomatic Complexity'},
labels: {enabled: true},
},
tooltip: {
formatter: function() {
return this.point.config[2];
}
},
series: [{
data: {cc_values},
marker: {
symbol: 'diamond'
}
}],
});
});
</script>
</body>
</html>
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Renders a PHP_CodeCoverage_Report_Node_Directory node.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_HTML_Renderer_Directory extends PHP_CodeCoverage_Report_HTML_Renderer
{
/**
* @param PHP_CodeCoverage_Report_Node_Directory $node
* @param string $file
*/
public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file)
{
$template = new Text_Template($this->templatePath . 'directory.html');
$this->setCommonTemplateVariables($template, $node);
$items = $this->renderItem($node, TRUE);
foreach ($node->getDirectories() as $item) {
$items .= $this->renderItem($item);
}
foreach ($node->getFiles() as $item) {
$items .= $this->renderItem($item);
}
$template->setVar(
array(
'id' => $node->getId(),
'items' => $items
)
);
$template->renderTo($file);
}
/**
* @param PHP_CodeCoverage_Report_Node $item
* @param boolean $total
* @return string
*/
protected function renderItem(PHP_CodeCoverage_Report_Node $item, $total = FALSE)
{
$data = array(
'numClasses' => $item->getNumClassesAndTraits(),
'numTestedClasses' => $item->getNumTestedClassesAndTraits(),
'numMethods' => $item->getNumMethods(),
'numTestedMethods' => $item->getNumTestedMethods(),
'linesExecutedPercent' => $item->getLineExecutedPercent(FALSE),
'linesExecutedPercentAsString' => $item->getLineExecutedPercent(),
'numExecutedLines' => $item->getNumExecutedLines(),
'numExecutableLines' => $item->getNumExecutableLines(),
'testedMethodsPercent' => $item->getTestedMethodsPercent(FALSE),
'testedMethodsPercentAsString' => $item->getTestedMethodsPercent(),
'testedClassesPercent' => $item->getTestedClassesAndTraitsPercent(FALSE),
'testedClassesPercentAsString' => $item->getTestedClassesAndTraitsPercent()
);
if ($total) {
$data['name'] = 'Total';
} else {
$data['name'] = sprintf(
'<a href="%s.html">%s</a>',
$item->getId(),
$item->getName()
);
if ($item instanceof PHP_CodeCoverage_Report_Node_Directory) {
$data['icon'] = '<i class="icon-folder-open"></i> ';
} else {
$data['icon'] = '<i class="icon-file"></i> ';
}
}
return $this->renderItemTemplate(
new Text_Template($this->templatePath . 'directory_item.html'),
$data
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Renders the dashboard for a PHP_CodeCoverage_Report_Node_Directory node.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_HTML_Renderer_Dashboard extends PHP_CodeCoverage_Report_HTML_Renderer
{
/**
* @param PHP_CodeCoverage_Report_Node_Directory $node
* @param string $file
*/
public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file)
{
$classes = $node->getClassesAndTraits();
$template = new Text_Template(
$this->templatePath . 'dashboard.html'
);
$this->setCommonTemplateVariables($template, $node);
$template->setVar(
array(
'least_tested_methods' => $this->leastTestedMethods($classes),
'top_project_risks' => $this->topProjectRisks($classes),
'cc_values' => $this->classComplexity($classes),
'ccd_values' => $this->classCoverageDistribution($classes),
'backlink' => basename(str_replace('.dashboard', '', $file))
)
);
$template->renderTo($file);
}
/**
* Returns the data for the Class Complexity chart.
*
* @param array $classes
* @return string
*/
protected function classComplexity(array $classes)
{
$data = array();
foreach ($classes as $name => $class) {
$data[] = array(
$class['coverage'],
$class['ccn'],
sprintf(
'<a href="%s">%s</a>',
$class['link'],
$name
)
);
}
return json_encode($data);
}
/**
* Returns the data for the Class Coverage Distribution chart.
*
* @param array $classes
* @return string
*/
protected function classCoverageDistribution(array $classes)
{
$data = array(
'0%' => 0,
'0-10%' => 0,
'10-20%' => 0,
'20-30%' => 0,
'30-40%' => 0,
'40-50%' => 0,
'50-60%' => 0,
'60-70%' => 0,
'70-80%' => 0,
'80-90%' => 0,
'90-100%' => 0,
'100%' => 0
);
foreach ($classes as $class) {
if ($class['coverage'] == 0) {
$data['0%']++;
}
else if ($class['coverage'] == 100) {
$data['100%']++;
}
else {
$key = floor($class['coverage']/10)*10;
$key = $key . '-' . ($key + 10) . '%';
$data[$key]++;
}
}
return json_encode(array_values($data));
}
/**
* Returns the least tested methods.
*
* @param array $classes
* @param integer $max
* @return string
*/
protected function leastTestedMethods(array $classes, $max = 10)
{
$methods = array();
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] < 100) {
if ($className != '*') {
$key = $className . '::' . $methodName;
} else {
$key = $methodName;
}
$methods[$key] = $method['coverage'];
}
}
}
asort($methods);
$methods = array_slice($methods, 0, min($max, count($methods)));
$buffer = '';
foreach ($methods as $name => $coverage) {
list($class, $method) = explode('::', $name);
$buffer .= sprintf(
' <li><a href="%s">%s</a> (%d%%)</li>' . "\n",
$classes[$class]['methods'][$method]['link'],
$name,
$coverage
);
}
return $buffer;
}
/**
* Returns the top project risks according to the CRAP index.
*
* @param array $classes
* @param integer $max
* @return string
*/
protected function topProjectRisks(array $classes, $max = 10)
{
$risks = array();
foreach ($classes as $className => $class) {
if ($class['coverage'] < 100 &&
$class['ccn'] > count($class['methods'])) {
$risks[$className] = $class['crap'];
}
}
arsort($risks);
$buffer = '';
$risks = array_slice($risks, 0, min($max, count($risks)));
foreach ($risks as $name => $crap) {
$buffer .= sprintf(
' <li><a href="%s">%s</a> (%d)</li>' . "\n",
$classes[$name]['link'],
$name,
$crap
);
}
return $buffer;
}
protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node, $isDirectory)
{
return sprintf(
' <li><a href="%s.html">%s</a></li>' . "\n" .
' <li class="active">(Dashboard)</li>' . "\n",
$node->getId(),
$node->getName()
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
/**
* Generates an HTML report from an PHP_CodeCoverage object.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
*/
class PHP_CodeCoverage_Report_HTML
{
/**
* @var string
*/
protected $templatePath;
/**
* @var string
*/
protected $charset;
/**
* @var string
*/
protected $generator;
/**
* @var integer
*/
protected $lowUpperBound;
/**
* @var integer
*/
protected $highLowerBound;
/**
* @var boolean
*/
protected $highlight;
/**
* Constructor.
*
* @param array $options
*/
public function __construct($charset = 'UTF-8', $highlight = FALSE, $lowUpperBound = 35, $highLowerBound = 70, $generator = '')
{
$this->charset = $charset;
$this->generator = $generator;
$this->highLowerBound = $highLowerBound;
$this->highlight = $highlight;
$this->lowUpperBound = $lowUpperBound;
$this->templatePath = sprintf(
'%s%sHTML%sRenderer%sTemplate%s',
dirname(__FILE__),
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR
);
}
/**
* @param PHP_CodeCoverage $coverage
* @param string $target
*/
public function process(PHP_CodeCoverage $coverage, $target)
{
$target = $this->getDirectory($target);
$report = $coverage->getReport();
unset($coverage);
if (!isset($_SERVER['REQUEST_TIME'])) {
$_SERVER['REQUEST_TIME'] = time();
}
$date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']);
$dashboard = new PHP_CodeCoverage_Report_HTML_Renderer_Dashboard(
$this->templatePath,
$this->charset,
$this->generator,
$date,
$this->lowUpperBound,
$this->highLowerBound
);
$directory = new PHP_CodeCoverage_Report_HTML_Renderer_Directory(
$this->templatePath,
$this->charset,
$this->generator,
$date,
$this->lowUpperBound,
$this->highLowerBound
);
$file = new PHP_CodeCoverage_Report_HTML_Renderer_File(
$this->templatePath,
$this->charset,
$this->generator,
$date,
$this->lowUpperBound,
$this->highLowerBound,
$this->highlight
);
$dashboard->render($report, $target . 'index.dashboard.html');
$directory->render($report, $target . 'index.html');
foreach ($report as $node) {
$id = $node->getId();
if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
$dashboard->render($node, $target . $id . '.dashboard.html');
$directory->render($node, $target . $id . '.html');
} else {
$file->render($node, $target . $id . '.html');
}
}
$this->copyFiles($target);
}
/**
* @param string $target
*/
protected function copyFiles($target)
{
$dir = $this->getDirectory($target . 'css');
copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
copy($this->templatePath . 'css/bootstrap-responsive.min.css', $dir . 'bootstrap-responsive.min.css');
copy($this->templatePath . 'css/style.css', $dir . 'style.css');
$dir = $this->getDirectory($target . 'js');
copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
copy($this->templatePath . 'js/highcharts.js', $dir . 'highcharts.js');
copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
copy($this->templatePath . 'js/html5shiv.js', $dir . 'html5shiv.js');
$dir = $this->getDirectory($target . 'img');
copy($this->templatePath . 'img/glyphicons-halflings.png', $dir . 'glyphicons-halflings.png');
copy($this->templatePath . 'img/glyphicons-halflings-white.png', $dir . 'glyphicons-halflings-white.png');
}
/**
* @param string $directory
* @return string
* @throws PHP_CodeCoverage_Exception
* @since Method available since Release 1.2.0
*/
protected function getDirectory($directory)
{
if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
$directory .= DIRECTORY_SEPARATOR;
}
if (is_dir($directory)) {
return $directory;
}
if (@mkdir($directory, 0777, TRUE)) {
return $directory;
}
throw new PHP_CodeCoverage_Exception(
sprintf(
'Directory "%s" does not exist.',
$directory
)
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Uses serialize() to write a PHP_CodeCoverage object to a file.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_PHP
{
/**
* @param PHP_CodeCoverage $coverage
* @param string $target
* @return string
*/
public function process(PHP_CodeCoverage $coverage, $target = NULL)
{
$coverage = serialize($coverage);
if ($target !== NULL) {
return file_put_contents($target, $coverage);
} else {
return $coverage;
}
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Generates human readable output from an PHP_CodeCoverage object.
*
* The output gets put into a text file our written to the CLI.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_Text
{
protected $outputStream;
protected $lowUpperBound;
protected $highLowerBound;
protected $showUncoveredFiles;
protected $colors = array(
'green' => "\x1b[30;42m",
'yellow' => "\x1b[30;43m",
'red' => "\x1b[37;41m",
'header' => "\x1b[47;40m",
'reset' => "\x1b[0m",
'eol' => "\x1b[2K",
);
public function __construct(PHPUnit_Util_Printer $outputStream, $lowUpperBound, $highLowerBound, $showUncoveredFiles)
{
$this->outputStream = $outputStream;
$this->lowUpperBound = $lowUpperBound;
$this->highLowerBound = $highLowerBound;
$this->showUncoveredFiles = $showUncoveredFiles;
}
/**
* @param PHP_CodeCoverage $coverage
* @param string $target
* @param string $name
* @return string
*/
public function process(PHP_CodeCoverage $coverage, $showColors = FALSE)
{
$output = '';
$report = $coverage->getReport();
unset($coverage);
$colors = array(
'header' => '',
'classes' => '',
'methods' => '',
'lines' => '',
'reset' => '',
'eol' => ''
);
if ($showColors) {
$colors['classes'] = $this->getCoverageColor(
$report->getNumTestedClassesAndTraits(),
$report->getNumClassesAndTraits()
);
$colors['methods'] = $this->getCoverageColor(
$report->getNumTestedMethods(),
$report->getNumMethods()
);
$colors['lines'] = $this->getCoverageColor(
$report->getNumExecutedLines(),
$report->getNumExecutableLines()
);
$colors['reset'] = $this->colors['reset'];
$colors['header'] = $this->colors['header'];
$colors['eol'] = $this->colors['eol'];
}
$output .= PHP_EOL . PHP_EOL .
$colors['header'] . 'Code Coverage Report ';
$output .= PHP_EOL .
date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) .
PHP_EOL;
$output .= PHP_EOL . ' Summary: ' . PHP_EOL . $colors['reset']
. $colors['classes'] . $colors['eol'] . ' Classes: ' . PHP_CodeCoverage_Util::percent($report->getNumTestedClassesAndTraits(), $report->getNumClassesAndTraits(), TRUE)
. ' (' . $report->getNumTestedClassesAndTraits() . '/' . $report->getNumClassesAndTraits() . ')' . PHP_EOL . $colors ['eol']
. $colors['methods'] . $colors['eol'] . ' Methods: ' . PHP_CodeCoverage_Util::percent($report->getNumTestedMethods(), $report->getNumMethods(), TRUE)
. ' (' . $report->getNumTestedMethods() . '/' . $report->getNumMethods() . ')' . PHP_EOL . $colors ['eol']
. $colors['lines'] . $colors['eol'] . ' Lines: ' . PHP_CodeCoverage_Util::percent($report->getNumExecutedLines(), $report->getNumExecutableLines(), TRUE)
. ' (' . $report->getNumExecutedLines() . '/' . $report->getNumExecutableLines() . ')' . PHP_EOL . $colors['reset'] . $colors ['eol'];
$classCoverage = array();
foreach ($report as $item) {
if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
continue;
}
$classes = $item->getClassesAndTraits();
$coverage = $item->getCoverageData();
$lines = array();
$ignoredLines = $item->getIgnoredLines();
foreach ($classes as $className => $class) {
$classStatements = 0;
$coveredClassStatements = 0;
$coveredMethods = 0;
foreach ($class['methods'] as $method) {
$methodCount = 0;
$methodLines = 0;
$methodLinesCovered = 0;
for ($i = $method['startLine'];
$i <= $method['endLine'];
$i++) {
if (isset($ignoredLines[$i])) {
continue;
}
$add = TRUE;
$count = 0;
if (isset($coverage[$i])) {
if ($coverage[$i] !== NULL) {
$classStatements++;
$methodLines++;
} else {
$add = FALSE;
}
$count = count($coverage[$i]);
if ($count > 0) {
$coveredClassStatements++;
$methodLinesCovered++;
}
} else {
$add = FALSE;
}
$methodCount = max($methodCount, $count);
if ($add) {
$lines[$i] = array(
'count' => $count, 'type' => 'stmt'
);
}
}
if ($methodCount > 0) {
$coveredMethods++;
}
}
if (!empty($class['package']['namespace'])) {
$namespace = '\\' . $class['package']['namespace'] . '::';
}
else if (!empty($class['package']['fullPackage'])) {
$namespace = '@' . $class['package']['fullPackage'] . '::';
}
else {
$namespace = '';
}
$classCoverage[$namespace . $className] = array(
'namespace' => $namespace,
'className ' => $className,
'methodsCovered' => $coveredMethods,
'methodCount' => count($class['methods']),
'statementsCovered' => $coveredClassStatements,
'statementCount' => $classStatements,
);
}
}
ksort($classCoverage);
$methodColor = '';
$linesColor = '';
$resetColor = '';
foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
if ($classInfo['statementsCovered'] != 0 ||
$this->showUncoveredFiles) {
if ($showColors) {
$methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
$linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
$resetColor = $colors['reset'];
}
$output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
. ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' '
. ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor
;
}
}
$this->outputStream->write($output . PHP_EOL);
}
protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
{
$coverage = PHP_CodeCoverage_Util::percent(
$numberOfCoveredElements, $totalNumberOfElements
);
if ($coverage > $this->highLowerBound) {
return $this->colors['green'];
}
else if ($coverage > $this->lowUpperBound) {
return $this->colors['yellow'];
}
return $this->colors['red'];
}
protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $presicion)
{
$format = '%' . $presicion . 's';
return PHP_CodeCoverage_Util::percent(
$numberOfCoveredElements, $totalNumberOfElements, TRUE, TRUE
) .
' (' . sprintf($format, $numberOfCoveredElements) . '/' .
sprintf($format, $totalNumberOfElements) . ')';
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.0.0
*/
/**
* Generates a Clover XML logfile from an PHP_CodeCoverage object.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.0.0
*/
class PHP_CodeCoverage_Report_Clover
{
/**
* @param PHP_CodeCoverage $coverage
* @param string $target
* @param string $name
* @return string
*/
public function process(PHP_CodeCoverage $coverage, $target = NULL, $name = NULL)
{
$xmlDocument = new DOMDocument('1.0', 'UTF-8');
$xmlDocument->formatOutput = TRUE;
$xmlCoverage = $xmlDocument->createElement('coverage');
$xmlCoverage->setAttribute('generated', (int)$_SERVER['REQUEST_TIME']);
$xmlDocument->appendChild($xmlCoverage);
$xmlProject = $xmlDocument->createElement('project');
$xmlProject->setAttribute('timestamp', (int)$_SERVER['REQUEST_TIME']);
if (is_string($name)) {
$xmlProject->setAttribute('name', $name);
}
$xmlCoverage->appendChild($xmlProject);
$packages = array();
$report = $coverage->getReport();
unset($coverage);
foreach ($report as $item) {
$namespace = 'global';
if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
continue;
}
$xmlFile = $xmlDocument->createElement('file');
$xmlFile->setAttribute('name', $item->getPath());
$classes = $item->getClassesAndTraits();
$coverage = $item->getCoverageData();
$lines = array();
$ignoredLines = $item->getIgnoredLines();
foreach ($classes as $className => $class) {
$classStatements = 0;
$coveredClassStatements = 0;
$coveredMethods = 0;
foreach ($class['methods'] as $methodName => $method) {
$methodCount = 0;
$methodLines = 0;
$methodLinesCovered = 0;
for ($i = $method['startLine'];
$i <= $method['endLine'];
$i++) {
if (isset($ignoredLines[$i])) {
continue;
}
$add = TRUE;
$count = 0;
if (isset($coverage[$i])) {
if ($coverage[$i] !== NULL) {
$classStatements++;
$methodLines++;
} else {
$add = FALSE;
}
$count = count($coverage[$i]);
if ($count > 0) {
$coveredClassStatements++;
$methodLinesCovered++;
}
} else {
$add = FALSE;
}
$methodCount = max($methodCount, $count);
if ($add) {
$lines[$i] = array(
'count' => $count, 'type' => 'stmt'
);
}
}
if ($methodCount > 0) {
$coveredMethods++;
}
$lines[$method['startLine']] = array(
'count' => $methodCount,
'crap' => $method['crap'],
'type' => 'method',
'name' => $methodName
);
}
if (!empty($class['package']['namespace'])) {
$namespace = $class['package']['namespace'];
}
$xmlClass = $xmlDocument->createElement('class');
$xmlClass->setAttribute('name', $className);
$xmlClass->setAttribute('namespace', $namespace);
if (!empty($class['package']['fullPackage'])) {
$xmlClass->setAttribute(
'fullPackage', $class['package']['fullPackage']
);
}
if (!empty($class['package']['category'])) {
$xmlClass->setAttribute(
'category', $class['package']['category']
);
}
if (!empty($class['package']['package'])) {
$xmlClass->setAttribute(
'package', $class['package']['package']
);
}
if (!empty($class['package']['subpackage'])) {
$xmlClass->setAttribute(
'subpackage', $class['package']['subpackage']
);
}
$xmlFile->appendChild($xmlClass);
$xmlMetrics = $xmlDocument->createElement('metrics');
$xmlMetrics->setAttribute('methods', count($class['methods']));
$xmlMetrics->setAttribute('coveredmethods', $coveredMethods);
$xmlMetrics->setAttribute('conditionals', 0);
$xmlMetrics->setAttribute('coveredconditionals', 0);
$xmlMetrics->setAttribute('statements', $classStatements);
$xmlMetrics->setAttribute(
'coveredstatements', $coveredClassStatements
);
$xmlMetrics->setAttribute(
'elements',
count($class['methods']) +
$classStatements
/* + conditionals */);
$xmlMetrics->setAttribute(
'coveredelements',
$coveredMethods +
$coveredClassStatements
/* + coveredconditionals */
);
$xmlClass->appendChild($xmlMetrics);
}
foreach ($coverage as $line => $data) {
if ($data === NULL ||
isset($lines[$line]) ||
isset($ignoredLines[$line])) {
continue;
}
$lines[$line] = array(
'count' => count($data), 'type' => 'stmt'
);
}
ksort($lines);
foreach ($lines as $line => $data) {
if (isset($ignoredLines[$line])) {
continue;
}
$xmlLine = $xmlDocument->createElement('line');
$xmlLine->setAttribute('num', $line);
$xmlLine->setAttribute('type', $data['type']);
if (isset($data['name'])) {
$xmlLine->setAttribute('name', $data['name']);
}
if (isset($data['crap'])) {
$xmlLine->setAttribute('crap', $data['crap']);
}
$xmlLine->setAttribute('count', $data['count']);
$xmlFile->appendChild($xmlLine);
}
$linesOfCode = $item->getLinesOfCode();
$xmlMetrics = $xmlDocument->createElement('metrics');
$xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
$xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
$xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits());
$xmlMetrics->setAttribute('methods', $item->getNumMethods());
$xmlMetrics->setAttribute(
'coveredmethods', $item->getNumTestedMethods()
);
$xmlMetrics->setAttribute('conditionals', 0);
$xmlMetrics->setAttribute('coveredconditionals', 0);
$xmlMetrics->setAttribute(
'statements', $item->getNumExecutableLines()
);
$xmlMetrics->setAttribute(
'coveredstatements', $item->getNumExecutedLines()
);
$xmlMetrics->setAttribute(
'elements',
$item->getNumMethods() +
$item->getNumExecutableLines()
/* + conditionals */
);
$xmlMetrics->setAttribute(
'coveredelements',
$item->getNumTestedMethods() +
$item->getNumExecutedLines()
/* + coveredconditionals */
);
$xmlFile->appendChild($xmlMetrics);
if ($namespace == 'global') {
$xmlProject->appendChild($xmlFile);
} else {
if (!isset($packages[$namespace])) {
$packages[$namespace] = $xmlDocument->createElement(
'package'
);
$packages[$namespace]->setAttribute('name', $namespace);
$xmlProject->appendChild($packages[$namespace]);
}
$packages[$namespace]->appendChild($xmlFile);
}
}
$linesOfCode = $report->getLinesOfCode();
$xmlMetrics = $xmlDocument->createElement('metrics');
$xmlMetrics->setAttribute('files', count($report));
$xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
$xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
$xmlMetrics->setAttribute(
'classes', $report->getNumClassesAndTraits()
);
$xmlMetrics->setAttribute('methods', $report->getNumMethods());
$xmlMetrics->setAttribute(
'coveredmethods', $report->getNumTestedMethods()
);
$xmlMetrics->setAttribute('conditionals', 0);
$xmlMetrics->setAttribute('coveredconditionals', 0);
$xmlMetrics->setAttribute(
'statements', $report->getNumExecutableLines()
);
$xmlMetrics->setAttribute(
'coveredstatements', $report->getNumExecutedLines()
);
$xmlMetrics->setAttribute(
'elements',
$report->getNumMethods() +
$report->getNumExecutableLines()
/* + conditionals */
);
$xmlMetrics->setAttribute(
'coveredelements',
$report->getNumTestedMethods() +
$report->getNumExecutedLines()
/* + coveredconditionals */
);
$xmlProject->appendChild($xmlMetrics);
if ($target !== NULL) {
if (!is_dir(dirname($target))) {
mkdir(dirname($target), 0777, TRUE);
}
return $xmlDocument->save($target);
} else {
return $xmlDocument->saveXML();
}
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since File available since Release 1.1.0
*/
/**
* Factory for PHP_CodeCoverage_Report_Node_* object graphs.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-code-coverage
* @since Class available since Release 1.1.0
*/
class PHP_CodeCoverage_Report_Factory
{
/**
* @param PHP_CodeCoverage $coverage
*/
public function create(PHP_CodeCoverage $coverage)
{
$files = $coverage->getData();
$commonPath = $this->reducePaths($files);
$root = new PHP_CodeCoverage_Report_Node_Directory(
$commonPath, NULL
);
$this->addItems(
$root,
$this->buildDirectoryStructure($files),
$coverage->getTests(),
$coverage->getCacheTokens()
);
return $root;
}
/**
* @param PHP_CodeCoverage_Report_Node_Directory $root
* @param array $items
* @param array $tests
* @param boolean $cacheTokens
*/
protected function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
{
foreach ($items as $key => $value) {
if (substr($key, -2) == '/f') {
$key = substr($key, 0, -2);
if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
$root->addFile($key, $value, $tests, $cacheTokens);
}
} else {
$child = $root->addDirectory($key);
$this->addItems($child, $value, $tests, $cacheTokens);
}
}
}
/**
* Builds an array representation of the directory structure.
*
* For instance,
*
* <code>
* Array
* (
* [Money.php] => Array
* (
* ...
* )
*
* [MoneyBag.php] => Array
* (
* ...
* )
* )
* </code>
*
* is transformed into
*
* <code>
* Array
* (
* [.] => Array
* (
* [Money.php] => Array
* (
* ...
* )
*
* [MoneyBag.php] => Array
* (
* ...
* )
* )
* )
* </code>
*
* @param array $files
* @return array
*/
protected 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;
}
/**
* Reduces the paths by cutting the longest common start path.
*
* For instance,
*
* <code>
* Array
* (
* [/home/sb/Money/Money.php] => Array
* (
* ...
* )
*
* [/home/sb/Money/MoneyBag.php] => Array
* (
* ...
* )
* )
* </code>
*
* is reduced to
*
* <code>
* Array
* (
* [Money.php] => Array
* (
* ...
* )
*
* [MoneyBag.php] => Array
* (
* ...
* )
* )
* </code>
*
* @param array $files
* @return string
*/
protected 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++) {
// strip phar:// prefixes
if (strpos($paths[$i], 'phar://') === 0) {
$paths[$i] = substr($paths[$i], 7);
}
$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];
if ($paths[0][0] != DIRECTORY_SEPARATOR) {
$commonPath .= 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 substr($commonPath, 0, -1);
}
}
PHP_CodeCoverage
Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
<?php
/**
* Text_Template
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Text
* @package Template
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/php-text-template
* @since File available since Release 1.0.0
*/
/**
* A simple template engine.
*
* @category Text
* @package Template
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.1.4
* @link http://github.com/sebastianbergmann/php-text-template
* @since Class available since Release 1.0.0
*/
class Text_Template
{
/**
* @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 {
$error = error_get_last();
throw new RuntimeException(
sprintf(
'Could not write to %s: %s',
$target,
substr(
$error['message'],
strpos($error['message'], ':') + 2
)
)
);
}
}
}
Text_Template
Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Text_Template 1.1
=================
This is the list of changes for the Text_Template 1.1 release series.
Text_Template 1.1.4
-------------------
* Improved error message in case `renderTo()` cannot write to the target file.
Text_Template 1.1.3
-------------------
* No changes.
Text_Template 1.1.2
-------------------
* No changes.
Text_Template 1.1.1
-------------------
* No changes.
Text_Template
=============
Installation
------------
Text_Template should be installed using the [PEAR Installer](http://pear.php.net/). This installer is the backbone of PEAR, which provides a distribution system for PHP packages, and is shipped with every release of PHP since version 4.3.0.
The PEAR channel (`pear.phpunit.de`) that is used to distribute Text_Template needs to be registered with the local PEAR environment:
sb@ubuntu ~ % pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded
This has to be done only once. Now the PEAR Installer can be used to install packages from the PHPUnit channel:
sb@vmware ~ % pear install phpunit/Text_Template
downloading Text_Template-1.0.0.tgz ...
Starting to download Text_Template-1.0.0.tgz (2,493 bytes)
....done: 2,493 bytes
install ok: channel://pear.phpunit.de/Text_Template-1.0.0
After the installation you can find the Text_Template source files inside your local PEAR directory; the path is usually `/usr/lib/php/Text`.
<?php
/**
* php-token-stream
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHP_TokenStream
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @since File available since Release 1.0.0
*/
/**
* A stream of PHP tokens.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.1.5
* @link http://github.com/sebastianbergmann/php-token-stream/tree
* @since Class available since Release 1.0.0
*/
class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
{
/**
* @var array
*/
protected static $customTokens = array(
'(' => 'PHP_Token_OPEN_BRACKET',
')' => 'PHP_Token_CLOSE_BRACKET',
'[' => 'PHP_Token_OPEN_SQUARE',
']' => 'PHP_Token_CLOSE_SQUARE',
'{' => 'PHP_Token_OPEN_CURLY',
'}' => 'PHP_Token_CLOSE_CURLY',
';' => 'PHP_Token_SEMICOLON',
'.' => 'PHP_Token_DOT',
',' => 'PHP_Token_COMMA',
'=' => 'PHP_Token_EQUAL',
'<' => 'PHP_Token_LT',
'>' => 'PHP_Token_GT',
'+' => 'PHP_Token_PLUS',
'-' => 'PHP_Token_MINUS',
'*' => 'PHP_Token_MULT',
'/' => 'PHP_Token_DIV',
'?' => 'PHP_Token_QUESTION_MARK',
'!' => 'PHP_Token_EXCLAMATION_MARK',
':' => 'PHP_Token_COLON',
'"' => 'PHP_Token_DOUBLE_QUOTES',
'@' => 'PHP_Token_AT',
'&' => 'PHP_Token_AMPERSAND',
'%' => 'PHP_Token_PERCENT',
'|' => 'PHP_Token_PIPE',
'$' => 'PHP_Token_DOLLAR',
'^' => 'PHP_Token_CARET',
'~' => 'PHP_Token_TILDE',
'`' => 'PHP_Token_BACKTICK'
);
/**
* @var string
*/
protected $filename;
/**
* @var array
*/
protected $tokens = array();
/**
* @var integer
*/
protected $position = 0;
/**
* @var array
*/
protected $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
/**
* @var array
*/
protected $classes;
/**
* @var array
*/
protected $functions;
/**
* @var array
*/
protected $includes;
/**
* @var array
*/
protected $interfaces;
/**
* @var array
*/
protected $traits;
/**
* Constructor.
*
* @param string $sourceCode
*/
public function __construct($sourceCode)
{
if (is_file($sourceCode)) {
$this->filename = $sourceCode;
$sourceCode = file_get_contents($sourceCode);
}
$this->scan($sourceCode);
}
/**
* Destructor.
*/
public function __destruct()
{
$this->tokens = array();
}
/**
* @return string
*/
public function __toString()
{
$buffer = '';
foreach ($this as $token) {
$buffer .= $token;
}
return $buffer;
}
/**
* @return string
* @since Method available since Release 1.1.0
*/
public function getFilename()
{
return $this->filename;
}
/**
* Scans the source for sequences of characters and converts them into a
* stream of tokens.
*
* @param string $sourceCode
*/
protected function scan($sourceCode)
{
$line = 1;
$tokens = token_get_all($sourceCode);
$numTokens = count($tokens);
for ($i = 0; $i < $numTokens; ++$i) {
$token = $tokens[$i];
unset($tokens[$i]);
if (is_array($token)) {
$text = $token[1];
$tokenClass = 'PHP_Token_' . substr(token_name($token[0]), 2);
} else {
$text = $token;
$tokenClass = self::$customTokens[$token];
}
$this->tokens[] = new $tokenClass($text, $line, $this, $i);
$lines = substr_count($text, "\n");
$line += $lines;
if ($tokenClass == 'PHP_Token_HALT_COMPILER') {
break;
}
else if ($tokenClass == 'PHP_Token_COMMENT' ||
$tokenClass == 'PHP_Token_DOC_COMMENT') {
$this->linesOfCode['cloc'] += $lines + 1;
}
}
$this->linesOfCode['loc'] = substr_count($sourceCode, "\n");
$this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
$this->linesOfCode['cloc'];
}
/**
* @return integer
*/
public function count()
{
return count($this->tokens);
}
/**
* @return PHP_Token[]
*/
public function tokens()
{
return $this->tokens;
}
/**
* @return array
*/
public function getClasses()
{
if ($this->classes !== NULL) {
return $this->classes;
}
$this->parse();
return $this->classes;
}
/**
* @return array
*/
public function getFunctions()
{
if ($this->functions !== NULL) {
return $this->functions;
}
$this->parse();
return $this->functions;
}
/**
* @return array
*/
public function getInterfaces()
{
if ($this->interfaces !== NULL) {
return $this->interfaces;
}
$this->parse();
return $this->interfaces;
}
/**
* @return array
* @since Method available since Release 1.1.0
*/
public function getTraits()
{
if ($this->traits !== NULL) {
return $this->traits;
}
$this->parse();
return $this->traits;
}
/**
* Gets the names of all files that have been included
* using include(), include_once(), require() or require_once().
*
* Parameter $categorize set to TRUE causing this function to return a
* multi-dimensional array with categories in the keys of the first dimension
* and constants and their values in the second dimension.
*
* Parameter $category allow to filter following specific inclusion type
*
* @param bool $categorize OPTIONAL
* @param string $category OPTIONAL Either 'require_once', 'require',
* 'include_once', 'include'.
* @return array
* @since Method available since Release 1.1.0
*/
public function getIncludes($categorize = FALSE, $category = NULL)
{
if ($this->includes === NULL) {
$this->includes = array(
'require_once' => array(),
'require' => array(),
'include_once' => array(),
'include' => array()
);
foreach ($this->tokens as $token) {
switch (get_class($token)) {
case 'PHP_Token_REQUIRE_ONCE':
case 'PHP_Token_REQUIRE':
case 'PHP_Token_INCLUDE_ONCE':
case 'PHP_Token_INCLUDE': {
$this->includes[$token->getType()][] = $token->getName();
}
break;
}
}
}
if (isset($this->includes[$category])) {
$includes = $this->includes[$category];
}
else if ($categorize === FALSE) {
$includes = array_merge(
$this->includes['require_once'],
$this->includes['require'],
$this->includes['include_once'],
$this->includes['include']
);
} else {
$includes = $this->includes;
}
return $includes;
}
protected function parse()
{
$this->interfaces = array();
$this->classes = array();
$this->traits = array();
$this->functions = array();
$class = FALSE;
$classEndLine = FALSE;
$trait = FALSE;
$traitEndLine = FALSE;
$interface = FALSE;
$interfaceEndLine = FALSE;
foreach ($this->tokens as $token) {
switch (get_class($token)) {
case 'PHP_Token_HALT_COMPILER': {
return;
}
break;
case 'PHP_Token_INTERFACE': {
$interface = $token->getName();
$interfaceEndLine = $token->getEndLine();
$this->interfaces[$interface] = array(
'methods' => array(),
'parent' => $token->getParent(),
'keywords' => $token->getKeywords(),
'docblock' => $token->getDocblock(),
'startLine' => $token->getLine(),
'endLine' => $interfaceEndLine,
'package' => $token->getPackage(),
'file' => $this->filename
);
}
break;
case 'PHP_Token_CLASS':
case 'PHP_Token_TRAIT': {
$tmp = array(
'methods' => array(),
'parent' => $token->getParent(),
'interfaces'=> $token->getInterfaces(),
'keywords' => $token->getKeywords(),
'docblock' => $token->getDocblock(),
'startLine' => $token->getLine(),
'endLine' => $token->getEndLine(),
'package' => $token->getPackage(),
'file' => $this->filename
);
if ($token instanceof PHP_Token_CLASS) {
$class = $token->getName();
$classEndLine = $token->getEndLine();
$this->classes[$class] = $tmp;
} else {
$trait = $token->getName();
$traitEndLine = $token->getEndLine();
$this->traits[$trait] = $tmp;
}
}
break;
case 'PHP_Token_FUNCTION': {
$name = $token->getName();
$tmp = array(
'docblock' => $token->getDocblock(),
'keywords' => $token->getKeywords(),
'visibility'=> $token->getVisibility(),
'signature' => $token->getSignature(),
'startLine' => $token->getLine(),
'endLine' => $token->getEndLine(),
'ccn' => $token->getCCN(),
'file' => $this->filename
);
if ($class === FALSE &&
$trait === FALSE &&
$interface === FALSE) {
$this->functions[$name] = $tmp;
}
else if ($class !== FALSE) {
$this->classes[$class]['methods'][$name] = $tmp;
}
else if ($trait !== FALSE) {
$this->traits[$trait]['methods'][$name] = $tmp;
}
else {
$this->interfaces[$interface]['methods'][$name] = $tmp;
}
}
break;
case 'PHP_Token_CLOSE_CURLY': {
if ($classEndLine !== FALSE &&
$classEndLine == $token->getLine()) {
$class = FALSE;
$classEndLine = FALSE;
}
else if ($traitEndLine !== FALSE &&
$traitEndLine == $token->getLine()) {
$trait = FALSE;
$traitEndLine = FALSE;
}
else if ($interfaceEndLine !== FALSE &&
$interfaceEndLine == $token->getLine()) {
$interface = FALSE;
$interfaceEndLine = FALSE;
}
}
break;
}
}
}
/**
* @return array
*/
public function getLinesOfCode()
{
return $this->linesOfCode;
}
/**
*/
public function rewind()
{
$this->position = 0;
}
/**
* @return boolean
*/
public function valid()
{
return isset($this->tokens[$this->position]);
}
/**
* @return integer
*/
public function key()
{
return $this->position;
}
/**
* @return PHP_Token
*/
public function current()
{
return $this->tokens[$this->position];
}
/**
*/
public function next()
{
$this->position++;
}
/**
* @param mixed $offset
*/
public function offsetExists($offset)
{
return isset($this->tokens[$offset]);
}
/**
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset)
{
return $this->tokens[$offset];
}
/**
* @param mixed $offset
* @param mixed $value
*/
public function offsetSet($offset, $value)
{
$this->tokens[$offset] = $value;
}
/**
* @param mixed $offset
*/
public function offsetUnset($offset)
{
unset($this->tokens[$offset]);
}
/**
* Seek to an absolute position.
*
* @param integer $position
* @throws OutOfBoundsException
*/
public function seek($position)
{
$this->position = $position;
if (!$this->valid()) {
throw new OutOfBoundsException('Invalid seek position');
}
}
}
<?php
/**
* php-token-stream
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHP_TokenStream
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @since File available since Release 1.0.0
*/
/**
* A caching factory for token stream objects.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.1.5
* @link http://github.com/sebastianbergmann/php-token-stream/tree
* @since Class available since Release 1.0.0
*/
class PHP_Token_Stream_CachingFactory
{
/**
* @var array
*/
protected static $cache = array();
/**
* @param string $filename
* @return PHP_Token_Stream
*/
public static function get($filename)
{
if (!isset(self::$cache[$filename])) {
self::$cache[$filename] = new PHP_Token_Stream($filename);
}
return self::$cache[$filename];
}
/**
* @param string $filename
*/
public static function clear($filename = NULL)
{
if (is_string($filename)) {
unset(self::$cache[$filename]);
} else {
self::$cache = array();
}
}
}
<?php
/**
* php-token-stream
*
* Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package PHP_TokenStream
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @since File available since Release 1.0.0
*/
/**
* A PHP token.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: 1.1.5
* @link http://github.com/sebastianbergmann/php-token-stream/tree
* @since Class available since Release 1.0.0
*/
abstract class PHP_Token
{
/**
* @var string
*/
protected $text;
/**
* @var integer
*/
protected $line;
/**
* @var PHP_Token_Stream
*/
protected $tokenStream;
/**
* @var integer
*/
protected $id;
/**
* Constructor.
*
* @param string $text
* @param integer $line
* @param PHP_Token_Stream $tokenStream
* @param integer $id
*/
public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
{
$this->text = $text;
$this->line = $line;
$this->tokenStream = $tokenStream;
$this->id = $id;
}
/**
* @return string
*/
public function __toString()
{
return $this->text;
}
/**
* @return integer
*/
public function getLine()
{
return $this->line;
}
}
abstract class PHP_TokenWithScope extends PHP_Token
{
protected $endTokenId;
/**
* Get the docblock for this token
*
* This method will fetch the docblock belonging to the current token. The
* docblock must be placed on the line directly above the token to be
* recognized.
*
* @return string|null Returns the docblock as a string if found
*/
public function getDocblock()
{
$tokens = $this->tokenStream->tokens();
$currentLineNumber = $tokens[$this->id]->getLine();
$prevLineNumber = $currentLineNumber - 1;
for ($i = $this->id - 1; $i; $i--) {
if (!isset($tokens[$i])) {
return;
}
if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
$tokens[$i] instanceof PHP_Token_CLASS ||
$tokens[$i] instanceof PHP_Token_TRAIT) {
// Some other trait, class or function, no docblock can be
// used for the current token
break;
}
$line = $tokens[$i]->getLine();
if ($line == $currentLineNumber ||
($line == $prevLineNumber &&
$tokens[$i] instanceof PHP_Token_WHITESPACE)) {
continue;
}
if ($line < $currentLineNumber &&
!$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
break;
}
return (string)$tokens[$i];
}
}
public function getEndTokenId()
{
$block = 0;
$i = $this->id;
$tokens = $this->tokenStream->tokens();
while ($this->endTokenId === NULL && isset($tokens[$i])) {
if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
$tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
$block++;
}
else if ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
$block--;
if ($block === 0) {
$this->endTokenId = $i;
}
}
else if (($this instanceof PHP_Token_FUNCTION ||
$this instanceof PHP_Token_NAMESPACE) &&
$tokens[$i] instanceof PHP_Token_SEMICOLON) {
if ($block === 0) {
$this->endTokenId = $i;
}
}
$i++;
}
if ($this->endTokenId === NULL) {
$this->endTokenId = $this->id;
}
return $this->endTokenId;
}
public function getEndLine()
{
return $this->tokenStream[$this->getEndTokenId()]->getLine();
}
}
abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope {
public function getVisibility()
{
$tokens = $this->tokenStream->tokens();
for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
if (isset($tokens[$i]) &&
($tokens[$i] instanceof PHP_Token_PRIVATE ||
$tokens[$i] instanceof PHP_Token_PROTECTED ||
$tokens[$i] instanceof PHP_Token_PUBLIC)) {
return strtolower(
str_replace('PHP_Token_', '', get_class($tokens[$i]))
);
}
if (isset($tokens[$i]) &&
!($tokens[$i] instanceof PHP_Token_STATIC ||
$tokens[$i] instanceof PHP_Token_FINAL ||
$tokens[$i] instanceof PHP_Token_ABSTRACT)) {
// no keywords; stop visibility search
break;
}
}
}
public function getKeywords()
{
$keywords = array();
$tokens = $this->tokenStream->tokens();
for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
if (isset($tokens[$i]) &&
($tokens[$i] instanceof PHP_Token_PRIVATE ||
$tokens[$i] instanceof PHP_Token_PROTECTED ||
$tokens[$i] instanceof PHP_Token_PUBLIC)) {
continue;
}
if (isset($tokens[$i]) &&
($tokens[$i] instanceof PHP_Token_STATIC ||
$tokens[$i] instanceof PHP_Token_FINAL ||
$tokens[$i] instanceof PHP_Token_ABSTRACT)) {
$keywords[] = strtolower(
str_replace('PHP_Token_', '', get_class($tokens[$i]))
);
}
}
return implode(',', $keywords);
}
}
abstract class PHP_Token_Includes extends PHP_Token
{
protected $name;
protected $type;
public function getName()
{
if ($this->name !== NULL) {
return $this->name;
}
$tokens = $this->tokenStream->tokens();
if ($tokens[$this->id+2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
$this->name = trim($tokens[$this->id+2], "'\"");
$this->type = strtolower(
str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
);
}
return $this->name;
}
public function getType()
{
$this->getName();
return $this->type;
}
}
class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes {}
class PHP_Token_REQUIRE extends PHP_Token_Includes {}
class PHP_Token_EVAL extends PHP_Token {}
class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes {}
class PHP_Token_INCLUDE extends PHP_Token_Includes {}
class PHP_Token_LOGICAL_OR extends PHP_Token {}
class PHP_Token_LOGICAL_XOR extends PHP_Token {}
class PHP_Token_LOGICAL_AND extends PHP_Token {}
class PHP_Token_PRINT extends PHP_Token {}
class PHP_Token_SR_EQUAL extends PHP_Token {}
class PHP_Token_SL_EQUAL extends PHP_Token {}
class PHP_Token_XOR_EQUAL extends PHP_Token {}
class PHP_Token_OR_EQUAL extends PHP_Token {}
class PHP_Token_AND_EQUAL extends PHP_Token {}
class PHP_Token_MOD_EQUAL extends PHP_Token {}
class PHP_Token_CONCAT_EQUAL extends PHP_Token {}
class PHP_Token_DIV_EQUAL extends PHP_Token {}
class PHP_Token_MUL_EQUAL extends PHP_Token {}
class PHP_Token_MINUS_EQUAL extends PHP_Token {}
class PHP_Token_PLUS_EQUAL extends PHP_Token {}
class PHP_Token_BOOLEAN_OR extends PHP_Token {}
class PHP_Token_BOOLEAN_AND extends PHP_Token {}
class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token {}
class PHP_Token_IS_IDENTICAL extends PHP_Token {}
class PHP_Token_IS_NOT_EQUAL extends PHP_Token {}
class PHP_Token_IS_EQUAL extends PHP_Token {}
class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token {}
class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token {}
class PHP_Token_SR extends PHP_Token {}
class PHP_Token_SL extends PHP_Token {}
class PHP_Token_INSTANCEOF extends PHP_Token {}
class PHP_Token_UNSET_CAST extends PHP_Token {}
class PHP_Token_BOOL_CAST extends PHP_Token {}
class PHP_Token_OBJECT_CAST extends PHP_Token {}
class PHP_Token_ARRAY_CAST extends PHP_Token {}
class PHP_Token_STRING_CAST extends PHP_Token {}
class PHP_Token_DOUBLE_CAST extends PHP_Token {}
class PHP_Token_INT_CAST extends PHP_Token {}
class PHP_Token_DEC extends PHP_Token {}
class PHP_Token_INC extends PHP_Token {}
class PHP_Token_CLONE extends PHP_Token {}
class PHP_Token_NEW extends PHP_Token {}
class PHP_Token_EXIT extends PHP_Token {}
class PHP_Token_IF extends PHP_Token {}
class PHP_Token_ELSEIF extends PHP_Token {}
class PHP_Token_ELSE extends PHP_Token {}
class PHP_Token_ENDIF extends PHP_Token {}
class PHP_Token_LNUMBER extends PHP_Token {}
class PHP_Token_DNUMBER extends PHP_Token {}
class PHP_Token_STRING extends PHP_Token {}
class PHP_Token_STRING_VARNAME extends PHP_Token {}
class PHP_Token_VARIABLE extends PHP_Token {}
class PHP_Token_NUM_STRING extends PHP_Token {}
class PHP_Token_INLINE_HTML extends PHP_Token {}
class PHP_Token_CHARACTER extends PHP_Token {}
class PHP_Token_BAD_CHARACTER extends PHP_Token {}
class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token {}
class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token {}
class PHP_Token_ECHO extends PHP_Token {}
class PHP_Token_DO extends PHP_Token {}
class PHP_Token_WHILE extends PHP_Token {}
class PHP_Token_ENDWHILE extends PHP_Token {}
class PHP_Token_FOR extends PHP_Token {}
class PHP_Token_ENDFOR extends PHP_Token {}
class PHP_Token_FOREACH extends PHP_Token {}
class PHP_Token_ENDFOREACH extends PHP_Token {}
class PHP_Token_DECLARE extends PHP_Token {}
class PHP_Token_ENDDECLARE extends PHP_Token {}
class PHP_Token_AS extends PHP_Token {}
class PHP_Token_SWITCH extends PHP_Token {}
class PHP_Token_ENDSWITCH extends PHP_Token {}
class PHP_Token_CASE extends PHP_Token {}
class PHP_Token_DEFAULT extends PHP_Token {}
class PHP_Token_BREAK extends PHP_Token {}
class PHP_Token_CONTINUE extends PHP_Token {}
class PHP_Token_GOTO extends PHP_Token {}
class PHP_Token_CALLABLE extends PHP_Token {}
class PHP_Token_INSTEADOF extends PHP_Token {}
class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
{
protected $arguments;
protected $ccn;
protected $name;
protected $signature;
public function getArguments()
{
if ($this->arguments !== NULL) {
return $this->arguments;
}
$this->arguments = array();
$i = $this->id + 3;
$tokens = $this->tokenStream->tokens();
$typeHint = NULL;
while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
if ($tokens[$i] instanceof PHP_Token_STRING) {
$typeHint = (string)$tokens[$i];
}
else if ($tokens[$i] instanceof PHP_Token_VARIABLE) {
$this->arguments[(string)$tokens[$i]] = $typeHint;
$typeHint = NULL;
}
$i++;
}
return $this->arguments;
}
public function getName()
{
if ($this->name !== NULL) {
return $this->name;
}
$tokens = $this->tokenStream->tokens();
if ($tokens[$this->id+2] instanceof PHP_Token_STRING) {
$this->name = (string)$tokens[$this->id+2];
}
else if ($tokens[$this->id+2] instanceof PHP_Token_AMPERSAND &&
$tokens[$this->id+3] instanceof PHP_Token_STRING) {
$this->name = (string)$tokens[$this->id+3];
}
else {
$this->name = 'anonymous function';
}
if ($this->name != 'anonymous function') {
for ($i = $this->id; $i; --$i) {
if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
$this->name = $tokens[$i]->getName() . '\\' . $this->name;
break;
}
if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
break;
}
}
}
return $this->name;
}
public function getCCN()
{
if ($this->ccn !== NULL) {
return $this->ccn;
}
$this->ccn = 1;
$end = $this->getEndTokenId();
$tokens = $this->tokenStream->tokens();
for ($i = $this->id; $i <= $end; $i++) {
switch (get_class($tokens[$i])) {
case 'PHP_Token_IF':
case 'PHP_Token_ELSEIF':
case 'PHP_Token_FOR':
case 'PHP_Token_FOREACH':
case 'PHP_Token_WHILE':
case 'PHP_Token_CASE':
case 'PHP_Token_CATCH':
case 'PHP_Token_BOOLEAN_AND':
case 'PHP_Token_LOGICAL_AND':
case 'PHP_Token_BOOLEAN_OR':
case 'PHP_Token_LOGICAL_OR':
case 'PHP_Token_QUESTION_MARK': {
$this->ccn++;
}
break;
}
}
return $this->ccn;
}
public function getSignature()
{
if ($this->signature !== NULL) {
return $this->signature;
}
if ($this->getName() == 'anonymous function') {
$this->signature = 'anonymous function';
$i = $this->id + 1;
} else {
$this->signature = '';
$i = $this->id + 2;
}
$tokens = $this->tokenStream->tokens();
while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
$this->signature .= $tokens[$i++];
}
$this->signature .= ')';
return $this->signature;
}
}
class PHP_Token_CONST extends PHP_Token {}
class PHP_Token_RETURN extends PHP_Token {}
class PHP_Token_TRY extends PHP_Token {}
class PHP_Token_CATCH extends PHP_Token {}
class PHP_Token_THROW extends PHP_Token {}
class PHP_Token_USE extends PHP_Token {}
class PHP_Token_GLOBAL extends PHP_Token {}
class PHP_Token_PUBLIC extends PHP_Token {}
class PHP_Token_PROTECTED extends PHP_Token {}
class PHP_Token_PRIVATE extends PHP_Token {}
class PHP_Token_FINAL extends PHP_Token {}
class PHP_Token_ABSTRACT extends PHP_Token {}
class PHP_Token_STATIC extends PHP_Token {}
class PHP_Token_VAR extends PHP_Token {}
class PHP_Token_UNSET extends PHP_Token {}
class PHP_Token_ISSET extends PHP_Token {}
class PHP_Token_EMPTY extends PHP_Token {}
class PHP_Token_HALT_COMPILER extends PHP_Token {}
class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
{
protected $interfaces;
public function getName()
{
return (string)$this->tokenStream[$this->id + 2];
}
public function hasParent()
{
return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
}
public function getPackage()
{
$className = $this->getName();
$docComment = $this->getDocblock();
$result = array(
'namespace' => '',
'fullPackage' => '',
'category' => '',
'package' => '',
'subpackage' => ''
);
for ($i = $this->id; $i; --$i) {
if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
$result['namespace'] = $this->tokenStream[$i]->getName();
break;
}
}
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'] = $this->arrayToName(
explode('_', str_replace('\\', '_', $className)), '.'
);
}
return $result;
}
protected function arrayToName(array $parts, $join = '\\')
{
$result = '';
if (count($parts) > 1) {
array_pop($parts);
$result = join($join, $parts);
}
return $result;
}
public function getParent()
{
if (!$this->hasParent()) {
return FALSE;
}
$i = $this->id + 6;
$tokens = $this->tokenStream->tokens();
$className = (string)$tokens[$i];
while (isset($tokens[$i+1]) &&
!$tokens[$i+1] instanceof PHP_Token_WHITESPACE) {
$className .= (string)$tokens[++$i];
}
return $className;
}
public function hasInterfaces()
{
return (isset($this->tokenStream[$this->id + 4]) &&
$this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
(isset($this->tokenStream[$this->id + 8]) &&
$this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
}
public function getInterfaces()
{
if ($this->interfaces !== NULL) {
return $this->interfaces;
}
if (!$this->hasInterfaces()) {
return ($this->interfaces = FALSE);
}
if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
$i = $this->id + 3;
} else {
$i = $this->id + 7;
}
$tokens = $this->tokenStream->tokens();
while (!$tokens[$i+1] instanceof PHP_Token_OPEN_CURLY) {
$i++;
if ($tokens[$i] instanceof PHP_Token_STRING) {
$this->interfaces[] = (string)$tokens[$i];
}
}
return $this->interfaces;
}
}
class PHP_Token_CLASS extends PHP_Token_INTERFACE {}
class PHP_Token_TRAIT extends PHP_Token_INTERFACE {}
class PHP_Token_EXTENDS extends PHP_Token {}
class PHP_Token_IMPLEMENTS extends PHP_Token {}
class PHP_Token_OBJECT_OPERATOR extends PHP_Token {}
class PHP_Token_DOUBLE_ARROW extends PHP_Token {}
class PHP_Token_LIST extends PHP_Token {}
class PHP_Token_ARRAY extends PHP_Token {}
class PHP_Token_CLASS_C extends PHP_Token {}
class PHP_Token_TRAIT_C extends PHP_Token {}
class PHP_Token_METHOD_C extends PHP_Token {}
class PHP_Token_FUNC_C extends PHP_Token {}
class PHP_Token_LINE extends PHP_Token {}
class PHP_Token_FILE extends PHP_Token {}
class PHP_Token_COMMENT extends PHP_Token {}
class PHP_Token_DOC_COMMENT extends PHP_Token {}
class PHP_Token_OPEN_TAG extends PHP_Token {}
class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token {}
class PHP_Token_CLOSE_TAG extends PHP_Token {}
class PHP_Token_WHITESPACE extends PHP_Token {}
class PHP_Token_START_HEREDOC extends PHP_Token {}
class PHP_Token_END_HEREDOC extends PHP_Token {}
class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token {}
class PHP_Token_CURLY_OPEN extends PHP_Token {}
class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token {}
class PHP_Token_NAMESPACE extends PHP_TokenWithScope
{
public function getName()
{
$tokens = $this->tokenStream->tokens();
$namespace = (string)$tokens[$this->id+2];
for ($i = $this->id + 3; ; $i += 2) {
if (isset($tokens[$i]) &&
$tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
$namespace .= '\\' . $tokens[$i+1];
} else {
break;
}
}
return $namespace;
}
}
class PHP_Token_NS_C extends PHP_Token {}
class PHP_Token_DIR extends PHP_Token {}
class PHP_Token_NS_SEPARATOR extends PHP_Token {}
class PHP_Token_DOUBLE_COLON extends PHP_Token {}
class PHP_Token_OPEN_BRACKET extends PHP_Token {}
class PHP_Token_CLOSE_BRACKET extends PHP_Token {}
class PHP_Token_OPEN_SQUARE extends PHP_Token {}
class PHP_Token_CLOSE_SQUARE extends PHP_Token {}
class PHP_Token_OPEN_CURLY extends PHP_Token {}
class PHP_Token_CLOSE_CURLY extends PHP_Token {}
class PHP_Token_SEMICOLON extends PHP_Token {}
class PHP_Token_DOT extends PHP_Token {}
class PHP_Token_COMMA extends PHP_Token {}
class PHP_Token_EQUAL extends PHP_Token {}
class PHP_Token_LT extends PHP_Token {}
class PHP_Token_GT extends PHP_Token {}
class PHP_Token_PLUS extends PHP_Token {}
class PHP_Token_MINUS extends PHP_Token {}
class PHP_Token_MULT extends PHP_Token {}
class PHP_Token_DIV extends PHP_Token {}
class PHP_Token_QUESTION_MARK extends PHP_Token {}
class PHP_Token_EXCLAMATION_MARK extends PHP_Token {}
class PHP_Token_COLON extends PHP_Token {}
class PHP_Token_DOUBLE_QUOTES extends PHP_Token {}
class PHP_Token_AT extends PHP_Token {}
class PHP_Token_AMPERSAND extends PHP_Token {}
class PHP_Token_PERCENT extends PHP_Token {}
class PHP_Token_PIPE extends PHP_Token {}
class PHP_Token_DOLLAR extends PHP_Token {}
class PHP_Token_CARET extends PHP_Token {}
class PHP_Token_TILDE extends PHP_Token {}
class PHP_Token_BACKTICK extends PHP_Token {}
PHP_TokenStream
Copyright (c) 2009-2012, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
PHP_TokenStream 1.1
===================
This is the list of changes for the PHP_TokenStream 1.1 release series.
PHP_TokenStream 1.1.5
---------------------
* No changes.
PHP_TokenStream 1.1.4
---------------------
* No changes.
PHP_TokenStream 1.1.3
---------------------
* Added class for the `T_TRAIT_C` token that was added in PHP 5.4.
PHP_TokenStream 1.1.2
---------------------
* Added classes for the `T_CALLABLE` and `T_INSTEADOF` tokens that were added in PHP 5.4.
* Added support for namespaced functions.
PHP_TokenStream 1.1.1
---------------------
* Fixed issue #19: Notice in `PHP_Token_INTERFACE::hasInterfaces()`.
PHP_TokenStream 1.1.0
---------------------
* Moved `phptok` tool to separate package.
PHP_TokenStream
===============
Installation
------------
PHP_TokenStream should be installed using the [PEAR Installer](http://pear.php.net/). This installer is the backbone of PEAR, which provides a distribution system for PHP packages, and is shipped with every release of PHP since version 4.3.0.
The PEAR channel (`pear.phpunit.de`) that is used to distribute PHP_TokenStream needs to be registered with the local PEAR environment:
sb@ubuntu ~ % pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded
This has to be done only once. Now the PEAR Installer can be used to install packages from the PHPUnit channel:
sb@ubuntu tokenstream % pear install phpunit/PHP_TokenStream-beta
downloading PHP_TokenStream-0.9.1.tgz ...
Starting to download PHP_TokenStream-0.9.1.tgz (5,113 bytes)
...done: 5,113 bytes
install ok: channel://pear.phpunit.de/PHP_TokenStream-0.9.1
After the installation you can find the PHP_TokenStream source files inside your local PEAR directory; the path is usually `/usr/lib/php/PHP`.
<DB>Q<BF><CC>%F3<46>e<8E>vB <0B><><AE>qjGBMB