snappymail/vendors/phpunit.phar
RainLoop Team 5236810d6b Added tests
Small fixes
2014-05-29 20:01:10 +04:00

72848 lines
3.1 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
if ($GLOBALS['_SERVER']['SCRIPT_NAME'] != '-') {
$phar = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
} else {
$files = get_included_files();
$phar = $files[0];
}
define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', $phar));
define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-4.1.1.phar');
spl_autoload_register(
function ($class)
{
static $classes = NULL;
if ($classes === NULL) {
$classes = array(
'file_iterator' => '/php-file-iterator/Iterator.php',
'file_iterator_facade' => '/php-file-iterator/Iterator/Facade.php',
'file_iterator_factory' => '/php-file-iterator/Iterator/Factory.php',
'php_codecoverage' => '/php-code-coverage/CodeCoverage.php',
'php_codecoverage_driver' => '/php-code-coverage/CodeCoverage/Driver.php',
'php_codecoverage_driver_hhvm' => '/php-code-coverage/CodeCoverage/Driver/HHVM.php',
'php_codecoverage_driver_xdebug' => '/php-code-coverage/CodeCoverage/Driver/Xdebug.php',
'php_codecoverage_exception' => '/php-code-coverage/CodeCoverage/Exception.php',
'php_codecoverage_exception_unintentionallycoveredcode' => '/php-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php',
'php_codecoverage_filter' => '/php-code-coverage/CodeCoverage/Filter.php',
'php_codecoverage_report_clover' => '/php-code-coverage/CodeCoverage/Report/Clover.php',
'php_codecoverage_report_crap4j' => '/php-code-coverage/CodeCoverage/Report/Crap4j.php',
'php_codecoverage_report_factory' => '/php-code-coverage/CodeCoverage/Report/Factory.php',
'php_codecoverage_report_html' => '/php-code-coverage/CodeCoverage/Report/HTML.php',
'php_codecoverage_report_html_renderer' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer.php',
'php_codecoverage_report_html_renderer_dashboard' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php',
'php_codecoverage_report_html_renderer_directory' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.php',
'php_codecoverage_report_html_renderer_file' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php',
'php_codecoverage_report_node' => '/php-code-coverage/CodeCoverage/Report/Node.php',
'php_codecoverage_report_node_directory' => '/php-code-coverage/CodeCoverage/Report/Node/Directory.php',
'php_codecoverage_report_node_file' => '/php-code-coverage/CodeCoverage/Report/Node/File.php',
'php_codecoverage_report_node_iterator' => '/php-code-coverage/CodeCoverage/Report/Node/Iterator.php',
'php_codecoverage_report_php' => '/php-code-coverage/CodeCoverage/Report/PHP.php',
'php_codecoverage_report_text' => '/php-code-coverage/CodeCoverage/Report/Text.php',
'php_codecoverage_report_xml' => '/php-code-coverage/CodeCoverage/Report/XML.php',
'php_codecoverage_report_xml_directory' => '/php-code-coverage/CodeCoverage/Report/XML/Directory.php',
'php_codecoverage_report_xml_file' => '/php-code-coverage/CodeCoverage/Report/XML/File.php',
'php_codecoverage_report_xml_file_coverage' => '/php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php',
'php_codecoverage_report_xml_file_method' => '/php-code-coverage/CodeCoverage/Report/XML/File/Method.php',
'php_codecoverage_report_xml_file_report' => '/php-code-coverage/CodeCoverage/Report/XML/File/Report.php',
'php_codecoverage_report_xml_file_unit' => '/php-code-coverage/CodeCoverage/Report/XML/File/Unit.php',
'php_codecoverage_report_xml_node' => '/php-code-coverage/CodeCoverage/Report/XML/Node.php',
'php_codecoverage_report_xml_project' => '/php-code-coverage/CodeCoverage/Report/XML/Project.php',
'php_codecoverage_report_xml_tests' => '/php-code-coverage/CodeCoverage/Report/XML/Tests.php',
'php_codecoverage_report_xml_totals' => '/php-code-coverage/CodeCoverage/Report/XML/Totals.php',
'php_codecoverage_util' => '/php-code-coverage/CodeCoverage/Util.php',
'php_codecoverage_util_invalidargumenthelper' => '/php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php',
'php_invoker' => '/php-invoker/Invoker.php',
'php_invoker_timeoutexception' => '/php-invoker/Invoker/TimeoutException.php',
'php_timer' => '/php-timer/Timer.php',
'php_token' => '/php-token-stream/Token.php',
'php_token_abstract' => '/php-token-stream/Token.php',
'php_token_ampersand' => '/php-token-stream/Token.php',
'php_token_and_equal' => '/php-token-stream/Token.php',
'php_token_array' => '/php-token-stream/Token.php',
'php_token_array_cast' => '/php-token-stream/Token.php',
'php_token_as' => '/php-token-stream/Token.php',
'php_token_at' => '/php-token-stream/Token.php',
'php_token_backtick' => '/php-token-stream/Token.php',
'php_token_bad_character' => '/php-token-stream/Token.php',
'php_token_bool_cast' => '/php-token-stream/Token.php',
'php_token_boolean_and' => '/php-token-stream/Token.php',
'php_token_boolean_or' => '/php-token-stream/Token.php',
'php_token_break' => '/php-token-stream/Token.php',
'php_token_callable' => '/php-token-stream/Token.php',
'php_token_caret' => '/php-token-stream/Token.php',
'php_token_case' => '/php-token-stream/Token.php',
'php_token_catch' => '/php-token-stream/Token.php',
'php_token_character' => '/php-token-stream/Token.php',
'php_token_class' => '/php-token-stream/Token.php',
'php_token_class_c' => '/php-token-stream/Token.php',
'php_token_class_name_constant' => '/php-token-stream/Token.php',
'php_token_clone' => '/php-token-stream/Token.php',
'php_token_close_bracket' => '/php-token-stream/Token.php',
'php_token_close_curly' => '/php-token-stream/Token.php',
'php_token_close_square' => '/php-token-stream/Token.php',
'php_token_close_tag' => '/php-token-stream/Token.php',
'php_token_colon' => '/php-token-stream/Token.php',
'php_token_comma' => '/php-token-stream/Token.php',
'php_token_comment' => '/php-token-stream/Token.php',
'php_token_concat_equal' => '/php-token-stream/Token.php',
'php_token_const' => '/php-token-stream/Token.php',
'php_token_constant_encapsed_string' => '/php-token-stream/Token.php',
'php_token_continue' => '/php-token-stream/Token.php',
'php_token_curly_open' => '/php-token-stream/Token.php',
'php_token_dec' => '/php-token-stream/Token.php',
'php_token_declare' => '/php-token-stream/Token.php',
'php_token_default' => '/php-token-stream/Token.php',
'php_token_dir' => '/php-token-stream/Token.php',
'php_token_div' => '/php-token-stream/Token.php',
'php_token_div_equal' => '/php-token-stream/Token.php',
'php_token_dnumber' => '/php-token-stream/Token.php',
'php_token_do' => '/php-token-stream/Token.php',
'php_token_doc_comment' => '/php-token-stream/Token.php',
'php_token_dollar' => '/php-token-stream/Token.php',
'php_token_dollar_open_curly_braces' => '/php-token-stream/Token.php',
'php_token_dot' => '/php-token-stream/Token.php',
'php_token_double_arrow' => '/php-token-stream/Token.php',
'php_token_double_cast' => '/php-token-stream/Token.php',
'php_token_double_colon' => '/php-token-stream/Token.php',
'php_token_double_quotes' => '/php-token-stream/Token.php',
'php_token_echo' => '/php-token-stream/Token.php',
'php_token_else' => '/php-token-stream/Token.php',
'php_token_elseif' => '/php-token-stream/Token.php',
'php_token_empty' => '/php-token-stream/Token.php',
'php_token_encapsed_and_whitespace' => '/php-token-stream/Token.php',
'php_token_end_heredoc' => '/php-token-stream/Token.php',
'php_token_enddeclare' => '/php-token-stream/Token.php',
'php_token_endfor' => '/php-token-stream/Token.php',
'php_token_endforeach' => '/php-token-stream/Token.php',
'php_token_endif' => '/php-token-stream/Token.php',
'php_token_endswitch' => '/php-token-stream/Token.php',
'php_token_endwhile' => '/php-token-stream/Token.php',
'php_token_equal' => '/php-token-stream/Token.php',
'php_token_eval' => '/php-token-stream/Token.php',
'php_token_exclamation_mark' => '/php-token-stream/Token.php',
'php_token_exit' => '/php-token-stream/Token.php',
'php_token_extends' => '/php-token-stream/Token.php',
'php_token_file' => '/php-token-stream/Token.php',
'php_token_final' => '/php-token-stream/Token.php',
'php_token_finally' => '/php-token-stream/Token.php',
'php_token_for' => '/php-token-stream/Token.php',
'php_token_foreach' => '/php-token-stream/Token.php',
'php_token_func_c' => '/php-token-stream/Token.php',
'php_token_function' => '/php-token-stream/Token.php',
'php_token_global' => '/php-token-stream/Token.php',
'php_token_goto' => '/php-token-stream/Token.php',
'php_token_gt' => '/php-token-stream/Token.php',
'php_token_halt_compiler' => '/php-token-stream/Token.php',
'php_token_if' => '/php-token-stream/Token.php',
'php_token_implements' => '/php-token-stream/Token.php',
'php_token_inc' => '/php-token-stream/Token.php',
'php_token_include' => '/php-token-stream/Token.php',
'php_token_include_once' => '/php-token-stream/Token.php',
'php_token_includes' => '/php-token-stream/Token.php',
'php_token_inline_html' => '/php-token-stream/Token.php',
'php_token_instanceof' => '/php-token-stream/Token.php',
'php_token_insteadof' => '/php-token-stream/Token.php',
'php_token_int_cast' => '/php-token-stream/Token.php',
'php_token_interface' => '/php-token-stream/Token.php',
'php_token_is_equal' => '/php-token-stream/Token.php',
'php_token_is_greater_or_equal' => '/php-token-stream/Token.php',
'php_token_is_identical' => '/php-token-stream/Token.php',
'php_token_is_not_equal' => '/php-token-stream/Token.php',
'php_token_is_not_identical' => '/php-token-stream/Token.php',
'php_token_is_smaller_or_equal' => '/php-token-stream/Token.php',
'php_token_isset' => '/php-token-stream/Token.php',
'php_token_line' => '/php-token-stream/Token.php',
'php_token_list' => '/php-token-stream/Token.php',
'php_token_lnumber' => '/php-token-stream/Token.php',
'php_token_logical_and' => '/php-token-stream/Token.php',
'php_token_logical_or' => '/php-token-stream/Token.php',
'php_token_logical_xor' => '/php-token-stream/Token.php',
'php_token_lt' => '/php-token-stream/Token.php',
'php_token_method_c' => '/php-token-stream/Token.php',
'php_token_minus' => '/php-token-stream/Token.php',
'php_token_minus_equal' => '/php-token-stream/Token.php',
'php_token_mod_equal' => '/php-token-stream/Token.php',
'php_token_mul_equal' => '/php-token-stream/Token.php',
'php_token_mult' => '/php-token-stream/Token.php',
'php_token_namespace' => '/php-token-stream/Token.php',
'php_token_new' => '/php-token-stream/Token.php',
'php_token_ns_c' => '/php-token-stream/Token.php',
'php_token_ns_separator' => '/php-token-stream/Token.php',
'php_token_num_string' => '/php-token-stream/Token.php',
'php_token_object_cast' => '/php-token-stream/Token.php',
'php_token_object_operator' => '/php-token-stream/Token.php',
'php_token_open_bracket' => '/php-token-stream/Token.php',
'php_token_open_curly' => '/php-token-stream/Token.php',
'php_token_open_square' => '/php-token-stream/Token.php',
'php_token_open_tag' => '/php-token-stream/Token.php',
'php_token_open_tag_with_echo' => '/php-token-stream/Token.php',
'php_token_or_equal' => '/php-token-stream/Token.php',
'php_token_paamayim_nekudotayim' => '/php-token-stream/Token.php',
'php_token_percent' => '/php-token-stream/Token.php',
'php_token_pipe' => '/php-token-stream/Token.php',
'php_token_plus' => '/php-token-stream/Token.php',
'php_token_plus_equal' => '/php-token-stream/Token.php',
'php_token_print' => '/php-token-stream/Token.php',
'php_token_private' => '/php-token-stream/Token.php',
'php_token_protected' => '/php-token-stream/Token.php',
'php_token_public' => '/php-token-stream/Token.php',
'php_token_question_mark' => '/php-token-stream/Token.php',
'php_token_require' => '/php-token-stream/Token.php',
'php_token_require_once' => '/php-token-stream/Token.php',
'php_token_return' => '/php-token-stream/Token.php',
'php_token_semicolon' => '/php-token-stream/Token.php',
'php_token_sl' => '/php-token-stream/Token.php',
'php_token_sl_equal' => '/php-token-stream/Token.php',
'php_token_sr' => '/php-token-stream/Token.php',
'php_token_sr_equal' => '/php-token-stream/Token.php',
'php_token_start_heredoc' => '/php-token-stream/Token.php',
'php_token_static' => '/php-token-stream/Token.php',
'php_token_stream' => '/php-token-stream/Token/Stream.php',
'php_token_stream_cachingfactory' => '/php-token-stream/Token/Stream/CachingFactory.php',
'php_token_string' => '/php-token-stream/Token.php',
'php_token_string_cast' => '/php-token-stream/Token.php',
'php_token_string_varname' => '/php-token-stream/Token.php',
'php_token_switch' => '/php-token-stream/Token.php',
'php_token_throw' => '/php-token-stream/Token.php',
'php_token_tilde' => '/php-token-stream/Token.php',
'php_token_trait' => '/php-token-stream/Token.php',
'php_token_trait_c' => '/php-token-stream/Token.php',
'php_token_try' => '/php-token-stream/Token.php',
'php_token_unset' => '/php-token-stream/Token.php',
'php_token_unset_cast' => '/php-token-stream/Token.php',
'php_token_use' => '/php-token-stream/Token.php',
'php_token_var' => '/php-token-stream/Token.php',
'php_token_variable' => '/php-token-stream/Token.php',
'php_token_while' => '/php-token-stream/Token.php',
'php_token_whitespace' => '/php-token-stream/Token.php',
'php_token_xor_equal' => '/php-token-stream/Token.php',
'php_token_yield' => '/php-token-stream/Token.php',
'php_tokenwithscope' => '/php-token-stream/Token.php',
'php_tokenwithscopeandvisibility' => '/php-token-stream/Token.php',
'phpunit_exception' => '/phpunit/Exception.php',
'phpunit_extensions_database_abstracttester' => '/dbunit/Extensions/Database/AbstractTester.php',
'phpunit_extensions_database_constraint_datasetisequal' => '/dbunit/Extensions/Database/Constraint/DataSetIsEqual.php',
'phpunit_extensions_database_constraint_tableisequal' => '/dbunit/Extensions/Database/Constraint/TableIsEqual.php',
'phpunit_extensions_database_constraint_tablerowcount' => '/dbunit/Extensions/Database/Constraint/TableRowCount.php',
'phpunit_extensions_database_dataset_abstractdataset' => '/dbunit/Extensions/Database/DataSet/AbstractDataSet.php',
'phpunit_extensions_database_dataset_abstracttable' => '/dbunit/Extensions/Database/DataSet/AbstractTable.php',
'phpunit_extensions_database_dataset_abstracttablemetadata' => '/dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php',
'phpunit_extensions_database_dataset_abstractxmldataset' => '/dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php',
'phpunit_extensions_database_dataset_compositedataset' => '/dbunit/Extensions/Database/DataSet/CompositeDataSet.php',
'phpunit_extensions_database_dataset_csvdataset' => '/dbunit/Extensions/Database/DataSet/CsvDataSet.php',
'phpunit_extensions_database_dataset_datasetfilter' => '/dbunit/Extensions/Database/DataSet/DataSetFilter.php',
'phpunit_extensions_database_dataset_defaultdataset' => '/dbunit/Extensions/Database/DataSet/DefaultDataSet.php',
'phpunit_extensions_database_dataset_defaulttable' => '/dbunit/Extensions/Database/DataSet/DefaultTable.php',
'phpunit_extensions_database_dataset_defaulttableiterator' => '/dbunit/Extensions/Database/DataSet/DefaultTableIterator.php',
'phpunit_extensions_database_dataset_defaulttablemetadata' => '/dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php',
'phpunit_extensions_database_dataset_flatxmldataset' => '/dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php',
'phpunit_extensions_database_dataset_idataset' => '/dbunit/Extensions/Database/DataSet/IDataSet.php',
'phpunit_extensions_database_dataset_ipersistable' => '/dbunit/Extensions/Database/DataSet/IPersistable.php',
'phpunit_extensions_database_dataset_ispec' => '/dbunit/Extensions/Database/DataSet/ISpec.php',
'phpunit_extensions_database_dataset_itable' => '/dbunit/Extensions/Database/DataSet/ITable.php',
'phpunit_extensions_database_dataset_itableiterator' => '/dbunit/Extensions/Database/DataSet/ITableIterator.php',
'phpunit_extensions_database_dataset_itablemetadata' => '/dbunit/Extensions/Database/DataSet/ITableMetaData.php',
'phpunit_extensions_database_dataset_iyamlparser' => '/dbunit/Extensions/Database/DataSet/IYamlParser.php',
'phpunit_extensions_database_dataset_mysqlxmldataset' => '/dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php',
'phpunit_extensions_database_dataset_persistors_abstract' => '/dbunit/Extensions/Database/DataSet/Persistors/Abstract.php',
'phpunit_extensions_database_dataset_persistors_factory' => '/dbunit/Extensions/Database/DataSet/Persistors/Factory.php',
'phpunit_extensions_database_dataset_persistors_flatxml' => '/dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php',
'phpunit_extensions_database_dataset_persistors_mysqlxml' => '/dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php',
'phpunit_extensions_database_dataset_persistors_xml' => '/dbunit/Extensions/Database/DataSet/Persistors/Xml.php',
'phpunit_extensions_database_dataset_persistors_yaml' => '/dbunit/Extensions/Database/DataSet/Persistors/Yaml.php',
'phpunit_extensions_database_dataset_querydataset' => '/dbunit/Extensions/Database/DataSet/QueryDataSet.php',
'phpunit_extensions_database_dataset_querytable' => '/dbunit/Extensions/Database/DataSet/QueryTable.php',
'phpunit_extensions_database_dataset_replacementdataset' => '/dbunit/Extensions/Database/DataSet/ReplacementDataSet.php',
'phpunit_extensions_database_dataset_replacementtable' => '/dbunit/Extensions/Database/DataSet/ReplacementTable.php',
'phpunit_extensions_database_dataset_replacementtableiterator' => '/dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php',
'phpunit_extensions_database_dataset_specs_csv' => '/dbunit/Extensions/Database/DataSet/Specs/Csv.php',
'phpunit_extensions_database_dataset_specs_dbquery' => '/dbunit/Extensions/Database/DataSet/Specs/DbQuery.php',
'phpunit_extensions_database_dataset_specs_dbtable' => '/dbunit/Extensions/Database/DataSet/Specs/DbTable.php',
'phpunit_extensions_database_dataset_specs_factory' => '/dbunit/Extensions/Database/DataSet/Specs/Factory.php',
'phpunit_extensions_database_dataset_specs_flatxml' => '/dbunit/Extensions/Database/DataSet/Specs/FlatXml.php',
'phpunit_extensions_database_dataset_specs_ifactory' => '/dbunit/Extensions/Database/DataSet/Specs/IFactory.php',
'phpunit_extensions_database_dataset_specs_xml' => '/dbunit/Extensions/Database/DataSet/Specs/Xml.php',
'phpunit_extensions_database_dataset_specs_yaml' => '/dbunit/Extensions/Database/DataSet/Specs/Yaml.php',
'phpunit_extensions_database_dataset_symfonyyamlparser' => '/dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php',
'phpunit_extensions_database_dataset_tablefilter' => '/dbunit/Extensions/Database/DataSet/TableFilter.php',
'phpunit_extensions_database_dataset_tablemetadatafilter' => '/dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php',
'phpunit_extensions_database_dataset_xmldataset' => '/dbunit/Extensions/Database/DataSet/XmlDataSet.php',
'phpunit_extensions_database_dataset_yamldataset' => '/dbunit/Extensions/Database/DataSet/YamlDataSet.php',
'phpunit_extensions_database_db_dataset' => '/dbunit/Extensions/Database/DB/DataSet.php',
'phpunit_extensions_database_db_defaultdatabaseconnection' => '/dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php',
'phpunit_extensions_database_db_filtereddataset' => '/dbunit/Extensions/Database/DB/FilteredDataSet.php',
'phpunit_extensions_database_db_idatabaseconnection' => '/dbunit/Extensions/Database/DB/IDatabaseConnection.php',
'phpunit_extensions_database_db_imetadata' => '/dbunit/Extensions/Database/DB/IMetaData.php',
'phpunit_extensions_database_db_metadata' => '/dbunit/Extensions/Database/DB/MetaData.php',
'phpunit_extensions_database_db_metadata_dblib' => '/dbunit/Extensions/Database/DB/MetaData/Dblib.php',
'phpunit_extensions_database_db_metadata_firebird' => '/dbunit/Extensions/Database/DB/MetaData/Firebird.php',
'phpunit_extensions_database_db_metadata_informationschema' => '/dbunit/Extensions/Database/DB/MetaData/InformationSchema.php',
'phpunit_extensions_database_db_metadata_mysql' => '/dbunit/Extensions/Database/DB/MetaData/MySQL.php',
'phpunit_extensions_database_db_metadata_oci' => '/dbunit/Extensions/Database/DB/MetaData/Oci.php',
'phpunit_extensions_database_db_metadata_pgsql' => '/dbunit/Extensions/Database/DB/MetaData/PgSQL.php',
'phpunit_extensions_database_db_metadata_sqlite' => '/dbunit/Extensions/Database/DB/MetaData/Sqlite.php',
'phpunit_extensions_database_db_metadata_sqlsrv' => '/dbunit/Extensions/Database/DB/MetaData/SqlSrv.php',
'phpunit_extensions_database_db_resultsettable' => '/dbunit/Extensions/Database/DB/ResultSetTable.php',
'phpunit_extensions_database_db_table' => '/dbunit/Extensions/Database/DB/Table.php',
'phpunit_extensions_database_db_tableiterator' => '/dbunit/Extensions/Database/DB/TableIterator.php',
'phpunit_extensions_database_db_tablemetadata' => '/dbunit/Extensions/Database/DB/TableMetaData.php',
'phpunit_extensions_database_defaulttester' => '/dbunit/Extensions/Database/DefaultTester.php',
'phpunit_extensions_database_exception' => '/dbunit/Extensions/Database/Exception.php',
'phpunit_extensions_database_idatabaselistconsumer' => '/dbunit/Extensions/Database/IDatabaseListConsumer.php',
'phpunit_extensions_database_itester' => '/dbunit/Extensions/Database/ITester.php',
'phpunit_extensions_database_operation_composite' => '/dbunit/Extensions/Database/Operation/Composite.php',
'phpunit_extensions_database_operation_delete' => '/dbunit/Extensions/Database/Operation/Delete.php',
'phpunit_extensions_database_operation_deleteall' => '/dbunit/Extensions/Database/Operation/DeleteAll.php',
'phpunit_extensions_database_operation_exception' => '/dbunit/Extensions/Database/Operation/Exception.php',
'phpunit_extensions_database_operation_factory' => '/dbunit/Extensions/Database/Operation/Factory.php',
'phpunit_extensions_database_operation_idatabaseoperation' => '/dbunit/Extensions/Database/Operation/IDatabaseOperation.php',
'phpunit_extensions_database_operation_insert' => '/dbunit/Extensions/Database/Operation/Insert.php',
'phpunit_extensions_database_operation_null' => '/dbunit/Extensions/Database/Operation/Null.php',
'phpunit_extensions_database_operation_replace' => '/dbunit/Extensions/Database/Operation/Replace.php',
'phpunit_extensions_database_operation_rowbased' => '/dbunit/Extensions/Database/Operation/RowBased.php',
'phpunit_extensions_database_operation_truncate' => '/dbunit/Extensions/Database/Operation/Truncate.php',
'phpunit_extensions_database_operation_update' => '/dbunit/Extensions/Database/Operation/Update.php',
'phpunit_extensions_database_testcase' => '/dbunit/Extensions/Database/TestCase.php',
'phpunit_extensions_database_ui_command' => '/dbunit/Extensions/Database/UI/Command.php',
'phpunit_extensions_database_ui_context' => '/dbunit/Extensions/Database/UI/Context.php',
'phpunit_extensions_database_ui_imedium' => '/dbunit/Extensions/Database/UI/IMedium.php',
'phpunit_extensions_database_ui_imediumprinter' => '/dbunit/Extensions/Database/UI/IMediumPrinter.php',
'phpunit_extensions_database_ui_imode' => '/dbunit/Extensions/Database/UI/IMode.php',
'phpunit_extensions_database_ui_imodefactory' => '/dbunit/Extensions/Database/UI/IModeFactory.php',
'phpunit_extensions_database_ui_invalidmodeexception' => '/dbunit/Extensions/Database/UI/InvalidModeException.php',
'phpunit_extensions_database_ui_mediums_text' => '/dbunit/Extensions/Database/UI/Mediums/Text.php',
'phpunit_extensions_database_ui_modefactory' => '/dbunit/Extensions/Database/UI/ModeFactory.php',
'phpunit_extensions_database_ui_modes_exportdataset' => '/dbunit/Extensions/Database/UI/Modes/ExportDataSet.php',
'phpunit_extensions_database_ui_modes_exportdataset_arguments' => '/dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php',
'phpunit_extensions_grouptestsuite' => '/phpunit/Extensions/GroupTestSuite.php',
'phpunit_extensions_phpttestcase' => '/phpunit/Extensions/PhptTestCase.php',
'phpunit_extensions_phpttestsuite' => '/phpunit/Extensions/PhptTestSuite.php',
'phpunit_extensions_repeatedtest' => '/phpunit/Extensions/RepeatedTest.php',
'phpunit_extensions_selenium2testcase' => '/phpunit-selenium/Extensions/Selenium2TestCase.php',
'phpunit_extensions_selenium2testcase_command' => '/phpunit-selenium/Extensions/Selenium2TestCase/Command.php',
'phpunit_extensions_selenium2testcase_commandsholder' => '/phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.php',
'phpunit_extensions_selenium2testcase_driver' => '/phpunit-selenium/Extensions/Selenium2TestCase/Driver.php',
'phpunit_extensions_selenium2testcase_element' => '/phpunit-selenium/Extensions/Selenium2TestCase/Element.php',
'phpunit_extensions_selenium2testcase_element_accessor' => '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php',
'phpunit_extensions_selenium2testcase_element_select' => '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php',
'phpunit_extensions_selenium2testcase_elementcommand_attribute' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.php',
'phpunit_extensions_selenium2testcase_elementcommand_click' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php',
'phpunit_extensions_selenium2testcase_elementcommand_css' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.php',
'phpunit_extensions_selenium2testcase_elementcommand_equals' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php',
'phpunit_extensions_selenium2testcase_elementcommand_genericaccessor' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.php',
'phpunit_extensions_selenium2testcase_elementcommand_genericpost' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.php',
'phpunit_extensions_selenium2testcase_elementcommand_value' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.php',
'phpunit_extensions_selenium2testcase_elementcriteria' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.php',
'phpunit_extensions_selenium2testcase_exception' => '/phpunit-selenium/Extensions/Selenium2TestCase/Exception.php',
'phpunit_extensions_selenium2testcase_keys' => '/phpunit-selenium/Extensions/Selenium2TestCase/Keys.php',
'phpunit_extensions_selenium2testcase_keysholder' => '/phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php',
'phpunit_extensions_selenium2testcase_noseleniumexception' => '/phpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.php',
'phpunit_extensions_selenium2testcase_response' => '/phpunit-selenium/Extensions/Selenium2TestCase/Response.php',
'phpunit_extensions_selenium2testcase_screenshotlistener' => '/phpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.php',
'phpunit_extensions_selenium2testcase_session' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session.php',
'phpunit_extensions_selenium2testcase_session_cookie' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.php',
'phpunit_extensions_selenium2testcase_session_cookie_builder' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php',
'phpunit_extensions_selenium2testcase_session_storage' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php',
'phpunit_extensions_selenium2testcase_session_timeouts' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php',
'phpunit_extensions_selenium2testcase_sessioncommand_acceptalert' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php',
'phpunit_extensions_selenium2testcase_sessioncommand_alerttext' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.php',
'phpunit_extensions_selenium2testcase_sessioncommand_click' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php',
'phpunit_extensions_selenium2testcase_sessioncommand_dismissalert' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php',
'phpunit_extensions_selenium2testcase_sessioncommand_file' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.php',
'phpunit_extensions_selenium2testcase_sessioncommand_frame' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php',
'phpunit_extensions_selenium2testcase_sessioncommand_genericaccessor' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.php',
'phpunit_extensions_selenium2testcase_sessioncommand_genericattribute' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php',
'phpunit_extensions_selenium2testcase_sessioncommand_keys' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php',
'phpunit_extensions_selenium2testcase_sessioncommand_location' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.php',
'phpunit_extensions_selenium2testcase_sessioncommand_log' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php',
'phpunit_extensions_selenium2testcase_sessioncommand_moveto' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php',
'phpunit_extensions_selenium2testcase_sessioncommand_orientation' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.php',
'phpunit_extensions_selenium2testcase_sessioncommand_url' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php',
'phpunit_extensions_selenium2testcase_sessioncommand_window' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.php',
'phpunit_extensions_selenium2testcase_sessionstrategy' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php',
'phpunit_extensions_selenium2testcase_sessionstrategy_isolated' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php',
'phpunit_extensions_selenium2testcase_sessionstrategy_shared' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.php',
'phpunit_extensions_selenium2testcase_statecommand' => '/phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.php',
'phpunit_extensions_selenium2testcase_url' => '/phpunit-selenium/Extensions/Selenium2TestCase/URL.php',
'phpunit_extensions_selenium2testcase_waituntil' => '/phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php',
'phpunit_extensions_selenium2testcase_webdriverexception' => '/phpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.php',
'phpunit_extensions_selenium2testcase_window' => '/phpunit-selenium/Extensions/Selenium2TestCase/Window.php',
'phpunit_extensions_seleniumbrowsersuite' => '/phpunit-selenium/Extensions/SeleniumBrowserSuite.php',
'phpunit_extensions_seleniumcommon_exithandler' => '/phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php',
'phpunit_extensions_seleniumcommon_remotecoverage' => '/phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.php',
'phpunit_extensions_seleniumtestcase' => '/phpunit-selenium/Extensions/SeleniumTestCase.php',
'phpunit_extensions_seleniumtestcase_driver' => '/phpunit-selenium/Extensions/SeleniumTestCase/Driver.php',
'phpunit_extensions_seleniumtestsuite' => '/phpunit-selenium/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_basetestlistener' => '/phpunit/Framework/BaseTestListener.php',
'phpunit_framework_codecoverageexception' => '/phpunit/Framework/CodeCoverageException.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_invalidcoverstargeterror' => '/phpunit/Framework/InvalidCoversTargetError.php',
'phpunit_framework_invalidcoverstargetexception' => '/phpunit/Framework/InvalidCoversTargetException.php',
'phpunit_framework_mockobject_builder_identity' => '/phpunit-mock-objects/Framework/MockObject/Builder/Identity.php',
'phpunit_framework_mockobject_builder_invocationmocker' => '/phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php',
'phpunit_framework_mockobject_builder_match' => '/phpunit-mock-objects/Framework/MockObject/Builder/Match.php',
'phpunit_framework_mockobject_builder_methodnamematch' => '/phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php',
'phpunit_framework_mockobject_builder_namespace' => '/phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php',
'phpunit_framework_mockobject_builder_parametersmatch' => '/phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php',
'phpunit_framework_mockobject_builder_stub' => '/phpunit-mock-objects/Framework/MockObject/Builder/Stub.php',
'phpunit_framework_mockobject_exception' => '/phpunit-mock-objects/Framework/MockObject/Exception.php',
'phpunit_framework_mockobject_generator' => '/phpunit-mock-objects/Framework/MockObject/Generator.php',
'phpunit_framework_mockobject_invocation' => '/phpunit-mock-objects/Framework/MockObject/Invocation.php',
'phpunit_framework_mockobject_invocation_object' => '/phpunit-mock-objects/Framework/MockObject/Invocation/Object.php',
'phpunit_framework_mockobject_invocation_static' => '/phpunit-mock-objects/Framework/MockObject/Invocation/Static.php',
'phpunit_framework_mockobject_invocationmocker' => '/phpunit-mock-objects/Framework/MockObject/InvocationMocker.php',
'phpunit_framework_mockobject_invokable' => '/phpunit-mock-objects/Framework/MockObject/Invokable.php',
'phpunit_framework_mockobject_matcher' => '/phpunit-mock-objects/Framework/MockObject/Matcher.php',
'phpunit_framework_mockobject_matcher_anyinvokedcount' => '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.php',
'phpunit_framework_mockobject_matcher_anyparameters' => '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php',
'phpunit_framework_mockobject_matcher_consecutiveparameters' => '/phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php',
'phpunit_framework_mockobject_matcher_invocation' => '/phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php',
'phpunit_framework_mockobject_matcher_invokedatindex' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php',
'phpunit_framework_mockobject_matcher_invokedatleastonce' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
'phpunit_framework_mockobject_matcher_invokedcount' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php',
'phpunit_framework_mockobject_matcher_invokedrecorder' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php',
'phpunit_framework_mockobject_matcher_methodname' => '/phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php',
'phpunit_framework_mockobject_matcher_parameters' => '/phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php',
'phpunit_framework_mockobject_matcher_statelessinvocation' => '/phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php',
'phpunit_framework_mockobject_mockbuilder' => '/phpunit-mock-objects/Framework/MockObject/MockBuilder.php',
'phpunit_framework_mockobject_mockobject' => '/phpunit-mock-objects/Framework/MockObject/MockObject.php',
'phpunit_framework_mockobject_stub' => '/phpunit-mock-objects/Framework/MockObject/Stub.php',
'phpunit_framework_mockobject_stub_consecutivecalls' => '/phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php',
'phpunit_framework_mockobject_stub_exception' => '/phpunit-mock-objects/Framework/MockObject/Stub/Exception.php',
'phpunit_framework_mockobject_stub_matchercollection' => '/phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php',
'phpunit_framework_mockobject_stub_return' => '/phpunit-mock-objects/Framework/MockObject/Stub/Return.php',
'phpunit_framework_mockobject_stub_returnargument' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.php',
'phpunit_framework_mockobject_stub_returncallback' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php',
'phpunit_framework_mockobject_stub_returnself' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php',
'phpunit_framework_mockobject_stub_returnvaluemap' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php',
'phpunit_framework_mockobject_verifiable' => '/phpunit-mock-objects/Framework/MockObject/Verifiable.php',
'phpunit_framework_outputerror' => '/phpunit/Framework/OutputError.php',
'phpunit_framework_riskytest' => '/phpunit/Framework/RiskyTest.php',
'phpunit_framework_riskytesterror' => '/phpunit/Framework/RiskyTestError.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_unintentionallycoveredcodeerror' => '/phpunit/Framework/UnintentionallyCoveredCodeError.php',
'phpunit_framework_warning' => '/phpunit/Framework/Warning.php',
'phpunit_runner_basetestrunner' => '/phpunit/Runner/BaseTestRunner.php',
'phpunit_runner_exception' => '/phpunit/Runner/Exception.php',
'phpunit_runner_filter_factory' => '/phpunit/Runner/Filter/Factory.php',
'phpunit_runner_filter_group_exclude' => '/phpunit/Runner/Filter/Group/Exclude.php',
'phpunit_runner_filter_group_include' => '/phpunit/Runner/Filter/Group/Include.php',
'phpunit_runner_filter_groupfilteriterator' => '/phpunit/Runner/Filter/Group.php',
'phpunit_runner_filter_test' => '/phpunit/Runner/Filter/Test.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_blacklist' => '/phpunit/Util/Blacklist.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_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',
'sebastianbergmann\\comparator\\arraycomparator' => '/sebastian-comparator/ArrayComparator.php',
'sebastianbergmann\\comparator\\comparator' => '/sebastian-comparator/Comparator.php',
'sebastianbergmann\\comparator\\comparisonfailure' => '/sebastian-comparator/ComparisonFailure.php',
'sebastianbergmann\\comparator\\datetimecomparator' => '/sebastian-comparator/DateTimeComparator.php',
'sebastianbergmann\\comparator\\domnodecomparator' => '/sebastian-comparator/DOMNodeComparator.php',
'sebastianbergmann\\comparator\\doublecomparator' => '/sebastian-comparator/DoubleComparator.php',
'sebastianbergmann\\comparator\\exceptioncomparator' => '/sebastian-comparator/ExceptionComparator.php',
'sebastianbergmann\\comparator\\factory' => '/sebastian-comparator/Factory.php',
'sebastianbergmann\\comparator\\mockobjectcomparator' => '/sebastian-comparator/MockObjectComparator.php',
'sebastianbergmann\\comparator\\numericcomparator' => '/sebastian-comparator/NumericComparator.php',
'sebastianbergmann\\comparator\\objectcomparator' => '/sebastian-comparator/ObjectComparator.php',
'sebastianbergmann\\comparator\\resourcecomparator' => '/sebastian-comparator/ResourceComparator.php',
'sebastianbergmann\\comparator\\scalarcomparator' => '/sebastian-comparator/ScalarComparator.php',
'sebastianbergmann\\comparator\\splobjectstoragecomparator' => '/sebastian-comparator/SplObjectStorageComparator.php',
'sebastianbergmann\\comparator\\typecomparator' => '/sebastian-comparator/TypeComparator.php',
'sebastianbergmann\\diff\\chunk' => '/sebastian-diff/Chunk.php',
'sebastianbergmann\\diff\\diff' => '/sebastian-diff/Diff.php',
'sebastianbergmann\\diff\\differ' => '/sebastian-diff/Differ.php',
'sebastianbergmann\\diff\\line' => '/sebastian-diff/Line.php',
'sebastianbergmann\\diff\\parser' => '/sebastian-diff/Parser.php',
'sebastianbergmann\\environment\\runtime' => '/sebastian-environment/Runtime.php',
'sebastianbergmann\\exporter\\context' => '/sebastian-exporter/Context.php',
'sebastianbergmann\\exporter\\exception' => '/sebastian-exporter/Exception.php',
'sebastianbergmann\\exporter\\exporter' => '/sebastian-exporter/Exporter.php',
'sebastianbergmann\\version' => '/sebastian-version/Version.php',
'symfony\\component\\yaml\\dumper' => '/symfony/yaml/Symfony/Component/Yaml/Dumper.php',
'symfony\\component\\yaml\\escaper' => '/symfony/yaml/Symfony/Component/Yaml/Escaper.php',
'symfony\\component\\yaml\\exception\\dumpexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php',
'symfony\\component\\yaml\\exception\\exceptioninterface' => '/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php',
'symfony\\component\\yaml\\exception\\parseexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php',
'symfony\\component\\yaml\\exception\\runtimeexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php',
'symfony\\component\\yaml\\inline' => '/symfony/yaml/Symfony/Component/Yaml/Inline.php',
'symfony\\component\\yaml\\parser' => '/symfony/yaml/Symfony/Component/Yaml/Parser.php',
'symfony\\component\\yaml\\unescaper' => '/symfony/yaml/Symfony/Component/Yaml/Unescaper.php',
'symfony\\component\\yaml\\yaml' => '/symfony/yaml/Symfony/Component/Yaml/Yaml.php',
'text_template' => '/php-text-template/Template.php'
);
}
$class = strtolower($class);
if (isset($classes[$class])) {
require __PHPUNIT_PHAR_ROOT__ . $classes[$class];
}
}
);
Phar::mapPhar('phpunit-4.1.1.phar');
if (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == '--manifest') {
print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt');
exit;
}
if ($GLOBALS['_SERVER']['SCRIPT_NAME'] != '-') {
PHPUnit_TextUI_Command::main();
}
__HALT_COMPILER(); ?>
<C0><80><00>phpunit-4.1.1.phar$phpunit/Framework/RiskyTestError.php)
7y<37>S)
y<><79><9E><AF>0phpunit/Framework/ExpectationFailedException.php<68> 7y<37>S<80> <00><0F>-<2D>.phpunit/Framework/InvalidCoversTargetError.phph
7y<37>Sh
<00>޶$phpunit/Framework/SelfDescribing.php<
7y<37>S<
<11>l<05>$phpunit/Framework/IncompleteTest.php
7y<37>S
<00><><DD>8<AC>!phpunit/Framework/TestFailure.php<68>7y<37>S<80><00><>Ŷ phpunit/Framework/Constraint.php<68>7y<37>S<80>/Vpж2phpunit/Framework/InvalidCoversTargetException.php<68> 7y<37>S<80> ں<><DABA><89>&phpunit/Framework/SkippedTestError.php/
7y<37>S/
<00><>)phpunit/Framework/IncompleteTestError.php9
7y<37>S9
<00>#<23>Y<DF>"phpunit/Framework/TestListener.phps7y<37>Ss<00><><AF>B<80>&phpunit/Framework/Assert/Functions.phpp<70>7y<37>Sp<53><00>[<5B>ʶ phpunit/Framework/TestResult.phpt7y<37>St{z<><7A><ED>$phpunit/Framework/SyntheticError.phpA7y<37>SA<00>/3<><33>+phpunit/Framework/SkippedTestSuiteError.php:
7y<37>S:
 <19><>+phpunit/Framework/CodeCoverageException.php<68> 7y<37>S<80> 5&^<5E>phpunit/Framework/Assert.php}<7D>7y<37>S}<7D>L<><4C>l<E3>!phpunit/Framework/SkippedTest.php<68> 7y<37>S<80> K9<4B><17>phpunit/Framework/Warning.php<68> 7y<37>S<80> <00><><98>l<8B>,phpunit/Framework/TestSuite/DataProvider.php<68>
7y<37>S<80>
<00>T<A9>`<60>phpunit/Framework/RiskyTest.php<68> 7y<37>S<80> 7<06><>phpunit/Framework/TestCase.php<68><70>7y<37>S<80><53><00><>E_<45>phpunit/Framework/TestSuite.php<68>i7y<37>S<80>i<0E>a<D0><61>*phpunit/Framework/AssertionFailedError.php<68>
7y<37>S<80>
<00>~Vp<56>phpunit/Framework/Test.php<68>
7y<37>S<80>
S<><53><18>!phpunit/Framework/OutputError.php
7y<37>S
M<>Ժ<D8>phpunit/Framework/Error.php8 7y<37>S8 n<>V<97>$phpunit/Framework/Constraint/Xor.php<68>7y<37>S<80>T<>}8<>2phpunit/Framework/Constraint/ClassHasAttribute.phpd7y<37>SdX<><58>,<2C>(phpunit/Framework/Constraint/IsEmpty.php<68>7y<37>S<80><00><92>&phpunit/Framework/Constraint/Count.phpL7y<37>SL<><E1BF82>1phpunit/Framework/Constraint/StringStartsWith.phpv 7y<37>Sv n<>><3E>)phpunit/Framework/Constraint/SameSize.php 7y<37>S <06><>~<7E>(phpunit/Framework/Constraint/IsEqual.php<68>7y<37>S<80>ӷ<><D3B7>#phpunit/Framework/Constraint/Or.php{7y<37>S{o<10>c<A5>/phpunit/Framework/Constraint/StringContains.php<68>7y<37>S<80>67[<06>*phpunit/Framework/Constraint/Composite.php<68>7y<37>S<80>[L<>m<85>1phpunit/Framework/Constraint/ExceptionMessage.php{7y<37>S{FXc<58>'phpunit/Framework/Constraint/IsNull.php! 7y<37>S! <00><><F8><9E><C5>.phpunit/Framework/Constraint/StringMatches.php<68>7y<37>S<80><00>ښ<>'phpunit/Framework/Constraint/IsType.php7y<37>S<00><>F<BD><46>-phpunit/Framework/Constraint/IsInstanceOf.php[7y<37>S[ߘ<><15>'phpunit/Framework/Constraint/IsTrue.php! 7y<37>S! 0<><30>߶(phpunit/Framework/Constraint/IsFalse.php% 7y<37>S% <00><><A0><91><F7>.phpunit/Framework/Constraint/ExceptionCode.php<68>7y<37>S<80><00>V)<29><>'phpunit/Framework/Constraint/IsJson.php<68>7y<37>S<80>Kh<4B><06>$phpunit/Framework/Constraint/Not.php7y<37>S<00><><CB><E2><DF>,phpunit/Framework/Constraint/ArrayHasKey.phpk7y<37>Sk|<7C><>o<83>*phpunit/Framework/Constraint/PCREMatch.phpj7y<37>Sj<00>1#׶$phpunit/Framework/Constraint/And.phpC7y<37>SC<00><>Z<>)phpunit/Framework/Constraint/Callback.phpK7y<37>SK<00><>O<06>8phpunit/Framework/Constraint/TraversableContainsOnly.php<68>7y<37>S<80>ϸ<>_<BF>*phpunit/Framework/Constraint/Attribute.php<68>7y<37>S<80>J<1A><>)phpunit/Framework/Constraint/LessThan.phpn 7y<37>Sn <00><>`<60><>,phpunit/Framework/Constraint/JsonMatches.php<7y<37>S<<00>t<17><>,phpunit/Framework/Constraint/GreaterThan.phpw 7y<37>Sw p<><70><FE><E0>4phpunit/Framework/Constraint/TraversableContains.php<68>7y<37>S<80><00><><B7><C6><FE>+phpunit/Framework/Constraint/FileExists.php[7y<37>S[yF<79>?<3F>+phpunit/Framework/Constraint/IsAnything.php<68>7y<37>S<80>C<><43>W<D6>3phpunit/Framework/Constraint/ObjectHasAttribute.phpM 7y<37>SM <00><><E9><1F>Aphpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php<68>7y<37>S<80><00><> <09><>8phpunit/Framework/Constraint/ClassHasStaticAttribute.php*7y<37>S*F<>*8<>*phpunit/Framework/Constraint/Exception.php<68>7y<37>S<80><00><08>w<C5>/phpunit/Framework/Constraint/StringEndsWith.php<68> 7y<37>S<80> <00>ȶ,phpunit/Framework/Constraint/IsIdentical.php<68>7y<37>S<80><00>4<>&phpunit/Framework/Error/Deprecated.phpx
7y<37>Sx
9<13>*<2A>"phpunit/Framework/Error/Notice.phpb
7y<37>Sb
<00><>ֶ#phpunit/Framework/Error/Warning.phpe
7y<37>Se
0f<30>l<90>phpunit/Framework/Exception.php<68> 7y<37>S<80> <08>|<1F>&phpunit/Framework/BaseTestListener.php@ 7y<37>S@ 9<>pu<70>5phpunit/Framework/UnintentionallyCoveredCodeError.php-
7y<37>S-
q<>phpunit/Util/Log/TAP.php<68>7y<37>S<80><00><>S`<60>phpunit/Util/Log/JSON.php| 7y<37>S| H7phpunit/Util/Log/JUnit.php#<7y<37>S#<<00>6`W<>phpunit/Util/PHP.php!7y<37>S!v**8<>phpunit/Util/XML.phpc}7y<37>Sc}<00><AB>۶phpunit/Util/Getopt.phpO7y<37>SOsOL޶phpunit/Util/PHP/Windows.php 7y<37>S 2<>u@<40>phpunit/Util/PHP/Default.php<68>7y<37>S<80>@<40>1phpunit/Util/PHP/Template/TestCaseMethod.tpl.dist?7y<37>S?<00><>phpunit/Util/Filesystem.php<68> 7y<37>S<80> <00>f<A6>%<25>phpunit/Util/Type.php 7y<37>S <00><>`<60><>"phpunit/Util/DeprecatedFeature.php<68> 7y<37>S<80> <00>Fpi<70>phpunit/Util/Filter.phpE7y<37>SEe<>/<2F><>)phpunit/Util/DeprecatedFeature/Logger.phpC7y<37>SC<00>Q<91><51><93>phpunit/Util/String.php<68>7y<37>S<80>@<40>R<AC><52>"phpunit/Util/TestSuiteIterator.phph7y<37>Sh<51><D298>phpunit/Util/GlobalState.php^17y<37>S^1<00><>˕<D5>phpunit/Util/Fileloader.php7y<37>S<00><03><>phpunit/Util/Test.phpd|7y<37>Sd|/<2F>C<9C><43>phpunit/Util/Printer.php]7y<37>S]<00><>g\<5C>phpunit/Util/Configuration.php<68><70>7y<37>S<80><53><00><>k0<6B>&phpunit/Util/InvalidArgumentHelper.php<68> 7y<37>S<80> ث1<D8AB><31>phpunit/Util/Blacklist.php7y<37>S<00><><01><>'phpunit/Util/TestDox/NamePrettifier.phpz7y<37>Sz<00>uZE<5A>&phpunit/Util/TestDox/ResultPrinter.php<68>(7y<37>S<80>(<00>Yö+phpunit/Util/TestDox/ResultPrinter/HTML.php<68>7y<37>S<80>7m{<7B><>+phpunit/Util/TestDox/ResultPrinter/Text.php<68> 7y<37>S<80> c<><63>"<22>phpunit/Util/ErrorHandler.php,7y<37>S,<00><>=n<>phpunit/TextUI/Command.php}7y<37>S}j;2<><32> phpunit/TextUI/ResultPrinter.php<68>O7y<37>S<80>O<00>x<E5>ڶphpunit/TextUI/TestRunner.php<68><70>7y<37>S<80><53><00><>EG<45>!phpunit/Runner/BaseTestRunner.phpD7y<37>SD <1E>q<EC>"phpunit/Runner/TestSuiteLoader.php 7y<37>S <00><>@<12>'phpunit/Runner/Filter/Group/Exclude.php
7y<37>S
<00>հ<C0><D5B0>'phpunit/Runner/Filter/Group/Include.php
7y<37>S
<00><10>/<2F>!phpunit/Runner/Filter/Factory.php<68> 7y<37>S<80> <55><D483>phpunit/Runner/Filter/Group.php<68> 7y<37>S<80> <00>t<88>`<60>phpunit/Runner/Filter/Test.php&7y<37>S&<15><><EA><C1>*phpunit/Runner/StandardTestSuiteLoader.php<68>7y<37>S<80><00>Ν<ED><CE9D>phpunit/Runner/Exception.php<68> 7y<37>S<80> 3<> <0C>phpunit/Runner/Version.php<68> 7y<37>S<80> <00>@3;<3B>#phpunit/Extensions/PhptTestCase.php<68>7y<37>S<80>^f@<40><>#phpunit/Extensions/RepeatedTest.phpn7y<37>SnM<>5Y<35>$phpunit/Extensions/TestDecorator.phpi7y<37>Si<00><>%phpunit/Extensions/GroupTestSuite.php<68>7y<37>S<80><00><1C>V<C5>%phpunit/Extensions/TicketListener.php 7y<37>S <00><><B5><E0><CE>$phpunit/Extensions/PhptTestSuite.phpZ 7y<37>SZ [<5B><>M<BB>phpunit/Exception.php<68> 7y<37>S<80> <00><A#<23>)php-code-coverage/CodeCoverage/Driver.php<68>
7y<37>S<80>
!MfT<66>=php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php<68> 7y<37>S<80> H<00>p<D3>)php-code-coverage/CodeCoverage/Filter.php ,7y<37>S ,<00>. ö0php-code-coverage/CodeCoverage/Driver/Xdebug.php<68>7y<37>S<80>a<><61>R<D7>.php-code-coverage/CodeCoverage/Driver/HHVM.php<68> 7y<37>S<80> o4<6F><01>Gphp-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php.
7y<37>S.
se~T<>'php-code-coverage/CodeCoverage/Util.php# 7y<37>S# <00>-php-code-coverage/CodeCoverage/Report/PHP.php 7y<37>S m7ض-php-code-coverage/CodeCoverage/Report/XML.php<68>#7y<37>S<80>#<00><><C3><10><php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.phpnP7y<37>SnP<05>K<B1><4B>Aphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.php<68>7y<37>S<80>S<><53><9A>Aphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php<-7y<37>S<-I<><49><85><F7>Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory.html.distY7y<37>SY<00>ʲr<CAB2>Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.distg7y<37>SgV<> P<>Iphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/holder.js^N7y<37>S^N'<27><>U<87>Nphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/respond.min.js7y<37>S<00>{<7B>Lphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.js| 7y<37>S| 2Yn<59><6E>Lphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/nv.d3.min.js<6A><73>7y<37>S<80><53>K<><4B>&<26>Iphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.jst=7y<37>St=<00><><F5>f<FE>Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.js<6A>q7y<37>S<80>q<00> <0C><12>Iphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.js|x7y<37>S|x<00><><07><>Jphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/style.css 7y<37>S MR#<23><>Jphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.css#27y<37>S#2 b<7F>Rphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.cssy<73>7y<37>Sy<53><00><>F<11>Rphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.distx7y<37>Sx*<1A><><F6>Kphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist<73>
7y<37>S<80>
<00>w<B6><77><C2>Sphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist17y<37>S1itL<74><4C>Uphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist57y<37>S5<00>Z<F1>]<5D>cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf@<40>7y<37>S@<40><00><><06>cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.svg<76><67>7y<37>S<80><53><00>L3A<33>cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eotoO7y<37>SoO<00><>q<B5><71>dphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff[7y<37>S[\<5C><>ζPphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist[7y<37>S[A<><41>Q<E0>7php-code-coverage/CodeCoverage/Report/HTML/Renderer.php<68>&7y<37>S<80>& <14>A<AF>0php-code-coverage/CodeCoverage/Report/Crap4j.php<68>7y<37>S<80>R<>k<86>7php-code-coverage/CodeCoverage/Report/Node/Iterator.php7y<37>S<00>-x<>3php-code-coverage/CodeCoverage/Report/Node/File.php\P7y<37>S\P<18><>v<BC>8php-code-coverage/CodeCoverage/Report/Node/Directory.php<68>07y<37>S<80>0<00><>N<9C><4E>1php-code-coverage/CodeCoverage/Report/Factory.phpe7y<37>Se<00><><D5><C3><EE>.php-code-coverage/CodeCoverage/Report/Node.phpm%7y<37>Sm%!z2<11>2php-code-coverage/CodeCoverage/Report/XML/File.php47y<37>S4*<0E>G<98>9php-code-coverage/CodeCoverage/Report/XML/File/Report.php_7y<37>S_<00><1A>Ͷ7php-code-coverage/CodeCoverage/Report/XML/File/Unit.php:7y<37>S:,K<>ö;php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php}7y<37>S}<00>$<24><>9php-code-coverage/CodeCoverage/Report/XML/File/Method.php<68> 7y<37>S<80> <00> <0B>ֶ7php-code-coverage/CodeCoverage/Report/XML/Directory.php<68> 7y<37>S<80> Mٶ0<D9B6>3php-code-coverage/CodeCoverage/Report/XML/Tests.php<68> 7y<37>S<80> <00><><82><FF><B3>2php-code-coverage/CodeCoverage/Report/XML/Node.phpz7y<37>Sz<0E><19><>4php-code-coverage/CodeCoverage/Report/XML/Totals.php<68>7y<37>S<80>g<><67><19>5php-code-coverage/CodeCoverage/Report/XML/Project.phpu7y<37>Su<><C7AE>.php-code-coverage/CodeCoverage/Report/HTML.php7y<37>S<00><14><><98>.php-code-coverage/CodeCoverage/Report/Text.php<68>)7y<37>S<80>)<00><1E>9<E4>0php-code-coverage/CodeCoverage/Report/Clover.php07y<37>S0s<>Զ,php-code-coverage/CodeCoverage/Exception.php<68> 7y<37>S<80> x<>'<27><>"php-code-coverage/CodeCoverage.php<68>j7y<37>S<80>jf<>;<3B>,symfony/yaml/Symfony/Component/Yaml/Yaml.php 7y<37>S <00><>~<7E>/symfony/yaml/Symfony/Component/Yaml/Escaper.phpm 7y<37>Sm m2<0E><>.symfony/yaml/Symfony/Component/Yaml/Parser.phpQ[7y<37>SQ[<00>7<97><37><81>.symfony/yaml/Symfony/Component/Yaml/Dumper.php<68> 7y<37>S<80> <00>H<E1><48><AA>1symfony/yaml/Symfony/Component/Yaml/Unescaper.php<68>7y<37>S<80><00><><B2>׶?symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php<68>7y<37>S<80>ؙ՚<D899>Dsymfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php<68>7y<37>S<80><00>+<2B>l<AD>@symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php<68> 7y<37>S<80> <08><><04>Bsymfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php<68>7y<37>S<80><00>|<7C>-<2D>.symfony/yaml/Symfony/Component/Yaml/Inline.php<68>?7y<37>S<80>?<0F>۱<B4>sebastian-exporter/Exporter.php&7y<37>S&<00><><D1><FE><D4> sebastian-exporter/Exception.php] 7y<37>S] <00>#1<><31>sebastian-exporter/Context.php(7y<37>S(`<60>S<> manifest.txt<78>7y<37>S<80>
<86>$<24><>5phpunit-selenium/Extensions/SeleniumCommon/append.php 7y<37>S <00><><9B><B7><FA>:phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php*7y<37>S*<00><><A2>϶?phpunit-selenium/Extensions/SeleniumCommon/phpunit_coverage.php<68> 7y<37>S<80> ow<6F><77><8D>6phpunit-selenium/Extensions/SeleniumCommon/prepend.php? 7y<37>S? <1A><><B0><B7>=phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.php>7y<37>S>*dBʶ1phpunit-selenium/Extensions/SeleniumTestSuite.php7y<37>S<00><><1D><>8phpunit-selenium/Extensions/Selenium2TestCase/Driver.php/7y<37>S/z}<7D><><9E>Lphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php1
7y<37>S1
BH<42><05>Qphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php<68>
7y<37>S<80>
<05>B<9B><42>Lphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.php<68> 7y<37>S<80> @\WI<57>Jphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.phpC 7y<37>SC lXim<69>Ephpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.php<68>7y<37>S<80>0<>ߗ<93>Pphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.phpT
7y<37>ST
X<12><><B7>Iphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.php<68> 7y<37>S<80> <00><><F4> <0C>Mphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php6
7y<37>S6
<00>v<D1>l<92>Fphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php<68> 7y<37>S<80> ^<5E>a<FF><61>Dphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php 7y<37>S K<14><><B8>Ephpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php$7y<37>S$w<>ͶFphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php<68> 7y<37>S<80> <00>z"<22>Gphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php<68>7y<37>S<80><00>-
<B6>Dphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php 7y<37>S <00><>"=<3D>Gphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.php<68>
7y<37>S<80>
<00><><95><12>@phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.php<68>7y<37>S<80>Zew<>Dphpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.php<68>7y<37>S<80><00><>|a<>Hphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.phpH7y<37>SH<00>Vm<56><6D>Jphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php<68> 7y<37>S<80> <15><>Ͷ9phpunit-selenium/Extensions/Selenium2TestCase/Session.php<68>/7y<37>S<80>/<00><>ĶAphpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.phpN 7y<37>SN <00><1B>Ephpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.php<68> 7y<37>S<80> <00><11>k<F6>9phpunit-selenium/Extensions/Selenium2TestCase/Command.phpL 7y<37>SL <00>cyƶBphpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php<68>7y<37>S<80><00>\w<><77>@phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php<68>7y<37>S<80><00>L@"<22>Pphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.phpi
7y<37>Si
<00>Pe<50>Lphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.phpW
7y<37>SW
<00>Lq<15>Fphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php+
7y<37>S+
<00>Ļ<1D>Gphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php` 7y<37>S` <00>n<C9>նDphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.phpi 7y<37>Si <00><01>Jphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.phpt 7y<37>St  ˈ<>Fphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.php<68>
7y<37>S<80>
<00>.<2E>$<24>5phpunit-selenium/Extensions/Selenium2TestCase/URL.php<68>7y<37>S<80>HF<48><0F>>phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.phpw
7y<37>Sw
<00>e3Z<33>6phpunit-selenium/Extensions/Selenium2TestCase/Keys.phpI7y<37>SI<00><06>Ͷ9phpunit-selenium/Extensions/Selenium2TestCase/Element.php<68>7y<37>S<80><00><><93><B8><FB>:phpunit-selenium/Extensions/Selenium2TestCase/Response.php7y<37>STZ<15>8phpunit-selenium/Extensions/Selenium2TestCase/Window.phpO 7y<37>SO S<><53><A7><DF>Aphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php<68> 7y<37>S<80> ̳<>r<E3>Dphpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.phpf 7y<37>Sf <00>K1<4B><31><phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php7y<37>S<00>|<7C>H<DA>Aphpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php8 7y<37>S8 <01><><9B><82>Hphpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php7y<37>SӸq<>Bphpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php]7y<37>S]<02>/X<>@phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.php<68>7y<37>S<80>$!<21><><B8>;phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php<68>7y<37>S<80><00>sX<>;phpunit-selenium/Extensions/Selenium2TestCase/Exception.php<68> 7y<37>S<80> H"<22>[<5B>4phpunit-selenium/Extensions/SeleniumBrowserSuite.php<68>7y<37>S<80>D<><44><1D>0phpunit-selenium/Extensions/SeleniumTestCase.phpЖ7y<37>`ec<65>1phpunit-selenium/Extensions/Selenium2TestCase.phpkC7y<37>SkC<00>mf<6D><66>7phpunit-selenium/Extensions/SeleniumTestCase/Driver.php^<5E>7y<37>S^<5E>7'q߶!sebastian-environment/Runtime.php7y<37>S<00>j<1B><>8phpunit-mock-objects/Framework/MockObject/Invocation.php<68> 7y<37>S<80> <00>a?<07>>phpunit-mock-objects/Framework/MockObject/InvocationMocker.php{7y<37>S{h<><68><F2><F7>5phpunit-mock-objects/Framework/MockObject/Matcher.php<68>(7y<37>S<80>(<00>L<E4><4C><86>7phpunit-mock-objects/Framework/MockObject/Generator.php$<24>7y<37>S$<24>z>ox<6F>7phpunit-mock-objects/Framework/MockObject/Invokable.php<68> 7y<37>S<80> <00>]<01><>Dphpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php<68> 7y<37>S<80> <01> <09>=phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php<68> 7y<37>S<80> <>Á<BF>9phpunit-mock-objects/Framework/MockObject/Stub/Return.php<68> 7y<37>S<80> <00><><9A><06>Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php<68> 7y<37>S<80> <00><>Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php<68> 7y<37>S<80> #j{5<>Cphpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php 7y<37>S <00>#<23>|<7C><phpunit-mock-objects/Framework/MockObject/Stub/Exception.phpX 7y<37>SX ȝ>n<>Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.phpe 7y<37>Se <00>M<9E>#<23>?phpunit-mock-objects/Framework/MockObject/Invocation/Object.php 7y<37>S a<>?phpunit-mock-objects/Framework/MockObject/Invocation/Static.phpt7y<37>St<00><>>g<>Kphpunit-mock-objects/Framework/MockObject/Generator/proxied_method.tpl.dist<73>7y<37>S<80>?a<7F><61>Pphpunit-mock-objects/Framework/MockObject/Generator/mocked_class_method.tpl.dist<73>7y<37>S<80><00>Iphpunit-mock-objects/Framework/MockObject/Generator/mocked_clone.tpl.dist<73>7y<37>S<80><00>aT<61>Jphpunit-mock-objects/Framework/MockObject/Generator/mocked_method.tpl.dist<73>7y<37>S<80><00>bV<62><56>Iphpunit-mock-objects/Framework/MockObject/Generator/mocked_class.tpl.dist 7y<37>S <00><>FZ<46>Hphpunit-mock-objects/Framework/MockObject/Generator/wsdl_method.tpl.dist<7y<37>S<<00><>i<D0><69>Gphpunit-mock-objects/Framework/MockObject/Generator/wsdl_class.tpl.dist<73>7y<37>S<80>w&S<>Hphpunit-mock-objects/Framework/MockObject/Generator/trait_class.tpl.dist77y<37>S7<00>[$~<7E>Kphpunit-mock-objects/Framework/MockObject/Generator/unmocked_clone.tpl.dist<73>7y<37>S<80>8W}ض9phpunit-mock-objects/Framework/MockObject/MockBuilder.php<68>%7y<37>S<80>%
<A3>d<B6>8phpunit-mock-objects/Framework/MockObject/Verifiable.php 7y<37>S &n<17>Fphpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php<68>$7y<37>S<80>$p
<9E>O<B6>Ephpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.phpa7y<37>Sa#$ <0C>Ephpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php<68> 7y<37>S<80> <00><><82><1D>?phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php7y<37>S<00>ca<>>phpunit-mock-objects/Framework/MockObject/Builder/Identity.php<68> 7y<37>S<80> N<>ts<74>:phpunit-mock-objects/Framework/MockObject/Builder/Stub.php<68> 7y<37>S<80> t <0B><04>;phpunit-mock-objects/Framework/MockObject/Builder/Match.php<68> 7y<37>S<80> <00>ڂ<84><DA82>8phpunit-mock-objects/Framework/MockObject/MockObject.php>7y<37>S><00>A<84><41><A5>Ephpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.phpA 7y<37>SA t<>M8<4D>@phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.phpe7y<37>Se̸<><CCB8><95>Iphpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php<68>7y<37>S<80><00>7g<37><67>Ephpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php<68>7y<37>S<80>; =P<>Dphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.phpu7y<37>Su<00>a <09><>@phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.phpB7y<37>SB<00>`5h<35>Hphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php/ 7y<37>S/ mrَ<72>@phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php<68>7y<37>S<80><00>e<9C>?<3F>Bphpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php<68>7y<37>S<80>9<><39>2<9A>Cphpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php<68> 7y<37>S<80> <00>e<D2><65><8B>Kphpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php<68>7y<37>S<80>tY<1D>2phpunit-mock-objects/Framework/MockObject/Stub.php<68> 7y<37>S<80> Y<><59><CE><FE>7phpunit-mock-objects/Framework/MockObject/Exception.php<68> 7y<37>S<80> <00>͚<BC><CD9A>php-file-iterator/Iterator.phpc7y<37>Sc~<7E>ԃ<C3>&php-file-iterator/Iterator/Factory.phph7y<37>Sh<00><><F6>ڶ%php-file-iterator/Iterator/Facade.php<68>7y<37>S<80>l<>ca.pem<65>
7y<37>S<80>
s<><73><D3><F1>sebastian-version/Version.php 7y<37>S Y<> <0B>+sebastian-comparator/DateTimeComparator.phpZ7y<37>SZ@Cp<43><70>)sebastian-comparator/ScalarComparator.php<68>7y<37>S<80>_<>(sebastian-comparator/ArrayComparator.phpB7y<37>SB<00>j<A7><6A><BC>#sebastian-comparator/Comparator.php<68>7y<37>S<80><11>6<1A>*sebastian-comparator/NumericComparator.phpA7y<37>SA<00><><CF>۶*sebastian-comparator/ComparisonFailure.php<68>7y<37>S<80> "Ҷ)sebastian-comparator/DoubleComparator.php<68>7y<37>S<80><16>O<B8><4F>)sebastian-comparator/ObjectComparator.php<68>7y<37>S<80><00>t<><74> sebastian-comparator/Factory.php77y<37>S7E<><45><B0><FF>,sebastian-comparator/ExceptionComparator.php<68> 7y<37>S<80> <00><><1A><>3sebastian-comparator/SplObjectStorageComparator.php7y<37>S<00><1E>϶'sebastian-comparator/TypeComparator.php 7y<37>S <00><><9C><E3><F5>-sebastian-comparator/MockObjectComparator.php<68> 7y<37>S<80> *<2A>)+<2B>*sebastian-comparator/DOMNodeComparator.php<68>7y<37>S<80>*<15><>+sebastian-comparator/ResourceComparator.phpV7y<37>SV<00> <20><><94>sebastian-diff/Parser.php<68>7y<37>S<80>H.w<><77>sebastian-diff/Line.php 7y<37>S <00>p<82>B<AB>sebastian-diff/Chunk.php<68> 7y<37>S<80> <00><><A7>%<25>sebastian-diff/Differ.php<68>!7y<37>S<80>!ohrŶsebastian-diff/Diff.php<68> 7y<37>S<80> <00><><99>̶,dbunit/Extensions/Database/DefaultTester.php<68> 7y<37>S<80> <00><>:<3A><>&dbunit/Extensions/Database/ITester.php<68>7y<37>S<80><00><><D2>o<F8>;dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php 7y<37>S ʉ1<10>0dbunit/Extensions/Database/DB/ResultSetTable.php<68> 7y<37>S<80> <00>[<5B><04>5dbunit/Extensions/Database/DB/IDatabaseConnection.php<68>7y<37>S<80><00><>D<8B><44>+dbunit/Extensions/Database/DB/IMetaData.php67y<37>S6<00>v<94>i<F7>'dbunit/Extensions/Database/DB/Table.php<68> 7y<37>S<80> <00><>s5<73><dbunit/Extensions/Database/DB/MetaData/InformationSchema.phpt7y<37>St<00><>ö0dbunit/Extensions/Database/DB/MetaData/MySQL.php<68>7y<37>S<80><00><><8A>0<B1>1dbunit/Extensions/Database/DB/MetaData/Sqlite.php>7y<37>S>=^ف<>.dbunit/Extensions/Database/DB/MetaData/Oci.phpV7y<37>SV<00>+ E<>0dbunit/Extensions/Database/DB/MetaData/PgSQL.php<68>7y<37>S<80><00><>3dbunit/Extensions/Database/DB/MetaData/Firebird.php<68>7y<37>S<80>B<><42>p<CB>0dbunit/Extensions/Database/DB/MetaData/Dblib.php 7y<37>S {ڧ<>1dbunit/Extensions/Database/DB/MetaData/SqlSrv.php<68>7y<37>S<80><00>0 <20><>)dbunit/Extensions/Database/DB/DataSet.php<68>7y<37>S<80>`<60>Wk<57>/dbunit/Extensions/Database/DB/TableIterator.php<68>7y<37>S<80><00>l<C1><6C><80>*dbunit/Extensions/Database/DB/MetaData.phpL 7y<37>SL <00>!<21>!<21>1dbunit/Extensions/Database/DB/FilteredDataSet.phpM 7y<37>SM <14><07><>/dbunit/Extensions/Database/DB/TableMetaData.php 7y<37>S <00>K<97><19>1dbunit/Extensions/Database/DataSet/CsvDataSet.php<68>7y<37>S<80>/<2F>0(<28>6dbunit/Extensions/Database/DataSet/Persistors/Yaml.php<68>7y<37>S<80>n<18><>:dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php<68>7y<37>S<80>f<>]-<2D>9dbunit/Extensions/Database/DataSet/Persistors/FlatXml.phpj7y<37>Sj_<><5F><A9><B5>9dbunit/Extensions/Database/DataSet/Persistors/Factory.php<68>7y<37>S<80>[<12>̶:dbunit/Extensions/Database/DataSet/Persistors/Abstract.php<68>7y<37>S<80><1D>7<C2><37>5dbunit/Extensions/Database/DataSet/Persistors/Xml.php7y<37>Sw:<3A><><97>3dbunit/Extensions/Database/DataSet/DefaultTable.php<68>7y<37>S<80>2<><32>F<CF>5dbunit/Extensions/Database/DataSet/ITableIterator.php
7y<37>S
"<22>h<E9><68>-dbunit/Extensions/Database/DataSet/ITable.php 7y<37>S 9<11><10><dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php<68>7y<37>S<80><00><><E1><F5><E1>7dbunit/Extensions/Database/DataSet/ReplacementTable.php37y<37>S3`<60>,dbunit/Extensions/Database/DataSet/ISpec.php<68>
7y<37>S<80>
<04>fC<66>6dbunit/Extensions/Database/DataSet/AbstractDataSet.php<68>7y<37>S<80><00>[9<><39>;dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php<68> 7y<37>S<80> <00><> <0C><>1dbunit/Extensions/Database/DataSet/XmlDataSet.php<68>7y<37>S<80>L2dbunit/Extensions/Database/DataSet/IYamlParser.php<68> 7y<37>S<80> Cp<43><01>7dbunit/Extensions/Database/DataSet/CompositeDataSet.php<68>7y<37>S<80>N<4E>=<3D>2dbunit/Extensions/Database/DataSet/TableFilter.php<68>7y<37>S<80><00>*E<>3dbunit/Extensions/Database/DataSet/IPersistable.php<68>
7y<37>S<80>
<1B><><97>?dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php<68>7y<37>S<80>B! <20>5dbunit/Extensions/Database/DataSet/DefaultDataSet.php<68> 7y<37>S<80> <00>kr<6B><72>0dbunit/Extensions/Database/DataSet/Specs/Csv.phpa7y<37>Sa<00>=Kj<4B>1dbunit/Extensions/Database/DataSet/Specs/Yaml.php<68> 7y<37>S<80> SD\<>4dbunit/Extensions/Database/DataSet/Specs/FlatXml.php<68> 7y<37>S<80> .<2E><><13>4dbunit/Extensions/Database/DataSet/Specs/Factory.php<68> 7y<37>S<80> <02>>3<>4dbunit/Extensions/Database/DataSet/Specs/DbQuery.php<68>7y<37>S<80>5v<15><>0dbunit/Extensions/Database/DataSet/Specs/Xml.php<68> 7y<37>S<80> <00>)5T<35>5dbunit/Extensions/Database/DataSet/Specs/IFactory.phpQ
7y<37>SQ
f<><05><>4dbunit/Extensions/Database/DataSet/Specs/DbTable.php<68>7y<37>S<80><00><>J<0F>3dbunit/Extensions/Database/DataSet/QueryDataSet.phpo7y<37>So1<>Г<CB>8dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php
7y<37>S
n| <06>2dbunit/Extensions/Database/DataSet/YamlDataSet.php7y<37>S<17>L<B8><4C>5dbunit/Extensions/Database/DataSet/FlatXmlDataSet.phpV7y<37>SV<00>N@Զ:dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php*7y<37>S*
<83><E6>۶/dbunit/Extensions/Database/DataSet/IDataSet.php<68> 7y<37>S<80> -<2D>oB<6F>4dbunit/Extensions/Database/DataSet/DataSetFilter.php7y<37>S<5F>6dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php/7y<37>S/<00>8o<38>1dbunit/Extensions/Database/DataSet/QueryTable.php7y<37>S<00>!<19><>9dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.phpt7y<37>St3<07>!<21>5dbunit/Extensions/Database/DataSet/ITableMetaData.php8 7y<37>S8 <00>qjY<6A>9dbunit/Extensions/Database/DataSet/ReplacementDataSet.php`7y<37>S`ք<><D684>4dbunit/Extensions/Database/DataSet/AbstractTable.phpW!7y<37>SW!<00>|<7C><>;dbunit/Extensions/Database/DataSet/DefaultTableIterator.php<68>7y<37>S<80><00><><EA>r<93>-dbunit/Extensions/Database/AbstractTester.php$7y<37>S$<00>Q<E9><51><85>-dbunit/Extensions/Database/UI/ModeFactory.php)7y<37>S)X<><58><9B><AA>.dbunit/Extensions/Database/UI/Mediums/Text.php<68>7y<37>S<80>2Z<32>v<96>)dbunit/Extensions/Database/UI/Command.phpR 7y<37>SR <00><><a<>'dbunit/Extensions/Database/UI/IMode.php<68>
7y<37>S<80>
<17><><D6><FB>5dbunit/Extensions/Database/UI/Modes/ExportDataSet.php<68>7y<37>S<80><00>>!B<>?dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php7y<37>S'<27>)dbunit/Extensions/Database/UI/IMedium.phpY 7y<37>SY <00><>1<FD><31>.dbunit/Extensions/Database/UI/IModeFactory.php<68>
7y<37>S<80>
<00>F<83>$<24>6dbunit/Extensions/Database/UI/InvalidModeException.php<68> 7y<37>S<80> <00><><96> <0B>0dbunit/Extensions/Database/UI/IMediumPrinter.php<68>
7y<37>S<80>
<00><><A8><05>)dbunit/Extensions/Database/UI/Context.php 7y<37>S <00>c<E0>$<24>4dbunit/Extensions/Database/IDatabaseListConsumer.phpA
7y<37>SA
S<><53>Ӷ'dbunit/Extensions/Database/TestCase.php(%7y<37>S(%s<><73><A6><C8>/dbunit/Extensions/Database/Operation/Delete.php7y<37>S<00>2_Ͷ0dbunit/Extensions/Database/Operation/Replace.phpf7y<37>Sf8w@<40>2dbunit/Extensions/Database/Operation/Composite.php<68>7y<37>S<80>9$ <09><>;dbunit/Extensions/Database/Operation/IDatabaseOperation.php<68> 7y<37>S<80> <00><><C8>f<C7>0dbunit/Extensions/Database/Operation/Factory.php<68>7y<37>S<80><00>t1dbunit/Extensions/Database/Operation/Truncate.php<68> 7y<37>S<80> <00><>p<19>/dbunit/Extensions/Database/Operation/Insert.php<68>7y<37>S<80><00><><FF><BB><BC>-dbunit/Extensions/Database/Operation/Null.php<68>
7y<37>S<80>
<1C>I9<49>/dbunit/Extensions/Database/Operation/Update.php<68>7y<37>S<80><00><><81><FB><84>2dbunit/Extensions/Database/Operation/Exception.php<68>7y<37>S<80><00><1B><><FB>2dbunit/Extensions/Database/Operation/DeleteAll.php<68> 7y<37>S<80> l<><6C>+<2B>1dbunit/Extensions/Database/Operation/RowBased.php*7y<37>S*+6dbunit/Extensions/Database/Constraint/TableIsEqual.phpd7y<37>SdNj<4E>Ƕ7dbunit/Extensions/Database/Constraint/TableRowCount.phpc 7y<37>Sc <>+/<2F>8dbunit/Extensions/Database/Constraint/DataSetIsEqual.phpr7y<37>Sr<00>T(<28>(dbunit/Extensions/Database/Exception.php
7y<37>S
x
<A6>!<21>php-invoker/Invoker.php&7y<37>S&<00>-顶(php-invoker/Invoker/TimeoutException.php<68> 7y<37>S<80> <1C>n<95><6E>php-timer/Timer.php67y<37>S6#X6<58><36>0php-token-stream/Token/Stream/CachingFactory.php<68> 7y<37>S<80> Ӓն!php-token-stream/Token/Stream.phpuD7y<37>SuDr<>php-token-stream/Token.php\7y<37>S\C2<43>}<7D>php-text-template/Template.php<68>7y<37>S<80><00>;$<13><?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of a risky test.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Framework_RiskyTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_RiskyTest
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
* SebastianBergmann\Comparator\ComparisonFailure which is used to
* generate diff output of the failed expectations.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 SebastianBergmann\Comparator\ComparisonFailure
*/
protected $comparisonFailure;
public function __construct($message, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null, Exception $previous = null)
{
$this->comparisonFailure = $comparisonFailure;
parent::__construct($message, 0, $previous);
}
/**
* @return SebastianBergmann\Comparator\ComparisonFailure
*/
public function getComparisonFailure()
{
return $this->comparisonFailure;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of a test that is skipped because of an invalid @covers annotation.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Framework_InvalidCoversTargetError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 . $e->getComparisonFailure()->getDiff();
}
if (!empty($buffer)) {
$buffer = trim($buffer) . "\n";
}
} elseif ($e instanceof PHPUnit_Framework_Error) {
$buffer = $e->getMessage() . "\n";
} else {
$buffer = get_class($e) . ': ' . $e->getMessage() . "\n";
}
return $buffer;
}
/**
* Gets the failed test.
*
* @return PHPUnit_Framework_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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
use SebastianBergmann\Exporter\Exporter;
/**
* 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-2014 Sebastian 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
{
protected $exporter;
public function __construct()
{
$this->exporter = new Exporter;
}
/**
* 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 SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure
* @throws PHPUnit_Framework_ExpectationFailedException
*/
protected function fail($other, $description, SebastianBergmann\Comparator\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 $this->exporter->export($other) . ' ' . $this->toString();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Framework_InvalidCoversTargetException extends PHPUnit_Framework_CodeCoverageException
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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);
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 3.0.0
*/
function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
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 Traversable
* 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.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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 3.0.0
*/
function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
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 Traversable
* 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.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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 2.1.0
*/
function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
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 Traversable.
*
* @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.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertEquals',
func_get_args()
);
}
/**
* Asserts that a condition is not true.
*
* @param boolean $condition
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
function assertNotTrue($condition, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotTrue',
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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 2.1.0
*/
function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
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 Traversable.
*
* @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.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 condition is not false.
*
* @param boolean $condition
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
function assertNotFalse($condition, $message = '')
{
return call_user_func_array(
'PHPUnit_Framework_Assert::assertNotFalse',
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 `Traversable` objects)
* is not the same.
*
* @param array|Countable|Traversable $expected
* @param array|Countable|Traversable $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 `Traversable` objects)
* is the same.
*
* @param array|Countable|Traversable $expected
* @param array|Countable|Traversable $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
* corresponding value.
* - `tag` : the node type must match the corresponding value.
* - `attributes` : a hash. The node's attributes must match the
* corresponding values in the hash.
* - `content` : The text content must match the given value.
* - `parent` : a hash. The node's parent must match the
* corresponding 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.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
* @param boolean $checkForNonObjectIdentity
* @return PHPUnit_Framework_Constraint_TraversableContains
* @since Method available since Release 3.0.0
*/
function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
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.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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 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 $risky = 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 $beStrictAboutTestsThatDoNotTestAnything = false;
/**
* @var boolean
*/
protected $beStrictAboutOutputDuringTests = false;
/**
* @var boolean
*/
protected $beStrictAboutTestSize = false;
/**
* @var boolean
*/
protected $stopOnRisky = 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_RiskyTest) {
$this->risky[] = new PHPUnit_Framework_TestFailure(
$test, $e
);
$notifyMethod = 'addRiskyTest';
if ($this->stopOnRisky) {
$this->stop();
}
} elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
$this->notImplemented[] = new PHPUnit_Framework_TestFailure(
$test, $e
);
$notifyMethod = 'addIncompleteTest';
if ($this->stopOnIncomplete) {
$this->stop();
}
} elseif ($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_RiskyTest) {
$this->risky[] = new PHPUnit_Framework_TestFailure(
$test, $e
);
$notifyMethod = 'addRiskyTest';
if ($this->stopOnRisky) {
$this->stop();
}
} elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
$this->notImplemented[] = new PHPUnit_Framework_TestFailure(
$test, $e
);
$notifyMethod = 'addIncompleteTest';
if ($this->stopOnIncomplete) {
$this->stop();
}
} elseif ($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 risky test occurred.
*
* @return boolean
* @since Method available since Release 4.0.0
*/
public function allHarmless()
{
return $this->riskyCount() == 0;
}
/**
* Gets the number of risky tests.
*
* @return integer
* @since Method available since Release 4.0.0
*/
public function riskyCount()
{
return count($this->risky);
}
/**
* Returns true if no incomplete test occurred.
*
* @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 risky tests.
*
* @return array
* @since Method available since Release 4.0.0
*/
public function risky()
{
return $this->risky;
}
/**
* 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;
}
/**
* 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;
$risky = 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();
}
}
$collectCodeCoverage = $this->codeCoverage !== null &&
!$test instanceof PHPUnit_Extensions_SeleniumTestCase &&
!$test instanceof PHPUnit_Framework_Warning;
if ($collectCodeCoverage) {
// We need to blacklist test source files when no whitelist is used.
if (!$this->codeCoverage->filter()->hasWhitelist()) {
$classes = $this->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->beStrictAboutTestSize &&
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_RiskyTestError) {
$risky = true;
} elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) {
$incomplete = true;
} elseif ($e instanceof PHPUnit_Framework_SkippedTestError) {
$skipped = true;
}
} catch (Exception $e) {
$error = true;
}
$time = PHP_Timer::stop();
$test->addToAssertionCount(PHPUnit_Framework_Assert::getCount());
if ($this->beStrictAboutTestsThatDoNotTestAnything &&
$test->getNumAssertions() == 0) {
$risky = true;
}
if ($collectCodeCoverage) {
$append = !$risky && !$incomplete && !$skipped;
$linesToBeCovered = array();
$linesToBeUsed = array();
if ($append && $test instanceof PHPUnit_Framework_TestCase) {
$linesToBeCovered = PHPUnit_Util_Test::getLinesToBeCovered(
get_class($test), $test->getName(false)
);
$linesToBeUsed = PHPUnit_Util_Test::getLinesToBeUsed(
get_class($test), $test->getName(false)
);
}
try {
$this->codeCoverage->stop(
$append, $linesToBeCovered, $linesToBeUsed
);
} catch (PHP_CodeCoverage_Exception_UnintentionallyCoveredCode $cce) {
$this->addFailure(
$test,
new PHPUnit_Framework_UnintentionallyCoveredCodeError(
'This test executed code that is not listed as code to be covered or used:' .
PHP_EOL . $cce->getMessage()
),
$time
);
} catch (PHPUnit_Framework_InvalidCoversTargetException $cce) {
$this->addFailure(
$test,
new PHPUnit_Framework_InvalidCoversTargetError(
$cce->getMessage()
),
$time
);
} 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);
} elseif ($failure === true) {
$this->addFailure($test, $e, $time);
} elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
$test->getNumAssertions() == 0) {
$this->addFailure(
$test,
new PHPUnit_Framework_RiskyTestError(
'This test did not perform any assertions'
),
$time
);
} elseif ($this->beStrictAboutOutputDuringTests && $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;
}
/**
* Sets the PHP_CodeCoverage object.
*
* @param PHP_CodeCoverage $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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->convertErrorsToExceptions = $flag;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->stopOnError = $flag;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->stopOnFailure = $flag;
}
/**
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 4.0.0
*/
public function beStrictAboutTestsThatDoNotTestAnything($flag)
{
if (!is_bool($flag)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->beStrictAboutTestsThatDoNotTestAnything = $flag;
}
/**
* @return boolean
* @since Method available since Release 4.0.0
*/
public function isStrictAboutTestsThatDoNotTestAnything()
{
return $this->beStrictAboutTestsThatDoNotTestAnything;
}
/**
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 4.0.0
*/
public function beStrictAboutOutputDuringTests($flag)
{
if (!is_bool($flag)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->beStrictAboutOutputDuringTests = $flag;
}
/**
* @return boolean
* @since Method available since Release 4.0.0
*/
public function isStrictAboutOutputDuringTests()
{
return $this->beStrictAboutOutputDuringTests;
}
/**
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 4.0.0
*/
public function beStrictAboutTestSize($flag)
{
if (!is_bool($flag)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->beStrictAboutTestSize = $flag;
}
/**
* @return boolean
* @since Method available since Release 4.0.0
*/
public function isStrictAboutTestSize()
{
return $this->beStrictAboutTestSize;
}
/**
* Enables or disables the stopping for risky tests.
*
* @param boolean $flag
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 4.0.0
*/
public function stopOnRisky($flag)
{
if (!is_bool($flag)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->stopOnRisky = $flag;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->stopOnIncomplete = $flag;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
$this->stopOnSkipped = $flag;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
$this->timeoutForSmallTests = $timeout;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
$this->timeoutForMediumTests = $timeout;
}
/**
* 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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
}
$this->timeoutForLargeTests = $timeout;
}
/**
* Returns the class hierarchy for a given class.
*
* @param string $className
* @param boolean $asReflectionObjects
* @return array
*/
protected 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;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Framework_CodeCoverageException extends PHPUnit_Framework_Exception
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 2.1.0
*/
public static function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
if (is_array($haystack) ||
is_object($haystack) && $haystack instanceof Traversable) {
$constraint = new PHPUnit_Framework_Constraint_TraversableContains(
$needle, $checkForObjectIdentity, $checkForNonObjectIdentity
);
} elseif (is_string($haystack)) {
$constraint = new PHPUnit_Framework_Constraint_StringContains(
$needle, $ignoreCase
);
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
2, 'array, traversable 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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 3.0.0
*/
public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
self::assertContains(
$needle,
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message,
$ignoreCase,
$checkForObjectIdentity,
$checkForNonObjectIdentity
);
}
/**
* Asserts that a haystack does not contain a needle.
*
* @param mixed $needle
* @param mixed $haystack
* @param string $message
* @param boolean $ignoreCase
* @param boolean $checkForObjectIdentity
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 2.1.0
*/
public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
if (is_array($haystack) ||
is_object($haystack) && $haystack instanceof Traversable) {
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_TraversableContains(
$needle, $checkForObjectIdentity, $checkForNonObjectIdentity
)
);
} elseif (is_string($haystack)) {
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_StringContains(
$needle, $ignoreCase
)
);
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
2, 'array, traversable 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
* @param boolean $checkForNonObjectIdentity
* @since Method available since Release 3.0.0
*/
public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
self::assertNotContains(
$needle,
self::readAttribute($haystackClassOrObject, $haystackAttributeName),
$message,
$ignoreCase,
$checkForObjectIdentity,
$checkForNonObjectIdentity
);
}
/**
* 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 traversable'
);
}
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 traversable'
);
}
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 traversable'
);
}
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 Traversable.
*
* @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 Traversable &&
!is_array($haystack)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
}
self::assertThat(
$haystack,
new PHPUnit_Framework_Constraint_Count($expectedCount),
$message
);
}
/**
* Asserts the number of elements of an array, Countable or Traversable
* 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 Traversable.
*
* @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 Traversable &&
!is_array($haystack)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
}
$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 Traversable
* 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.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.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.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.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 not true.
*
* @param boolean $condition
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
public static function assertNotTrue($condition, $message = '')
{
self::assertThat($condition, self::logicalNot(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 condition is not false.
*
* @param boolean $condition
* @param string $message
* @throws PHPUnit_Framework_AssertionFailedError
*/
public static function assertNotFalse($condition, $message = '')
{
self::assertThat($condition, self::logicalNot(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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
}
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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
}
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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
}
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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
}
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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
}
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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
}
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) && (class_exists($expected) || interface_exists($expected)))) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
}
$constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
$expected
);
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) && (class_exists($expected) || interface_exists($expected)))) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
}
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_IsInstanceOf($expected)
);
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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$constraint = new PHPUnit_Framework_Constraint_IsType(
$expected
);
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)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
$constraint = new PHPUnit_Framework_Constraint_Not(
new PHPUnit_Framework_Constraint_IsType($expected)
);
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 `Traversable` objects)
* is the same.
*
* @param array|Countable|Traversable $expected
* @param array|Countable|Traversable $actual
* @param string $message
*/
public static function assertSameSize($expected, $actual, $message = '')
{
if (!$expected instanceof Countable &&
!$expected instanceof Traversable &&
!is_array($expected)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
}
if (!$actual instanceof Countable &&
!$actual instanceof Traversable &&
!is_array($actual)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
}
self::assertThat(
$actual,
new PHPUnit_Framework_Constraint_SameSize($expected),
$message
);
}
/**
* Assert that the size of two arrays (or `Countable` or `Traversable` objects)
* is not the same.
*
* @param array|Countable|Traversable $expected
* @param array|Countable|Traversable $actual
* @param string $message
*/
public static function assertNotSameSize($expected, $actual, $message = '')
{
if (!$expected instanceof Countable &&
!$expected instanceof Traversable &&
!is_array($expected)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
}
if (!$actual instanceof Countable &&
!$actual instanceof Traversable &&
!is_array($actual)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
}
$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
* corresponding value.
* - `tag` : the node type must match the corresponding value.
* - `attributes` : a hash. The node's attributes must match the
* corresponding values in the hash.
* - `content` : The text content must match the given value.
* - `parent` : a hash. The node's parent must match the
* corresponding 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 $actualJson
* @param string $message
* @since Method available since Release 3.7.20
*/
public static function assertJson($actualJson, $message = '')
{
if (!is_string($actualJson)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
self::assertThat($actualJson, 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
* @param boolean $checkForNonObjectIdentity
* @return PHPUnit_Framework_Constraint_TraversableContains
* @since Method available since Release 3.0.0
*/
public static function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
return new PHPUnit_Framework_Constraint_TraversableContains($value, $checkForObjectIdentity, $checkForNonObjectIdentity);
}
/**
* 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.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.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);
}
/**
* Returns a PHPUnit_Framework_Constraint_Count matcher object.
*
* @param int $count
* @return PHPUnit_Framework_Constraint_Count
*/
public static function countOf($count)
{
return new PHPUnit_Framework_Constraint_Count($count);
}
/**
* 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 (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
}
if (is_string($classOrObject)) {
if (!class_exists($classOrObject)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'class name'
);
}
return self::getStaticAttribute(
$classOrObject,
$attributeName
);
} elseif (is_object($classOrObject)) {
return self::getObjectAttribute(
$classOrObject,
$attributeName
);
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'class name or object'
);
}
}
/**
* 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 4.0.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');
}
if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
}
$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 4.0.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');
}
if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
}
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
)
);
}
/**
* 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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;
/**
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* A marker interface for marking any exception/error as result of an unit
* test as risky.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
interface PHPUnit_Framework_RiskyTest
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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;
/**
* 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,
'OS' => 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 array
*/
private $mockObjectGenerator = null;
/**
* @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 boolean
* @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
* @throws PHPUnit_Framework_Exception
*/
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) {
}
}
/**
* @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['OS'])) {
$this->required['OS'] = $requirements['OS'];
}
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']
);
}
if ($this->required['OS'] &&
!preg_match($this->required['OS'], PHP_OS)) {
$missingRequirements[] = sprintf(
'Operating system matching %s is required.',
$this->required['OS']
);
}
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();
}
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(
__DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl'
);
if ($this->preserveGlobalState) {
$constants = PHPUnit_Util_GlobalState::getConstantsAsString();
$globals = PHPUnit_Util_GlobalState::getGlobalsAsString();
$includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString();
$iniSettings = PHPUnit_Util_GlobalState::getIniSettingsAsString();
} else {
$constants = '';
$globals = '';
$includedFiles = '';
$iniSettings = '';
}
$coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false';
$isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false';
$isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false';
$isStrictAboutTestSize = $result->isStrictAboutTestSize() ? 'true' : 'false';
if (defined('PHPUNIT_COMPOSER_INSTALL')) {
$composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true);
} else {
$composerAutoload = '\'\'';
}
if (defined('__PHPUNIT_PHAR__')) {
$phar = var_export(__PHPUNIT_PHAR__, true);
} else {
$phar = '\'\'';
}
$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,
'phar' => $phar,
'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,
'iniSettings' => $iniSettings,
'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything,
'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests,
'isStrictAboutTestSize' => $isStrictAboutTestSize
)
);
$this->prepareTemplate($template);
$php = PHPUnit_Util_PHP::factory();
$php->runTestJob($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();
$hookMethods = PHPUnit_Util_Test::getHookMethods(get_class($this));
try {
$this->checkRequirements();
if ($this->inIsolation) {
foreach ($hookMethods['beforeClass'] as $method) {
$this->$method();
}
}
$this->setExpectedExceptionFromAnnotation();
foreach ($hookMethods['before'] as $method) {
$this->$method();
}
$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 {
foreach ($hookMethods['after'] as $method) {
$this->$method();
}
if ($this->inIsolation) {
foreach ($hookMethods['afterClass'] as $method) {
$this->$method();
}
}
} 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;
} elseif ($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 Exception|PHPUnit_Framework_Exception
* @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();
}
}
/**
* 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;
}
/**
* Returns true if the tests has dependencies
*
* @return boolean
* @since Method available since Release 4.0.0
*/
public function hasDependencies()
{
return count($this->dependencies) > 0;
}
/**
* 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 Name of the class to mock.
* @param array|null $methods When provided, only methods whose names are in the array
* are replaced with a configurable test double. The behavior
* of the other methods is not changed.
* Providing null means that no methods will be replaced.
* @param array $arguments Parameters to pass to the original class' constructor.
* @param string $mockClassName Class name for the generated test double class.
* @param boolean $callOriginalConstructor Can be used to disable the call to the original class' constructor.
* @param boolean $callOriginalClone Can be used to disable the call to the original class' clone constructor.
* @param boolean $callAutoload Can be used to disable __autoload() during the generation of the test double class.
* @param boolean $cloneArguments
* @param boolean $callOriginalMethods
* @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, $callOriginalMethods = false)
{
$mockObject = $this->getMockObjectGenerator()->getMock(
$originalClassName,
$methods,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments,
$callOriginalMethods
);
$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 = $this->getMockObjectGenerator()->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
* @param array $options An array of options passed to SOAPClient::_construct
* @return PHPUnit_Framework_MockObject_MockObject
* @since Method available since Release 3.4.0
*/
protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = true, array $options = array())
{
if ($originalClassName === '') {
$originalClassName = str_replace(
'.wsdl', '', basename($wsdlFile)
);
}
if (!class_exists($originalClassName)) {
eval(
$this->getMockObjectGenerator()->generateClassFromWsdl(
$wsdlFile, $originalClassName, $methods, $options
)
);
}
return $this->getMock(
$originalClassName,
$methods,
array('', $options),
$mockClassName,
$callOriginalConstructor,
false,
false
);
}
/**
* Returns a mock object for the specified trait with all abstract methods
* of the trait mocked. Concrete methods to mock can be specified with the
* `$mockedMethods` parameter.
*
* @param string $traitName
* @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 4.0.0
* @throws PHPUnit_Framework_Exception
*/
public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
{
$mockObject = $this->getMockObjectGenerator()->getMockForTrait(
$traitName,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$mockedMethods,
$cloneArguments
);
$this->mockObjects[] = $mockObject;
return $mockObject;
}
/**
* 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 $this->getMockObjectGenerator()->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();
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
}, E_WARNING);
foreach ($data as $key => $_data) {
try {
// Detect array-recursions by using count
// http://php.net/manual/en/function.count.php
$iRecursiveCheck = count($_data, COUNT_RECURSIVE);
if (is_array($_data)) {
$result[] = 'array(' . $this->dataToString($_data) . ')';
} elseif (is_object($_data)) {
$object = new ReflectionObject($_data);
if ($object->hasMethod('__toString')) {
$result[] = (string) $_data;
} else {
$result[] = get_class($_data);
}
} elseif (is_resource($_data)) {
$result[] = '<resource>';
} else {
$result[] = var_export($_data, true);
}
} catch (ErrorException $e) {
$result[] = '*RECURSION*';
}
}
restore_error_handler();
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
* @throws Exception
*/
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)
{
}
/**
* Get the mock object generator, creating it if it doesn't exist.
*
* @return PHPUnit_Framework_MockObject_Generator
*/
protected function getMockObjectGenerator()
{
if (null === $this->mockObjectGenerator) {
$this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator;
}
return $this->mockObjectGenerator;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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;
/**
* @var boolean
*/
protected $runTestInSeparateProcess = false;
/**
* 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;
/**
* @var PHPUnit_Runner_Filter_Factory
*/
private $iteratorFilter = null;
/**
* 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;
} elseif (is_string($theClass) &&
$theClass !== '' &&
class_exists($theClass, false)) {
$argumentsValid = true;
if ($name == '') {
$name = $theClass;
}
$theClass = new ReflectionClass($theClass);
} elseif (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);
} elseif ($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;
}
$classes = get_declared_classes();
$filename = PHPUnit_Util_Fileloader::checkAndLoad($filename);
$newClasses = array_values(array_diff(get_declared_classes(), $classes));
$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;
}
}
}
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));
}
} elseif ($class->implementsInterface('PHPUnit_Framework_Test')) {
$this->addTestSuite($class);
}
}
}
$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()
{
$numTests = 0;
foreach ($this as $test) {
$numTests += count($test);
}
return $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);
}
public function getGroupDetails()
{
return $this->groups;
}
/**
* Set tests groups of the test case
*
* @param array $groups
* @since Method available since Release 4.0.0
*/
public function setGroupDetails(array $groups)
{
$this->groups = $groups;
}
/**
* Runs the tests and collects their 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();
}
if (count($this) == 0) {
return $result;
}
$hookMethods = PHPUnit_Util_Test::getHookMethods($this->name);
$result->startTestSuite($this);
try {
$this->setUp();
foreach ($hookMethods['beforeClass'] as $beforeClassMethod) {
if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $beforeClassMethod)) {
call_user_func(array($this->name, $beforeClassMethod));
}
}
} 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;
}
foreach ($this as $test) {
if ($result->shouldStop()) {
break;
}
if ($test instanceof PHPUnit_Framework_TestCase ||
$test instanceof PHPUnit_Framework_TestSuite) {
$test->setBackupGlobals($this->backupGlobals);
$test->setBackupStaticAttributes($this->backupStaticAttributes);
$test->setRunTestInSeparateProcess($this->runTestInSeparateProcess);
}
$test->run($result);
}
foreach ($hookMethods['afterClass'] as $afterClassMethod) {
if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $afterClassMethod)) {
call_user_func(array($this->name, $afterClassMethod));
}
}
$this->tearDown();
$result->endTestSuite($this);
return $result;
}
/**
* @param boolean $runTestInSeparateProcess
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.7.0
*/
public function setRunTestInSeparateProcess($runTestInSeparateProcess)
{
if (is_bool($runTestInSeparateProcess)) {
$this->runTestInSeparateProcess = $runTestInSeparateProcess;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
}
}
/**
* Runs a test.
*
* @deprecated
* @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;
}
/**
* Set tests of the test suite
*
* @param array $tests
* @since Method available since Release 4.0.0
*/
public function setTests(array $tests)
{
$this->tests = $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)
{
if (!$this->isTestMethod($method))
return;
$name = $method->getName();
if (!$method->isPublic()) {
$this->addTest(
self::warning(
sprintf(
'Test method "%s" in test class "%s" is not public.',
$name,
$class->getName()
)
)
);
return;
}
$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)
);
}
/**
* @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()
$doc_comment = $method->getDocComment();
return strpos($doc_comment, '@test') !== false ||
strpos($doc_comment, '@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()
{
$iterator = new PHPUnit_Util_TestSuiteIterator($this);
if ($this->iteratorFilter !== null) {
$iterator = $this->iteratorFilter->factory($iterator, $this);
}
return $iterator;
}
public function injectFilter(PHPUnit_Runner_Filter_Factory $filter)
{
$this->iteratorFilter = $filter;
foreach ($this as $test) {
if ($test instanceof PHPUnit_Framework_TestSuite) {
$test->injectFilter($filter);
}
}
}
/**
* 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 $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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
if ($other instanceof Countable) {
return count($other) === 0;
}
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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 Traversable) {
if ($other instanceof IteratorAggregate) {
$iterator = $other->getIterator();
} else {
$iterator = $other;
}
$key = $iterator->key();
$count = iterator_count($iterator);
// manually rewind $iterator to previous key, since iterator_count
// moves pointer
if ($key !== null) {
$iterator->rewind();
while ($key !== $iterator->key()) {
$iterator->next();
}
}
return $count;
}
}
/**
* 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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.0;
/**
* @var integer
*/
protected $maxDepth = 10;
/**
* @var boolean
*/
protected $canonicalize = false;
/**
* @var boolean
*/
protected $ignoreCase = false;
/**
* @var SebastianBergmann\Comparator\ComparisonFailure
*/
protected $lastFailure;
/**
* @param mixed $value
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
* @throws PHPUnit_Framework_Exception
*/
public function __construct($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
{
parent::__construct();
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 = new SebastianBergmann\Comparator\Factory;
try {
$comparator = $comparatorFactory->getComparatorFor(
$other, $this->value
);
$comparator->assertEquals(
$this->value,
$other,
$this->delta,
$this->canonicalize,
$this->ignoreCase
);
} catch (SebastianBergmann\Comparator\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',
$this->exporter->export($this->value),
$delta
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 $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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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 evaluation 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-2014 Sebastian 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)
{
parent::__construct();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
use SebastianBergmann\Diff\Differ;
/**
* ...
*
* @package PHPUnit
* @subpackage Framework_Constraint
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian 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)
{
parent::__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);
$differ = new Differ("--- Expected\n+++ Actual\n");
return $differ->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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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 %s "%s"',
$this->exporter->shortenedExport($other),
$this->getType(),
$this->className
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return sprintf(
'is instance of %s "%s"',
$this->getType(),
$this->className
);
}
private function getType()
{
try {
$reflection = new ReflectionClass($this->className);
if ($reflection->isInterface()) {
return 'interface';
}
} catch (ReflectionException $e) {
}
return 'class';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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',
$this->exporter->export($other->getCode()),
$this->exporter->export($this->expectedCode)
);
}
/**
* @return string
*/
public function toString()
{
return 'exception code is ';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)',
$this->exporter->shortenedExport($other),
$error
);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'is valid JSON';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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 evaluation 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-2014 Sebastian 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)
{
parent::__construct();
$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)
{
if (is_array($other)) {
return array_key_exists($this->key, $other);
}
if ($other instanceof ArrayAccess) {
return $other->offsetExists($this->key);
}
return false;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return 'has the key ' . $this->exporter->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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 $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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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 2001-2014 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 PHPUnit_Framework_Exception
*/
public function __construct($callback)
{
if (!is_callable($callback)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'callable'
);
}
parent::__construct();
$this->callback = $callback;
}
/**
* Evaluates the constraint for parameter $value. Returns true if the
* constraint is met, false otherwise.
*
* @param mixed $other 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
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;
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) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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 ' . $this->exporter->export($this->value);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 2001-2014 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 2001-2014 Sebastian Bergmann <sebastian@phpunit.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)
{
parent::__construct();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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 ' . $this->exporter->export($this->value);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 boolean
*/
protected $checkForNonObjectIdentity;
/**
* @var mixed
*/
protected $value;
/**
* @param mixed $value
* @param boolean $checkForObjectIdentity
* @param boolean $checkForNonObjectIdentity
* @throws PHPUnit_Framework_Exception
*/
public function __construct($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
{
parent::__construct();
if (!is_bool($checkForObjectIdentity)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
}
if (!is_bool($checkForNonObjectIdentity)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
}
$this->checkForObjectIdentity = $checkForObjectIdentity;
$this->checkForNonObjectIdentity = $checkForNonObjectIdentity;
$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 (($this->checkForNonObjectIdentity &&
$element === $this->value) ||
(!$this->checkForNonObjectIdentity &&
$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 ' . $this->exporter->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(
'%s %s',
is_array($other) ? 'an array' : 'a traversable',
$this->toString()
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 2001-2014 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 2001-2014 Sebastian Bergmann <sebastian@phpunit.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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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) {
$message = '. Message was: "' . $other->getMessage() . '" at'
. "\n" . $other->getTraceAsString();
}
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
parent::__construct();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 float
*/
const EPSILON = 0.0000000001;
/**
* @var mixed
*/
protected $value;
/**
* @param mixed $value
*/
public function __construct($value)
{
parent::__construct();
$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 SebastianBergmann\Comparator\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 ' .
$this->exporter->export($this->value);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 implements PHPUnit_Exception
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Giorgio Sironi <info@giorgiosironi.com>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* An empty Listener that can be extended to implement TestListener
* with just a few lines of code.
* @see PHPUnit_Framework_TestListener for documentation on the API methods.
*
* @package PHPUnit
* @subpackage Framework
* @author Giorgio Sironi<info@giorgiosironi.com>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
abstract class PHPUnit_Framework_BaseTestListener implements PHPUnit_Framework_TestListener
{
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {}
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
public function startTest(PHPUnit_Framework_Test $test) {}
public function endTest(PHPUnit_Framework_Test $test, $time) {}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* Extension to PHPUnit_Framework_AssertionFailedError to mark the special
* case of a test test that unintentionally covers code.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Framework_UnintentionallyCoveredCodeError extends PHPUnit_Framework_RiskyTestError
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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');
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->write(
sprintf(
"ok %d - # RISKY%s\n",
$this->testNumber,
$e->getMessage() != '' ? ' ' . $e->getMessage() : ''
)
);
$this->testSuccessful = 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)
{
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
if (!defined('JSON_PRETTY_PRINT')) {
define('JSON_PRETTY_PRINT', 128);
}
/**
* A TestListener that generates JSON messages.
*
* @package PHPUnit
* @subpackage Util_Log
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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;
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->writeCase(
'error',
$time,
PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
'Risky 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 = '';
// take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput
if ($test !== null && method_exists($test, 'hasOutput') && $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);
}
});
parent::write(json_encode($buffer, JSON_PRETTY_PRINT));
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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;
}
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
$error = $this->document->createElement(
'error',
PHPUnit_Util_XML::prepareString(
"Risky 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());
} 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;
if (method_exists($test, 'hasOutput') && $test->hasOutput()) {
$systemOut = $this->document->createElement('system-out');
$systemOut->appendChild(
$this->document->createTextNode($test->getActualOutput())
);
$this->currentTestCase->appendChild($systemOut);
}
}
}
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
{
/**
* @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 test in a separate PHP process.
*
* @param string $job
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_TestResult $result
* @throws PHPUnit_Framework_Exception
*/
public function runTestJob($job, PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
{
$result->startTest($test);
$_result = $this->runJob($job);
$this->processChildResult(
$test, $result, $_result['stdout'], $_result['stderr']
);
}
/**
* Runs a single job (PHP code) using a separate PHP process.
*
* @param string $job
* @param array $settings
* @return array
* @throws PHPUnit_Framework_Exception
*/
abstract public function runJob($job, array $settings = array());
/**
* @param array $settings
* @return string
* @since Method available since Release 4.0.0
*/
protected function settingsToParameters(array $settings)
{
$buffer = '';
foreach ($settings as $setting) {
$buffer .= ' -d ' . $setting;
}
return $buffer;
}
/**
* Processes the TestResult object from an isolated process.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_TestResult $result
* @param string $stdout
* @param string $stderr
* @since Method available since Release 3.5.0
*/
private 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 {
if (strpos($stdout, "#!/usr/bin/env php\n") === 0) {
$stdout = substr($stdout, 19);
}
$childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $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();
$risky = $childResult->risky();
$skipped = $childResult->skipped();
$errors = $childResult->errors();
$failures = $childResult->failures();
if (!empty($notImplemented)) {
$result->addError(
$test, $this->getException($notImplemented[0]), $time
);
} elseif (!empty($risky)) {
$result->addError(
$test, $this->getException($risky[0]), $time
);
} elseif (!empty($skipped)) {
$result->addError(
$test, $this->getException($skipped[0]), $time
);
} elseif (!empty($errors)) {
$result->addError(
$test, $this->getException($errors[0]), $time
);
} elseif (!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
* @return Exception
* @since Method available since Release 3.6.0
* @see https://github.com/sebastianbergmann/phpunit/issues/74
*/
private 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
{
/**
* Escapes a string for the use in XML documents
* Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
* and FFFF (not even as character reference).
* See http://www.w3.org/TR/xml/#charsets
*
* @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(
'/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/',
'',
htmlspecialchars(
PHPUnit_Util_String::convertToUtf8($string), ENT_QUOTES, '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;
}
// adjacent-sibling selector
if ($element == '+') {
$previousTag = array('adjacent-sibling' => $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'];
} elseif (!empty($previousTag['child'])) {
$tag['child'] = $previousTag['child'];
} elseif (!empty($previousTag['adjacent-sibling'])) {
$tag['adjacent-sibling'] = $previousTag['adjacent-sibling'];
unset($tag['content']);
}
$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 boolean|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', 'adjacent-sibling'
);
$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',
// HTML5
'article', 'aside', 'audio', 'bdi', 'canvas', 'command',
'datalist', 'details', 'dialog', 'embed', 'figure', 'figcaption',
'footer', 'header', 'hgroup', 'keygen', 'mark', 'meter', 'nav',
'output', 'progress', 'ruby', 'rt', 'rp', 'track', 'section',
'source', 'summary', 'time', 'video', 'wbr'
);
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 adjacent-sibling
if ($options['adjacent-sibling']) {
$adjacentSiblingNodes = self::findNodes($dom, $options['adjacent-sibling'], $isHtml);
$adjacentSiblingNodes = !empty($adjacentSiblingNodes) ? $adjacentSiblingNodes : array();
foreach ($nodes as $node) {
$sibling = $node;
while ($sibling = $sibling->nextSibling) {
if ($sibling->nodeType !== XML_ELEMENT_NODE) {
continue;
}
foreach ($adjacentSiblingNodes as $adjacentSiblingNode) {
if ($sibling === $adjacentSiblingNode) {
$filtered[] = $node;
break;
}
}
break;
}
}
$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;
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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;
} elseif (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"
);
}
}
} elseif ($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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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_Default
{
/**
* @var string
*/
private $tempFile;
/**
* @param resource $pipe
* @param string $job
* @throws PHPUnit_Framework_Exception
* @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 file'
);
}
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
use SebastianBergmann\Environment\Runtime;
/**
* Default utility for PHP sub-processes.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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
{
/**
* Runs a single job (PHP code) using a separate PHP process.
*
* @param string $job
* @param array $settings
* @return array
* @throws PHPUnit_Framework_Exception
*/
public function runJob($job, array $settings = array())
{
$runtime = new Runtime;
$process = proc_open(
$runtime->getBinary() . $this->settingsToParameters($settings),
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 spawn worker process'
);
}
$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();
return array('stdout' => $stdout, 'stderr' => $stderr);
}
/**
* @param resource $pipe
* @param string $job
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.5.12
*/
protected function process($pipe, $job)
{
fwrite($pipe, $job);
}
/**
* @since Method available since Release 3.5.12
*/
protected function cleanup()
{
}
}
<?php
{iniSettings}
ini_set('display_errors', 'stderr');
set_include_path('{include_path}');
$composerAutoload = {composerAutoload};
$phar = {phar};
ob_start();
if ($composerAutoload) {
require_once $composerAutoload;
define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
} else if ($phar) {
require $phar;
}
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->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything});
$result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests});
$result->beStrictAboutTestSize({isStrictAboutTestSize});
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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'
)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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 2001-2014 Sebastian 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;
}
/**
* @return string
* @since Method available since Release 4.0.0
*/
public function getMessage()
{
return $this->message;
}
/**
* @return string
* @since Method available since Release 4.0.0
*/
public function getSource()
{
$source = '';
if (isset($this->traceInfo['file'])) {
$source .= $this->traceInfo['file'];
if (isset($this->traceInfo['line'])) {
$source .= ':' . $this->traceInfo['line'];
}
}
return $source;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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_ROOT__')) {
$prefix = __PHPUNIT_PHAR_ROOT__;
}
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)
);
}
$blacklist = new PHPUnit_Util_Blacklist;
foreach ($eTrace as $frame) {
if (isset($frame['file']) && is_file($frame['file']) &&
!$blacklist->isBlacklisted($frame['file']) &&
($prefix === false || 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
*/
private 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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 2001-2014 Sebastian 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 publicly 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'] = $method->getStartLine() . '-' . $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)
{
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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;
} elseif ((ord($string[$i]) & 0xE0) == 0xC0) {
$n = 1;
} elseif ((ord($string[$i]) & 0xF0) == 0xE0) {
$n = 2;
} elseif ((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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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'
);
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 = new PHPUnit_Util_Blacklist;
$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 && strpos($file, $prefix) === 0) {
continue;
}
if (!$blacklist->isBlacklisted($file) && is_file($file)) {
$result = 'require_once \'' . $file . "';\n" . $result;
}
}
return $result;
}
public static function getIniSettingsAsString()
{
$result = '';
$iniSettings = ini_get_all(null, false);
foreach ($iniSettings as $key => $value) {
$result .= sprintf(
'@ini_set(%s, %s);' . "\n",
self::exportVariable($key),
self::exportVariable($value)
);
}
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';
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_Token_Stream') !== 0 &&
strpos($declaredClasses[$i], 'Symfony') !== 0 &&
strpos($declaredClasses[$i], 'Text_Template') !== 0) {
$class = new ReflectionClass($declaredClasses[$i]);
if ($class->isSubclassOf('PHPUnit_Framework_Test')) {
continue;
}
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);
} elseif (!is_scalar($element) && !is_null($element)) {
$result = false;
}
if ($result === false) {
break;
}
}
return $result;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
* @return string
* @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) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
if (!function_exists('trait_exists')) {
function trait_exists($traitname, $autoload = true)
{
return false;
}
}
/**
* Test helpers.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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_OS = '/@requires\s+OS\s+(?P<value>.+?)[ \t]*\r?$/m';
const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^ ]+?))[ \t]*\r?$/m';
const SMALL = 0;
const MEDIUM = 1;
const LARGE = 2;
private static $annotationCache = array();
private static $templateMethods = array(
'setUp', 'assertPreConditions', 'assertPostConditions', 'tearDown'
);
private static $hookMethods = array();
/**
* @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()
);
} elseif ($test instanceof PHPUnit_Framework_SelfDescribing) {
return array('', $test->toString());
} else {
return array('', get_class($test));
}
}
}
/**
* @param string $className
* @param string $methodName
* @return array|bool
* @throws PHPUnit_Framework_CodeCoverageException
* @since Method available since Release 4.0.0
*/
public static function getLinesToBeCovered($className, $methodName)
{
$codeToCoverList = array();
$class = new ReflectionClass($className);
try {
$method = new ReflectionMethod($className, $methodName);
} catch (ReflectionException $e) {
return array();
}
$docComment = self::getDocCommentsOfTestClassAndTestMethodAndTemplateMethods($class, $method);
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 PHPUnit_Framework_CodeCoverageException(
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,
self::resolveElementToReflectionObjects($coveredElement)
);
}
}
return self::resolveReflectionObjectsToLines($codeToCoverList);
}
/**
* Returns lines of code specified with the @uses annotation.
*
* @param string $className
* @param string $methodName
* @return array
* @since Method available since Release 4.0.0
*/
public static function getLinesToBeUsed($className, $methodName)
{
$annotations = self::parseTestMethodAnnotations(
$className, $methodName
);
$uses = array();
if (isset($annotations['class']['uses'])) {
$uses = $annotations['class']['uses'];
}
if (isset($annotations['method']['uses'])) {
$uses = array_merge($uses, $annotations['method']['uses']);
}
$uses = array_unique($uses);
$codeToUseList = array();
foreach (array_unique($uses) as $element) {
$codeToUseList = array_merge(
$codeToUseList,
self::resolveElementToReflectionObjects($element)
);
}
return self::resolveReflectionObjectsToLines($codeToUseList);
}
/**
* 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_OS, $docComment, $matches)) {
$requires['OS'] = sprintf(
'/%s/i',
addcslashes($matches['value'][$count - 1], '/')
);
}
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]);
} elseif (isset($annotations['method']['expectedExceptionMessage'])) {
$message = self::parseAnnotationContent(
$annotations['method']['expectedExceptionMessage'][0]
);
}
if (isset($matches[3])) {
$code = $matches[3];
} elseif (isset($annotations['method']['expectedExceptionCode'])) {
$code = self::parseAnnotationContent(
$annotations['method']['expectedExceptionCode'][0]
);
}
if (is_numeric($code)) {
$code = (int) $code;
} elseif (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
*/
private 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
* @return array|Iterator when a data provider is specified and exists
* false when a data provider is specified but does not exist
* null when no data provider is specified
* @throws PHPUnit_Framework_Exception
* @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'];
} elseif (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;
} elseif (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;
} elseif (isset($groups['medium'])) {
$size = self::MEDIUM;
} elseif (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 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
* @return array
* @since Method available since Release 4.0.8
*/
public static function getHookMethods($className)
{
if (!class_exists($className, false)) {
return self::emptyHookMethodsArray();
}
if (!isset(self::$hookMethods[$className])) {
self::$hookMethods[$className] = self::emptyHookMethodsArray();
try {
$class = new ReflectionClass($className);
foreach ($class->getMethods() as $method) {
if ($method->getDeclaringClass()->getName() != $className) {
continue;
}
if (self::isBeforeClassMethod($method)) {
self::$hookMethods[$className]['beforeClass'][] = $method->getName();
}
if (self::isBeforeMethod($method)) {
self::$hookMethods[$className]['before'][] = $method->getName();
}
if (self::isAfterMethod($method)) {
self::$hookMethods[$className]['after'][] = $method->getName();
}
if (self::isAfterClassMethod($method)) {
self::$hookMethods[$className]['afterClass'][] = $method->getName();
}
}
} catch (ReflectionException $e) {
}
}
return self::$hookMethods[$className];
}
/**
* @return array
* @since Method available since Release 4.0.9
*/
private static function emptyHookMethodsArray()
{
return array(
'beforeClass' => array('setUpBeforeClass'),
'before' => array('setUp'),
'after' => array('tearDown'),
'afterClass' => array('tearDownAfterClass')
);
}
/**
* @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;
} elseif ($annotations['class'][$settingName][0] == 'disabled') {
$result = false;
}
}
if (isset($annotations['method'][$settingName])) {
if ($annotations['method'][$settingName][0] == 'enabled') {
$result = true;
} elseif ($annotations['method'][$settingName][0] == 'disabled') {
$result = false;
}
}
return $result;
}
/**
* @param string $element
* @return array
* @throws PHPUnit_Framework_InvalidCoversTargetException
* @since Method available since Release 4.0.0
*/
private static function resolveElementToReflectionObjects($element)
{
$codeToCoverList = array();
if (strpos($element, '::') !== false) {
list($className, $methodName) = explode('::', $element);
if (isset($methodName[0]) && $methodName[0] == '<') {
$classes = array($className);
foreach ($classes as $className) {
if (!class_exists($className) &&
!interface_exists($className)) {
throw new PHPUnit_Framework_InvalidCoversTargetException(
sprintf(
'Trying to @cover or @use 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';
} elseif (strpos($methodName, 'private')) {
$visibility = 'isPrivate';
} elseif (strpos($methodName, 'public')) {
$visibility = 'isPublic';
}
foreach ($methods as $method) {
if ($inverse && !$method->$visibility()) {
$codeToCoverList[] = $method;
} elseif (!$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 PHPUnit_Framework_InvalidCoversTargetException(
sprintf(
'Trying to @cover or @use not existing method "%s::%s".',
$className,
$methodName
)
);
}
$codeToCoverList[] = new ReflectionMethod(
$className, $methodName
);
}
}
}
} else {
$extended = false;
if (strpos($element, '<extended>') !== false) {
$element = str_replace(
'<extended>', '', $element
);
$extended = true;
}
$classes = array($element);
if ($extended) {
$classes = array_merge(
$classes,
class_implements($element),
class_parents($element)
);
}
foreach ($classes as $className) {
if (!class_exists($className) &&
!interface_exists($className) &&
!trait_exists($className)) {
throw new PHPUnit_Framework_InvalidCoversTargetException(
sprintf(
'Trying to @cover or @use not existing class or ' .
'interface "%s".',
$className
)
);
}
$codeToCoverList[] = new ReflectionClass($className);
}
}
return $codeToCoverList;
}
/**
* @param array $reflectors
* @return array
*/
private static function resolveReflectionObjectsToLines(array $reflectors)
{
$result = array();
foreach ($reflectors as $reflector) {
$filename = $reflector->getFileName();
if (!isset($result[$filename])) {
$result[$filename] = array();
}
$result[$filename] = array_unique(
array_merge(
$result[$filename],
range(
$reflector->getStartLine(), $reflector->getEndLine()
)
)
);
}
return $result;
}
/**
* @param ReflectionClass $class
* @param ReflectionMethod $method
* @return string
*/
private static function getDocCommentsOfTestClassAndTestMethodAndTemplateMethods(ReflectionClass $class, ReflectionMethod $method)
{
$buffer = substr($class->getDocComment(), 3, -2) . PHP_EOL .
substr($method->getDocComment(), 3, -2);
foreach (self::$templateMethods as $templateMethod) {
if ($class->hasMethod($templateMethod)) {
$_method = $class->getMethod($templateMethod);
$buffer .= PHP_EOL . substr($_method->getDocComment(), 3, -2);
}
}
return $buffer;
}
/**
* @param ReflectionMethod $method
* @return boolean
* @since Method available since Release 4.0.8
*/
private static function isBeforeClassMethod(ReflectionMethod $method)
{
return $method->isStatic() && strpos($method->getDocComment(), '@beforeClass') !== false;
}
/**
* @param ReflectionMethod $method
* @return boolean
* @since Method available since Release 4.0.8
*/
private static function isBeforeMethod(ReflectionMethod $method)
{
return preg_match('/@before\b/', $method->getDocComment());
}
/**
* @param ReflectionMethod $method
* @return boolean
* @since Method available since Release 4.0.8
*/
private static function isAfterClassMethod(ReflectionMethod $method)
{
return $method->isStatic() && strpos($method->getDocComment(), '@afterClass') !== false;
}
/**
* @param ReflectionMethod $method
* @return boolean
* @since Method available since Release 4.0.8
*/
private static function isAfterMethod(ReflectionMethod $method)
{
return preg_match('/@after\b/', $method->getDocComment());
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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"
* stderr="false"
* convertErrorsToExceptions="true"
* convertNoticesToExceptions="true"
* convertWarningsToExceptions="true"
* forceCoversAnnotation="false"
* mapTestClassNameToCoveredClassName="false"
* printerClass="PHPUnit_TextUI_ResultPrinter"
* processIsolation="false"
* stopOnError="false"
* stopOnFailure="false"
* stopOnIncomplete="false"
* stopOnRisky="false"
* stopOnSkipped="false"
* testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
* timeoutForSmallTests="1"
* timeoutForMediumTests="10"
* timeoutForLargeTests="60"
* beStrictAboutTestsThatDoNotTestAnything="false"
* beStrictAboutOutputDuringTests="false"
* beStrictAboutTestSize="false"
* checkForUnintentionallyCoveredCode="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" lowUpperBound="50" highLowerBound="90"/>
* <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"/>
* <log type="coverage-crap4j" target="/tmp/crap.xml"/>
* </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-2014 Sebastian 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
*/
final private 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('lowUpperBound')) {
$result['lowUpperBound'] = (string) $log->getAttribute('lowUpperBound');
}
if ($log->hasAttribute('highLowerBound')) {
$result['highLowerBound'] = (string) $log->getAttribute('highLowerBound');
}
} elseif ($type == 'junit') {
if ($log->hasAttribute('logIncompleteSkipped')) {
$result['logIncompleteSkipped'] = $this->getBoolean(
(string) $log->getAttribute('logIncompleteSkipped'),
false
);
}
} elseif ($type == 'coverage-text') {
if ($log->hasAttribute('showUncoveredFiles')) {
$result['coverageTextShowUncoveredFiles'] = $this->getBoolean(
(string) $log->getAttribute('showUncoveredFiles'),
false
);
}
if ($log->hasAttribute('showOnlySummary')) {
$result['coverageTextShowOnlySummary'] = $this->getBoolean(
(string) $log->getAttribute('showOnlySummary'),
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', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
// See https://github.com/sebastianbergmann/phpunit/issues/277
switch ($array) {
case 'var':
$target = &$GLOBALS;
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) {
if (false === getenv($name)) {
putenv("{$name}={$value}");
}
if (!isset($_ENV[$name])) {
$_ENV[$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
);
}
/**
* Issue #657
*/
if ($root->hasAttribute('stderr')) {
$result['stderr'] = $this->getBoolean(
(string)$root->getAttribute('stderr'), 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('stopOnRisky')) {
$result['stopOnRisky'] = $this->getBoolean(
(string) $root->getAttribute('stopOnRisky'), 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'] = $this->toAbsolutePath(
(string) $root->getAttribute('testSuiteLoaderFile')
);
}
if ($root->hasAttribute('printerClass')) {
$result['printerClass'] = (string) $root->getAttribute(
'printerClass'
);
}
if ($root->hasAttribute('printerFile')) {
$result['printerFile'] = $this->toAbsolutePath(
(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('beStrictAboutTestsThatDoNotTestAnything')) {
$result['reportUselessTests'] = $this->getBoolean(
(string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'), false
);
}
if ($root->hasAttribute('checkForUnintentionallyCoveredCode')) {
$result['strictCoverage'] = $this->getBoolean(
(string) $root->getAttribute('checkForUnintentionallyCoveredCode'), false
);
}
if ($root->hasAttribute('beStrictAboutOutputDuringTests')) {
$result['disallowTestOutput'] = $this->getBoolean(
(string) $root->getAttribute('beStrictAboutOutputDuringTests'), false
);
}
if ($root->hasAttribute('beStrictAboutTestSize')) {
$result['enforceTimeLimit'] = $this->getBoolean(
(string) $root->getAttribute('beStrictAboutTestSize'), false
);
}
if ($root->hasAttribute('strict')) {
$flag = $this->getBoolean(
(string) $root->getAttribute('strict'), false
);
$result['reportUselessTests'] = $flag;
$result['strictCoverage'] = $flag;
$result['disallowTestOutput'] = $flag;
$result['enforceTimeLimit'] = $flag;
}
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[] = $this->toAbsolutePath(
(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(
$this->toAbsolutePath($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;
} elseif (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)
{
if ($path[0] === '/') {
return $path;
}
// Matches the following on Windows:
// - \\NetworkComputer\Path
// - \\.\D:
// - \\.\c:
// - C:\Windows
// - C:\windows
// - C:/windows
// - c:/windows
if (defined('PHP_WINDOWS_VERSION_BUILD') &&
($path[0] === '\\' ||
(strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) {
return $path;
}
// Stream
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
* @return PHPUnit_Framework_Exception
*/
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 ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
$stack[1]['class'],
$stack[1]['function'],
$type
)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* Utility class for blacklisting PHPUnit's own source code files.
*
* @package PHPUnit
* @subpackage Util
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Util_Blacklist
{
/**
* @var array
*/
public static $blacklistedClassNames = array(
'File_Iterator' => 1,
'PHP_CodeCoverage' => 1,
'PHP_Invoker' => 1,
'PHP_Timer' => 1,
'PHP_Token' => 1,
'PHPUnit_Framework_TestCase' => 2,
'PHPUnit_Extensions_Database_TestCase' => 2,
'PHPUnit_Framework_MockObject_Generator' => 2,
'PHPUnit_Extensions_SeleniumTestCase' => 2,
'PHPUnit_Extensions_Story_TestCase' => 2,
'Text_Template' => 1,
'Symfony\Component\Yaml\Yaml' => 1,
'SebastianBergmann\Diff\Diff' => 1,
'SebastianBergmann\Environment\Runtime' => 1,
'SebastianBergmann\Comparator\Comparator' => 1,
'SebastianBergmann\Exporter\Exporter' => 1,
'SebastianBergmann\Version' => 1,
'Composer\Autoload\ClassLoader' => 1
);
/**
* @var array
*/
private static $directories;
/**
* @return array
* @since Method available since Release 4.1.0
*/
public function getBlacklistedDirectories()
{
$this->initialize();
return self::$directories;
}
/**
* @param string $file
* @return boolean
*/
public function isBlacklisted($file)
{
if (defined('PHPUNIT_TESTSUITE')) {
return false;
}
$this->initialize();
foreach (self::$directories as $directory) {
if (strpos($file, $directory) === 0) {
return true;
}
}
return false;
}
private function initialize()
{
if (self::$directories === null) {
self::$directories = array();
foreach (self::$blacklistedClassNames as $className => $parent) {
if (!class_exists($className)) {
continue;
}
$reflector = new ReflectionClass($className);
$directory = $reflector->getFileName();
for ($i = 0; $i < $parent; $i++) {
$directory = dirname($directory);
}
self::$directories[] = $directory;
}
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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));
}
if (substr($title, 0, 1) == '\\') {
$title = substr($title, 1);
}
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;
} elseif ($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 $suffix
*/
public function setSuffix($suffix)
{
$this->suffix = $suffix;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 $risky = 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++;
}
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
if ($test instanceof $this->testTypeOfInterest) {
$this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_RISKY;
$this->risky++;
}
}
/**
* 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 = '<span style="text-decoration:line-through;">';
$strikeClose = '</span>';
} 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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';
} elseif ($errno == E_WARNING || $errno == E_USER_WARNING) {
if (PHPUnit_Framework_Error_Warning::$enabled !== true) {
return false;
}
$exception = 'PHPUnit_Framework_Error_Warning';
} elseif ($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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-clover=' => null,
'coverage-crap4j=' => null,
'coverage-html=' => null,
'coverage-php=' => null,
'coverage-text==' => null,
'coverage-xml=' => 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-risky' => null,
'stop-on-skipped' => null,
'report-useless-tests' => null,
'strict-coverage' => null,
'disallow-test-output' => null,
'enforce-time-limit' => 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
);
/**
* @param boolean $exit
*/
public static function main($exit = true)
{
$command = new static;
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;
} elseif (!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()
* {
* // my-switch won't accept a value, it's an on/off
* $this->longOptions['my-switch'] = 'myHandler';
* // my-secondswitch will accept a value - note the equals sign
* $this->longOptions['my-secondswitch='] = 'myOtherHandler';
* }
*
* // --my-switch -> myHandler()
* protected function myHandler()
* {
* }
*
* // --my-secondswitch foo -> myOtherHandler('foo')
* protected function myOtherHandler ($value)
* {
* }
*
* // You will also need this - the static keyword in the
* // PHPUnit_TextUI_Command will mean that it'll be
* // PHPUnit_TextUI_Command that gets instantiated,
* // not MyCommand
* public static function main($exit = true)
* {
* $command = new static;
*
* return $command->run($_SERVER['argv'], $exit);
* }
*
* }
* </code>
*
* @param array $argv
*/
protected function handleArguments(array $argv)
{
if (defined('__PHPUNIT_PHAR__')) {
$this->longOptions['selfupdate'] = null;
$this->longOptions['self-update'] = null;
}
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': {
$this->arguments['coverageClover'] = $option[1];
}
break;
case '--coverage-crap4j': {
$this->arguments['coverageCrap4J'] = $option[1];
}
break;
case '--coverage-html': {
$this->arguments['coverageHtml'] = $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;
$this->arguments['coverageTextShowOnlySummary'] = false;
}
break;
case '--coverage-xml': {
$this->arguments['coverageXml'] = $option[1];
}
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['stderr'] = true;
}
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-risky': {
$this->arguments['stopOnRisky'] = 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 '--report-useless-tests': {
$this->arguments['reportUselessTests'] = true;
}
break;
case '--strict-coverage': {
$this->arguments['strictCoverage'] = true;
}
break;
case '--disallow-test-output': {
$this->arguments['disallowTestOutput'] = true;
}
break;
case '--enforce-time-limit': {
$this->arguments['enforceTimeLimit'] = true;
}
break;
case '--strict': {
$this->arguments['reportUselessTests'] = true;
$this->arguments['strictCoverage'] = true;
$this->arguments['disallowTestOutput'] = true;
$this->arguments['enforceTimeLimit'] = true;
}
break;
case '--selfupdate':
case '--self-update': {
$this->handleSelfUpdate();
}
break;
default: {
$optionName = str_replace('--', '', $option[0]);
if (isset($this->longOptions[$optionName])) {
$handler = $this->longOptions[$optionName];
} elseif (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'] = realpath($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
);
} elseif (file_exists($configurationFile . '.dist')) {
$this->arguments['configuration'] = realpath(
$configurationFile . '.dist'
);
}
} elseif (!isset($this->arguments['configuration']) &&
$this->arguments['useDefaultConfiguration']) {
if (file_exists('phpunit.xml')) {
$this->arguments['configuration'] = realpath('phpunit.xml');
} elseif (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']);
}
/**
* Issue #657
*/
if (isset($phpunit['stderr']) && $phpunit['stderr'] == true) {
$this->arguments['printer'] = new PHPUnit_TextUI_ResultPrinter(
'php://stderr',
isset($this->arguments['verbose']) ? $this->arguments['verbose'] : FALSE
);
}
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
);
}
$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)) {
$class = new ReflectionClass($printerClass);
if ($class->implementsInterface('PHPUnit_Framework_TestListener') &&
$class->isSubclassOf('PHPUnit_Util_Printer') &&
$class->isInstantiable()) {
if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
return $printerClass;
}
$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());
}
}
/**
* @since Method available since Release 4.0.0
*/
protected function handleSelfUpdate()
{
PHPUnit_TextUI_TestRunner::printVersionString();
if (!extension_loaded('openssl')) {
print "The OpenSSL extension is not loaded.\n";
exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
}
$remoteFilename = sprintf(
'https://phar.phpunit.de/phpunit%s.phar',
PHPUnit_Runner_Version::getReleaseChannel()
);
$localFilename = realpath($_SERVER['argv'][0]);
$tempFilename = basename($localFilename, '.phar') . '-temp.phar';
// Workaround for https://bugs.php.net/bug.php?id=65538
$caFile = dirname($tempFilename) . '/ca.pem';
copy(__PHPUNIT_PHAR_ROOT__ . '/ca.pem', $caFile);
print 'Updating the PHPUnit PHAR ... ';
$options = array(
'ssl' => array(
'allow_self_signed' => false,
'cafile' => $caFile,
'verify_peer' => true
)
);
if (PHP_VERSION_ID < 50600) {
$options['ssl']['CN_match'] = 'phar.phpunit.de';
$options['ssl']['SNI_server_name'] = 'phar.phpunit.de';
}
file_put_contents(
$tempFilename,
file_get_contents(
$remoteFilename,
false,
stream_context_create($options)
)
);
chmod($tempFilename, 0777 & ~umask());
try {
$phar = new Phar($tempFilename);
unset($phar);
rename($tempFilename, $localFilename);
unlink($caFile);
} catch (Exception $e) {
unlink($caFile);
unlink($tempFilename);
print " done\n\n" . $e->getMessage() . "\n";
exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
}
print " done\n";
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
}
/**
* Show the help message.
*/
protected function showHelp()
{
PHPUnit_TextUI_TestRunner::printVersionString();
print <<<EOT
Usage: phpunit [options] UnitTest [UnitTest.php]
phpunit [options] <directory>
Code Coverage Options:
--coverage-clover <file> Generate code coverage report in Clover XML format.
--coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
--coverage-html <dir> Generate code coverage report in HTML format.
--coverage-php <file> Export PHP_CodeCoverage object to file.
--coverage-text=<file> Generate code coverage report in text format.
Default: Standard output.
--coverage-xml <dir> Generate code coverage report in PHPUnit XML format.
Logging Options:
--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.
--testdox-html <file> Write agile documentation in HTML format to file.
--testdox-text <file> Write agile documentation in Text format to file.
Test Selection Options:
--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
Test Execution Options:
--report-useless-tests Be strict about tests that do not test anything.
--strict-coverage Be strict about unintentionally covered code.
--disallow-test-output Be strict about output during tests.
--enforce-time-limit Enforce time limit based on test size.
--strict Run tests in strict mode (enables all of the above).
--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.
--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-risky Stop execution upon first risky test.
--stop-on-skipped Stop execution upon first skipped test.
--stop-on-incomplete Stop execution upon first incomplete test.
-v|--verbose Output more verbose information.
--debug Display debugging information during test execution.
--loader <loader> TestSuiteLoader 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.
--printer <printer> TestSuiteListener implementation to use.
Configuration Options:
--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.
Miscellaneous Options:
-h|--help Prints this usage information.
--version Prints the version and exits.
EOT;
if (defined('__PHPUNIT_PHAR__')) {
print "\n --self-update Update PHPUnit to the latest version.\n";
}
}
/**
* Custom callback for test suite discovery.
*/
protected function handleCustomTestSuite()
{
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 array
*/
private static $ansiCodes = array(
'bold' => 1,
'fg-black' => 30,
'fg-red' => 31,
'fg-yellow' => 33,
'fg-cyan' => 36,
'fg-white' => 37,
'bg-red' => 41,
'bg-green' => 42,
'bg-yellow' => 43
);
/**
* @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();
$this->printErrors($result);
$printSeparator = $result->errorCount() > 0;
if ($printSeparator && $result->failureCount() > 0) {
$this->write("\n--\n\n");
}
$printSeparator = $printSeparator || $result->failureCount() > 0;
$this->printFailures($result);
if ($this->verbose) {
if ($printSeparator && $result->deprecatedFeaturesCount() > 0) {
$this->write("\n--\n\n");
}
$printSeparator = $printSeparator ||
$result->deprecatedFeaturesCount() > 0;
$this->printDeprecated($result);
if ($printSeparator && $result->riskyCount() > 0) {
$this->write("\n--\n\n");
}
$printSeparator = $printSeparator ||
$result->riskyCount() > 0;
$this->printRisky($result);
if ($printSeparator && $result->notImplementedCount() > 0) {
$this->write("\n--\n\n");
}
$printSeparator = $printSeparator ||
$result->notImplementedCount() > 0;
$this->printIncompletes($result);
if ($printSeparator && $result->skippedCount() > 0) {
$this->write("\n--\n\n");
}
$this->printSkipped($result);
}
$this->printFooter($result);
}
/**
* @param array $defects
* @param string $type
*/
protected function printDefects(array $defects, $type)
{
$count = count($defects);
if ($count == 0) {
return;
}
$this->write(
sprintf(
"There %s %d %s%s:\n",
($count == 1) ? 'was' : 'were',
$count,
$type,
($count == 1) ? '' : 's'
)
);
$i = 1;
foreach ($defects as $defect) {
$this->printDefect($defect, $i++);
}
}
/**
* @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());
$trace = PHPUnit_Util_Filter::getFilteredStacktrace(
$defect->thrownException()
);
if (!empty($trace)) {
$this->write("\n" . $trace);
}
$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(), 'error');
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printFailures(PHPUnit_Framework_TestResult $result)
{
$this->printDefects($result->failures(), 'failure');
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printIncompletes(PHPUnit_Framework_TestResult $result)
{
$this->printDefects($result->notImplemented(), 'incomplete test');
}
/**
* @param PHPUnit_Framework_TestResult $result
* @since Method available since Release 4.0.0
*/
protected function printRisky(PHPUnit_Framework_TestResult $result)
{
$this->printDefects($result->risky(), 'risky 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(), 'skipped test');
}
/**
* @param PHPUnit_Framework_TestResult $result
* @since Method available since Release 4.0.0
*/
protected function printDeprecated(PHPUnit_Framework_TestResult $result)
{
$deprecatedFeatures = $result->deprecatedFeatures();
$count = count($deprecatedFeatures);
if ($count == 0) {
return;
}
$this->write(
sprintf(
"There %s %d tests that use%s deprecated features:\n",
($count == 1) ? 'was' : 'were',
$count,
($count != 1) ? '' : 's'
)
);
$i = 1;
foreach ($result->deprecatedFeatures() as $deprecatedFeature) {
$this->write(
sprintf(
"\n%d) %s\n\n%s\n",
$i++,
$deprecatedFeature->getMessage(),
$deprecatedFeature->getSource()
)
);
}
}
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) {
$this->writeWithColor(
'fg-black, bg-yellow',
'No tests executed!'
);
} elseif ($result->wasSuccessful() &&
$result->allHarmless() &&
$result->allCompletelyImplemented() &&
$result->noneSkipped()) {
$this->writeWithColor(
'fg-black, bg-green',
sprintf(
'OK (%d test%s, %d assertion%s)',
count($result),
(count($result) == 1) ? '' : 's',
$this->numAssertions,
($this->numAssertions == 1) ? '' : 's'
)
);
} elseif ((!$result->allCompletelyImplemented() ||
!$result->allHarmless() ||
!$result->noneSkipped()) &&
$result->wasSuccessful()) {
$this->writeWithColor(
'fg-black, bg-yellow',
sprintf(
"%sOK, but incomplete, skipped, or risky tests!\n" .
'Tests: %d, Assertions: %d%s%s%s.',
$this->verbose ? "\n" : '',
count($result),
$this->numAssertions,
$this->getCountString(
$result->notImplementedCount(), 'Incomplete'
),
$this->getCountString(
$result->skippedCount(), 'Skipped'
),
$this->getCountString(
$result->riskyCount(), 'Risky'
)
)
);
} else {
$this->writeWithColor(
'fg-white, bg-red',
sprintf(
"\nFAILURES!\n" .
'Tests: %d, Assertions: %s%s%s%s%s.',
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->verbose &&
$result->deprecatedFeaturesCount() > 0) {
$this->write("\n");
$this->writeWithColor(
'fg-white, bg-red',
sprintf(
"Warning: Deprecated PHPUnit features are being used %s times!\n" .
'Use --verbose for more information.',
$result->deprecatedFeaturesCount()
)
);
}
}
/**
* @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)
{
$this->writeProgressWithColor('fg-red, bold', 'E');
$this->lastTestFailed = true;
}
/**
* A failure occurred.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_AssertionFailedError $e
* @param float $time
*/
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
{
$this->writeProgressWithColor('bg-red, fg-white', 'F');
$this->lastTestFailed = true;
}
/**
* Incomplete test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->writeProgressWithColor('fg-yellow, bold', 'I');
$this->lastTestFailed = true;
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->writeProgressWithColor('fg-yellow, bold', 'R');
$this->lastTestFailed = true;
}
/**
* Skipped test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 3.0.0
*/
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->writeProgressWithColor('fg-cyan, bold', '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();
} elseif ($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");
}
/**
* Formats a buffer with a specified ANSI color sequence if colors are
* enabled.
*
* @param string $color
* @param string $buffer
* @return string
* @since Method available since Release 4.0.0
*/
protected function formatWithColor($color, $buffer)
{
if (!$this->colors) {
return $buffer;
}
$codes = array_map('trim', explode(',', $color));
$lines = explode("\n", $buffer);
$padding = max(array_map('strlen', $lines));
$styles = array();
foreach ($codes as $code) {
$styles[] = self::$ansiCodes[$code];
}
$style = sprintf("\x1b[%sm", implode(';', $styles));
$styledLines = array();
foreach ($lines as $line) {
$styledLines[] = $style . str_pad($line, $padding) . "\x1b[0m";
}
return implode("\n", $styledLines);
}
/**
* Writes a buffer out with a color sequence if colors are enabled.
*
* @param string $color
* @param string $buffer
* @since Method available since Release 4.0.0
*/
protected function writeWithColor($color, $buffer)
{
$buffer = $this->formatWithColor($color, $buffer);
$this->write($buffer . "\n");
}
/**
* Writes progress with a color sequence if colors are enabled.
*
* @param string $color
* @param string $buffer
* @since Method available since Release 4.0.0
*/
protected function writeProgressWithColor($color, $buffer)
{
$buffer = $this->formatWithColor($color, $buffer);
$this->writeProgress($buffer);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
use SebastianBergmann\Environment\Runtime;
/**
* A TestRunner for the Command Line Interface (CLI)
* PHP SAPI Module.
*
* @package PHPUnit
* @subpackage TextUI
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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;
/**
* @var array
*/
private $missingExtensions = array();
/**
* @var boolean
*/
private $canCollectCodeCoverage;
/**
* @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;
$runtime = new Runtime;
$this->canCollectCodeCoverage = $runtime->canCollectCodeCoverage();
}
/**
* @param PHPUnit_Framework_Test|ReflectionClass $test
* @param array $arguments
* @return PHPUnit_Framework_TestResult
* @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;
}
private function processSuiteFilters(PHPUnit_Framework_TestSuite $suite, array $arguments)
{
if (!$arguments['filter'] &&
empty($arguments['groups']) &&
empty($arguments['excludeGroups'])) {
return;
}
$filterFactory = new PHPUnit_Runner_Filter_Factory();
if (!empty($arguments['excludeGroups'])) {
$filterFactory->addFilter(
new ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'),
$arguments['excludeGroups']
);
}
if (!empty($arguments['groups'])) {
$filterFactory->addFilter(
new ReflectionClass('PHPUnit_Runner_Filter_Group_Include'),
$arguments['groups']
);
}
if ($arguments['filter']) {
$filterFactory->addFilter(
new ReflectionClass('PHPUnit_Runner_Filter_Test'),
$arguments['filter']
);
}
$suite->injectFilter($filterFactory);
}
/**
* @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);
$this->processSuiteFilters($suite, $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['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['stopOnRisky']) {
$result->stopOnRisky(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 {
$printerClass = 'PHPUnit_TextUI_ResultPrinter';
if (isset($arguments['printer']) &&
is_string($arguments['printer']) &&
class_exists($arguments['printer'], false)) {
$class = new ReflectionClass($arguments['printer']);
if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
$printerClass = $arguments['printer'];
}
}
$this->printer = new $printerClass(
isset($arguments['stderr']) ? 'php://stderr' : null,
$arguments['verbose'],
$arguments['colors'],
$arguments['debug']
);
}
}
if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
$this->printer->write(
PHPUnit_Runner_Version::getVersionString() . "\n\n"
);
self::$versionStringPrinted = true;
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 (isset($arguments['coverageClover'])) {
$codeCoverageReports++;
}
if (isset($arguments['coverageCrap4J'])) {
$codeCoverageReports++;
}
if (isset($arguments['coverageHtml'])) {
$codeCoverageReports++;
}
if (isset($arguments['coveragePHP'])) {
$codeCoverageReports++;
}
if (isset($arguments['coverageText'])) {
$codeCoverageReports++;
}
if (isset($arguments['coverageXml'])) {
$codeCoverageReports++;
}
if ($codeCoverageReports > 0 && (!extension_loaded('tokenizer') || !$this->canCollectCodeCoverage)) {
if (!extension_loaded('tokenizer')) {
$this->showExtensionNotLoadedMessage(
'tokenizer', 'No code coverage will be generated.'
);
} elseif (!extension_loaded('Xdebug')) {
$this->showExtensionNotLoadedMessage(
'Xdebug', 'No code coverage will be generated.'
);
}
$codeCoverageReports = 0;
}
if ($codeCoverageReports > 0) {
$codeCoverage = new PHP_CodeCoverage(
null, $this->codeCoverageFilter
);
$codeCoverage->setAddUncoveredFilesFromWhitelist(
$arguments['addUncoveredFilesFromWhitelist']
);
$codeCoverage->setCheckForUnintentionallyCoveredCode(
$arguments['strictCoverage']
);
$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']
)
);
}
$result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']);
$result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']);
$result->beStrictAboutTestSize($arguments['enforceTimeLimit']);
$result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']);
$result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']);
$result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']);
if ($suite instanceof PHPUnit_Framework_TestSuite) {
$suite->setRunTestInSeparateProcess($arguments['processIsolation']);
}
$suite->run($result);
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['coverageCrap4J'])) {
$this->printer->write(
"\nGenerating Crap4J report XML file ..."
);
$writer = new PHP_CodeCoverage_Report_Crap4j;
$writer->process($codeCoverage, $arguments['coverageCrap4J']);
$this->printer->write(" done\n");
unset($writer);
}
if (isset($arguments['coverageHtml'])) {
$this->printer->write(
"\nGenerating code coverage report in HTML format ..."
);
$writer = new PHP_CodeCoverage_Report_HTML(
$arguments['reportLowUpperBound'],
$arguments['reportHighLowerBound'],
sprintf(
' and <a href="http://phpunit.de/">PHPUnit %s</a>',
PHPUnit_Runner_Version::id()
)
);
$writer->process($codeCoverage, $arguments['coverageHtml']);
$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;
}
$processor = new PHP_CodeCoverage_Report_Text(
$arguments['reportLowUpperBound'],
$arguments['reportHighLowerBound'],
$arguments['coverageTextShowUncoveredFiles'],
$arguments['coverageTextShowOnlySummary']
);
$outputStream->write(
$processor->process($codeCoverage, $colors)
);
}
if (isset($arguments['coverageXml'])) {
$this->printer->write(
"\nGenerating code coverage report in PHPUnit XML format ..."
);
$writer = new PHP_CodeCoverage_Report_XML;
$writer->process($codeCoverage, $arguments['coverageXml']);
$this->printer->write(" done\n");
unset($writer);
}
}
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['reportUselessTests']) &&
!isset($arguments['reportUselessTests'])) {
$arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests'];
}
if (isset($phpunitConfiguration['strictCoverage']) &&
!isset($arguments['strictCoverage'])) {
$arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage'];
}
if (isset($phpunitConfiguration['disallowTestOutput']) &&
!isset($arguments['disallowTestOutput'])) {
$arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput'];
}
if (isset($phpunitConfiguration['enforceTimeLimit']) &&
!isset($arguments['enforceTimeLimit'])) {
$arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit'];
}
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-clover']) &&
!isset($arguments['coverageClover'])) {
$arguments['coverageClover'] = $loggingConfiguration['coverage-clover'];
}
if (isset($loggingConfiguration['coverage-crap4j']) &&
!isset($arguments['coverageCrap4J'])) {
$arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j'];
}
if (isset($loggingConfiguration['coverage-html']) &&
!isset($arguments['coverageHtml'])) {
if (isset($loggingConfiguration['lowUpperBound']) &&
!isset($arguments['reportLowUpperBound'])) {
$arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound'];
}
if (isset($loggingConfiguration['highLowerBound']) &&
!isset($arguments['reportHighLowerBound'])) {
$arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound'];
}
$arguments['coverageHtml'] = $loggingConfiguration['coverage-html'];
}
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['coverageTextShowOnlySummary'])) {
$arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary'];
} else {
$arguments['coverageTextShowOnlySummary'] = false;
}
}
if (isset($loggingConfiguration['coverage-xml']) &&
!isset($arguments['coverageXml'])) {
$arguments['coverageXml'] = $loggingConfiguration['coverage-xml'];
}
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['coverageCrap4J']) ||
isset($arguments['coverageHtml']) ||
isset($arguments['coveragePHP'])) ||
isset($arguments['coverageText']) &&
$this->canCollectCodeCoverage) {
$filterConfiguration = $arguments['configuration']->getFilterConfiguration();
$arguments['addUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist'];
$arguments['processUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist'];
if (empty($filterConfiguration['whitelist']['include']['directory']) &&
empty($filterConfiguration['whitelist']['include']['file'])) {
if (defined('__PHPUNIT_PHAR__')) {
$this->codeCoverageFilter->addFileToBlacklist(__PHPUNIT_PHAR__);
}
$blacklist = new PHPUnit_Util_Blacklist;
foreach ($blacklist->getBlacklistedDirectories() as $directory) {
$this->codeCoverageFilter->addDirectoryToBlacklist($directory);
}
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['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 90;
$arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 50;
$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['stopOnRisky'] = isset($arguments['stopOnRisky']) ? $arguments['stopOnRisky'] : 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['reportUselessTests'] = isset($arguments['reportUselessTests']) ? $arguments['reportUselessTests'] : false;
$arguments['strictCoverage'] = isset($arguments['strictCoverage']) ? $arguments['strictCoverage'] : false;
$arguments['disallowTestOutput'] = isset($arguments['disallowTestOutput']) ? $arguments['disallowTestOutput'] : false;
$arguments['enforceTimeLimit'] = isset($arguments['enforceTimeLimit']) ? $arguments['enforceTimeLimit'] : false;
$arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : false;
}
/**
* @param string $message
* @since Method available since Release 4.0.0
*/
private 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"
);
$this->missingExtensions[$extension] = true;
}
/**
* Shows a message.
*
* @param string $message
* @param boolean $exit
* @since Method available since Release 4.0.0
*/
private function showMessage($message, $exit = false)
{
$this->printVersionString();
$this->write($message . "\n");
if ($exit) {
exit(self::EXCEPTION_EXIT);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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 STATUS_RISKY = 5;
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 (PHPUnit_Framework_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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Runner_Filter_Group_Exclude extends PHPUnit_Runner_Filter_GroupFilterIterator
{
protected function doAccept($hash)
{
return !in_array($hash, $this->groupTests);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Runner_Filter_Group_Include extends PHPUnit_Runner_Filter_GroupFilterIterator
{
protected function doAccept($hash)
{
return in_array($hash, $this->groupTests);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Runner_Filter_Factory
{
/**
* @var array
*/
private $filters = array();
/**
* @param ReflectionClass $filter
* @param mixed $args
*/
public function addFilter(ReflectionClass $filter, $args)
{
if (!$filter->isSubclassOf('RecursiveFilterIterator')) {
throw new InvalidArgumentException(
sprintf(
'Class "%s" does not extend RecursiveFilterIterator',
$filter->name
)
);
}
$this->filters[] = array($filter, $args);
}
/**
* @return FilterIterator
*/
public function factory(Iterator $iterator, PHPUnit_Framework_TestSuite $suite)
{
foreach ($this->filters as $filter) {
list($class, $args) = $filter;
$iterator = $class->newInstance($iterator, $args, $suite);
}
return $iterator;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
abstract class PHPUnit_Runner_Filter_GroupFilterIterator extends RecursiveFilterIterator
{
/**
* @var array
*/
protected $groupTests = array();
/**
* @param RecursiveIterator $iterator
* @param array $groups
* @param PHPUnit_Framework_TestSuite $suite
*/
public function __construct(RecursiveIterator $iterator, array $groups, PHPUnit_Framework_TestSuite $suite)
{
parent::__construct($iterator);
foreach ($suite->getGroupDetails() as $group => $tests) {
if (in_array($group, $groups)) {
$testHashes = array_map(
function ($test) { return spl_object_hash($test); },
$tests
);
$this->groupTests = array_merge($this->groupTests, $testHashes);
}
}
}
/**
* @return boolean
*/
public function accept()
{
$test = $this->getInnerIterator()->current();
if ($test instanceof PHPUnit_Framework_TestSuite) {
return true;
}
return $this->doAccept(spl_object_hash($test));
}
abstract protected function doAccept($hash);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Runner_Filter_Test extends RecursiveFilterIterator
{
/**
* @var string
*/
protected $filter = null;
/**
* @var integer
*/
protected $filterMin;
/**
* @var integer
*/
protected $filterMax;
/**
* @param RecursiveIterator $iterator
* @param string $filter
*/
public function __construct(RecursiveIterator $iterator, $filter)
{
parent::__construct($iterator);
$this->setFilter($filter);
}
/**
* @param string $filter
*/
protected function setFilter($filter)
{
if ($filter[0] != substr($filter, -1) ||
preg_match('/^[a-zA-Z0-9_]/', $filter)) {
// Handles:
// * testAssertEqualsSucceeds#4
// * testAssertEqualsSucceeds#4-8
if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
if (isset($matches[3]) && $matches[2] < $matches[3]) {
$filter = sprintf(
'%s.*with data set #(\d+)$',
$matches[1]
);
$this->filterMin = $matches[2];
$this->filterMax = $matches[3];
} else {
$filter = sprintf(
'%s.*with data set #%s$',
$matches[1],
$matches[2]
);
}
}
// Handles:
// * testDetermineJsonError@JSON_ERROR_NONE
// * testDetermineJsonError@JSON.*
elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
$filter = sprintf(
'%s.*with data set "%s"$',
$matches[1],
$matches[2]
);
}
// Escape delimiters in regular expression. Do NOT use preg_quote,
// to keep magic characters.
$filter = sprintf('/%s/', str_replace(
'/', '\\/', $filter
));
}
$this->filter = $filter;
}
/**
* @return boolean
*/
public function accept()
{
$test = $this->getInnerIterator()->current();
if ($test instanceof PHPUnit_Framework_TestSuite) {
return true;
}
$tmp = PHPUnit_Util_Test::describe($test, false);
if ($tmp[0] != '') {
$name = join('::', $tmp);
} else {
$name = $tmp[1];
}
$accepted = preg_match($this->filter, $name, $matches);
if ($accepted && isset($this->filterMax)) {
$set = end($matches);
$accepted = $set >= $this->filterMin && $set <= $this->filterMax;
}
return $accepted;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)) {
$loadedClasses = get_declared_classes();
$filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile);
$loadedClasses = array_values(
array_diff(get_declared_classes(), $loadedClasses)
);
}
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* @package PHPUnit
* @subpackage Runner
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
class PHPUnit_Runner_Exception extends RuntimeException implements PHPUnit_Exception
{
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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
{
private static $pharVersion = "4.1.1";
private static $version;
/**
* Returns the current version of PHPUnit.
*
* @return string
*/
public static function id()
{
if (self::$pharVersion !== null) {
return self::$pharVersion;
}
if (self::$version === null) {
$version = new SebastianBergmann\Version('4.1.1', dirname(dirname(__DIR__)));
self::$version = $version->getVersion();
}
return self::$version;
}
/**
* @return string
*/
public static function getVersionString()
{
return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann.';
}
/**
* @return string
* @since Method available since Release 4.0.0
*/
public static function getReleaseChannel()
{
if (strpos(self::$pharVersion, 'alpha') !== false) {
return '-alpha';
}
if (strpos(self::$pharVersion, 'beta') !== false) {
return '-beta';
}
return '';
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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
*/
/**
* Runner for PHPT test cases.
*
* @package PHPUnit
* @subpackage Extensions_PhptTestCase
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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
{
/**
* @var string
*/
private $filename;
/**
* @var array
*/
private $settings = array(
'allow_url_fopen=1',
'auto_append_file=',
'auto_prepend_file=',
'disable_functions=',
'display_errors=1',
'docref_root=',
'docref_ext=.html',
'error_append_string=',
'error_prepend_string=',
'error_reporting=-1',
'html_errors=0',
'log_errors=0',
'magic_quotes_runtime=0',
'output_handler=',
'open_basedir=',
'output_buffering=Off',
'report_memleaks=0',
'report_zend_debug=0',
'safe_mode=0',
'track_errors=1',
'xdebug.default_enable=0'
);
/**
* Constructs a test case with the given filename.
*
* @param string $filename
* @throws PHPUnit_Framework_Exception
*/
public function __construct($filename)
{
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;
}
/**
* 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
* @return PHPUnit_Framework_TestResult
*/
public function run(PHPUnit_Framework_TestResult $result = null)
{
$sections = $this->parse();
$code = $this->render($sections['FILE']);
if ($result === null) {
$result = new PHPUnit_Framework_TestResult;
}
$php = PHPUnit_Util_PHP::factory();
$skip = false;
$time = 0;
$result->startTest($this);
if (isset($sections['SKIPIF'])) {
$jobResult = $php->runJob($sections['SKIPIF'], $this->settings);
if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $message)) {
$message = substr($message[1], 2);
} else {
$message = '';
}
$result->addFailure($this, new PHPUnit_Framework_SkippedTestError($message), 0);
$skip = true;
}
}
if (!$skip) {
PHP_Timer::start();
$jobResult = $php->runJob($code, $this->settings);
$time = PHP_Timer::stop();
if (isset($sections['EXPECT'])) {
$assertion = 'assertEquals';
$expected = preg_replace('/\r\n/', "\n", trim($sections['EXPECT']));
} else {
$assertion = 'assertStringMatchesFormat';
$expected = trim($sections['EXPECTF']);
}
try {
PHPUnit_Framework_Assert::$assertion($expected, trim($jobResult['stdout']));
} catch (PHPUnit_Framework_AssertionFailedError $e) {
$result->addFailure($this, $e, $time);
} catch (Exception $e) {
$result->addError($this, $e, $time);
}
}
$result->endTest($this, $time);
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;
}
/**
* @return array
* @throws PHPUnit_Framework_Exception
*/
private function parse()
{
$sections = array();
$section = '';
foreach (file($this->filename) as $line) {
if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
$section = $result[1];
$sections[$section] = '';
continue;
} elseif (empty($section)) {
throw new PHPUnit_Framework_Exception('Invalid PHPT file');
}
$sections[$section] .= $line;
}
if (!isset($sections['FILE']) ||
(!isset($sections['EXPECT']) && !isset($sections['EXPECTF']))) {
throw new PHPUnit_Framework_Exception('Invalid PHPT file');
}
return $sections;
}
/**
* @param string $code
* @return string
*/
private function render($code)
{
return str_replace(
array(
'__DIR__',
'__FILE__'
),
array(
"'" . dirname($this->filename) . "'",
"'" . $this->filename . "'"
),
$code
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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, $processIsolation = false)
{
parent::__construct($test);
if (is_integer($timesRepeat) &&
$timesRepeat >= 0) {
$this->timesRepeat = $timesRepeat;
} else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
2, 'positive integer'
);
}
$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->setRunTestInSeparateProcess($this->processIsolation);
}
$this->test->run($result);
}
return $result;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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)
{
}
/**
* Risky test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 4.0.0
*/
public function addRiskyTest(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;
} elseif ($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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.phpunit.de/
* @since File available since Release 4.0.0
*/
/**
* Marker interface for PHPUnit exceptions.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian 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 4.0.0
*/
interface PHPUnit_Exception
{
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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 ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
$stack[1]['class'],
$stack[1]['function'],
$type
)
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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
*/
private $blacklistedFiles = array();
/**
* Source files that are whitelisted.
*
* @var array
*/
private $whitelistedFiles = array();
/**
* @var boolean
*/
private $blacklistPrefilled = false;
/**
* A list of classes which are always blacklisted
*
* @var array
*/
public static $blacklistClassNames = array(
'File_Iterator' => 1,
'PHP_CodeCoverage' => 1,
'PHP_Invoker' => 1,
'PHP_Timer' => 1,
'PHP_Token' => 1,
'PHPUnit_Framework_TestCase' => 2,
'PHPUnit_Extensions_Database_TestCase' => 2,
'PHPUnit_Framework_MockObject_Generator' => 2,
'PHPUnit_Extensions_SeleniumTestCase' => 2,
'PHPUnit_Extensions_Story_TestCase' => 2,
'Text_Template' => 1,
'Symfony\Component\Yaml\Yaml' => 1,
'SebastianBergmann\Diff\Diff' => 1,
'SebastianBergmann\Environment\Runtime' => 1,
'SebastianBergmann\Exporter\Exporter' => 1,
'SebastianBergmann\Version' => 1,
'Composer\Autoload\ClassLoader' => 1
);
/**
* 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)
{
if (!$this->isFile($filename)) {
return true;
}
$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
*/
private function prefillBlacklist()
{
if (defined('__PHPUNIT_PHAR__')) {
$this->addFileToBlacklist(__PHPUNIT_PHAR__);
}
foreach (self::$blacklistClassNames as $className => $parent) {
$this->addDirectoryContainingClassToBlacklist($className, $parent);
}
$this->blacklistPrefilled = true;
}
/**
* @param string $className
* @param integer $parent
* @since Method available since Release 1.2.3
*/
private 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);
}
/**
* Returns the blacklisted files.
*
* @return array
* @since Method available since Release 2.0.0
*/
public function getBlacklistedFiles()
{
return $this->blacklistedFiles;
}
/**
* Sets the blacklisted files.
*
* @param array $blacklistedFiles
* @since Method available since Release 2.0.0
*/
public function setBlacklistedFiles($blacklistedFiles)
{
$this->blacklistedFiles = $blacklistedFiles;
}
/**
* Returns the whitelisted files.
*
* @return array
* @since Method available since Release 2.0.0
*/
public function getWhitelistedFiles()
{
return $this->whitelistedFiles;
}
/**
* Sets the whitelisted files.
*
* @param array $whitelistedFiles
* @since Method available since Release 2.0.0
*/
public function setWhitelistedFiles($whitelistedFiles)
{
$this->whitelistedFiles = $whitelistedFiles;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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('This driver requires Xdebug');
}
if (version_compare(phpversion('xdebug'), '2.2.0-dev', '>=') &&
!ini_get('xdebug.coverage_enable')) {
throw new PHP_CodeCoverage_Exception(
'xdebug.coverage_enable=On has to be set in 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()
{
$data = xdebug_get_code_coverage();
xdebug_stop_code_coverage();
return $this->cleanup($data);
}
/**
* @param array $data
* @return array
* @since Method available since Release 2.0.0
*/
private function cleanup(array $data)
{
foreach (array_keys($data) as $file) {
if (isset($data[$file][0])) {
unset($data[$file][0]);
}
if (file_exists($file)) {
$numLines = $this->getNumberOfLinesInFile($file);
foreach (array_keys($data[$file]) as $line) {
if (isset($data[$file][$line]) && $line > $numLines) {
unset($data[$file][$line]);
}
}
}
}
return $data;
}
/**
* @param string $file
* @return integer
* @since Method available since Release 2.0.0
*/
private function getNumberOfLinesInFile($file)
{
$buffer = file_get_contents($file);
$lines = substr_count($buffer, "\n");
if (substr($buffer, -1) !== "\n") {
$lines++;
}
return $lines;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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.3.0
*/
/**
* Driver for HHVM's code coverage functionality.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2014 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.3.0
* @codeCoverageIgnore
*/
class PHP_CodeCoverage_Driver_HHVM implements PHP_CodeCoverage_Driver
{
/**
* Constructor.
*/
public function __construct()
{
if (!defined('HHVM_VERSION')) {
throw new PHP_CodeCoverage_Exception('This driver requires HHVM');
}
}
/**
* Start collection of code coverage information.
*/
public function start()
{
fb_enable_code_coverage();
}
/**
* Stop collection of code coverage information.
*
* @return array
*/
public function stop()
{
$codeCoverage = fb_get_code_coverage(TRUE);
fb_disable_code_coverage();
return $codeCoverage;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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 2.0.0
*/
/**
* Exception that is raised when code is unintentionally covered.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Exception_UnintentionallyCoveredCode extends PHP_CodeCoverage_Exception
{
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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
{
/**
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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 var_export() to write a PHP_CodeCoverage object to a file.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author uyga <iamuyga@gmail.com>
* @copyright 2009-2014 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)
{
$filter = $coverage->filter();
$output = sprintf(
'<?php
$coverage = new PHP_CodeCoverage;
$coverage->setData(%s);
$coverage->setTests(%s);
$filter = $coverage->filter();
$filter->setBlacklistedFiles(%s);
$filter->setWhitelistedFiles(%s);
return $coverage;',
var_export($coverage->getData(true), 1),
var_export($coverage->getTests(), 1),
var_export($filter->getBlacklistedFiles(), 1),
var_export($filter->getWhitelistedFiles(), 1)
);
if ($target !== null) {
return file_put_contents($target, $output);
} else {
return $output;
}
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML
{
/**
* @var string
*/
private $target;
/**
* @var PHP_CodeCoverage_Report_XML_Project
*/
private $project;
public function process(PHP_CodeCoverage $coverage, $target)
{
if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
$target .= DIRECTORY_SEPARATOR;
}
$this->target = $target;
$this->initTargetDirectory($target);
$report = $coverage->getReport();
$this->project = new PHP_CodeCoverage_Report_XML_Project(
$coverage->getReport()->getName()
);
$this->processTests($coverage->getTests());
$this->processDirectory($report, $this->project);
$index = $this->project->asDom();
$index->formatOutput = true;
$index->preserveWhiteSpace = false;
$index->save($target . '/index.xml');
}
private function initTargetDirectory($dir)
{
if (file_exists($dir)) {
if (!is_dir($dir)) {
throw new PHP_CodeCoverage_Exception(
"'$dir' exists but is not a directory."
);
}
if (!is_writable($dir)) {
throw new PHP_CodeCoverage_Exception(
"'$dir' exists but is not writable."
);
}
} elseif (!@mkdir($dir, 0777, true)) {
throw new PHP_CodeCoverage_Exception(
"'$dir' could not be created."
);
}
}
private function processDirectory(PHP_CodeCoverage_Report_Node_Directory $directory, PHP_CodeCoverage_Report_XML_Node $context)
{
$dirObject = $context->addDirectory($directory->getName());
$this->setTotals($directory, $dirObject->getTotals());
foreach ($directory as $node) {
if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
$this->processDirectory($node, $dirObject);
continue;
}
if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
$this->processFile($node, $dirObject);
continue;
}
throw new PHP_CodeCoverage_Exception(
'Unknown node type for XML report'
);
}
}
private function processFile(PHP_CodeCoverage_Report_Node_File $file, PHP_CodeCoverage_Report_XML_Directory $context)
{
$fileObject = $context->addFile(
$file->getName(),
$file->getId() . '.xml'
);
$this->setTotals($file, $fileObject->getTotals());
$fileReport = new PHP_CodeCoverage_Report_XML_File_Report(
$file->getName()
);
$this->setTotals($file, $fileReport->getTotals());
foreach ($file->getClassesAndTraits() as $unit) {
$this->processUnit($unit, $fileReport);
}
foreach ($file->getFunctions() as $function) {
$this->processFunction($function, $fileReport);
}
foreach ($file->getCoverageData() as $line => $tests) {
if (!is_array($tests) || count($tests) == 0) {
continue;
}
$coverage = $fileReport->getLineCoverage($line);
foreach ($tests as $test) {
$coverage->addTest($test);
}
$coverage->finalize();
}
$this->initTargetDirectory(
$this->target . dirname($file->getId()) . '/'
);
$fileDom = $fileReport->asDom();
$fileDom->formatOutput = true;
$fileDom->preserveWhiteSpace = false;
$fileDom->save($this->target . $file->getId() . '.xml');
}
private function processUnit($unit, PHP_CodeCoverage_Report_XML_File_Report $report)
{
if (isset($unit['className'])) {
$unitObject = $report->getClassObject($unit['className']);
} else {
$unitObject = $report->getTraitObject($unit['traitName']);
}
$unitObject->setLines(
$unit['startLine'],
$unit['executableLines'],
$unit['executedLines']
);
$unitObject->setCrap($unit['crap']);
$unitObject->setPackage(
$unit['package']['fullPackage'],
$unit['package']['package'],
$unit['package']['subpackage'],
$unit['package']['category']
);
$unitObject->setNamespace($unit['package']['namespace']);
foreach ($unit['methods'] as $method) {
$methodObject = $unitObject->addMethod($method['methodName']);
$methodObject->setSignature($method['signature']);
$methodObject->setLines($method['startLine'], $method['endLine']);
$methodObject->setCrap($method['crap']);
$methodObject->setTotals(
$method['executableLines'],
$method['executedLines'],
$method['coverage']
);
}
}
private function processFunction($function, PHP_CodeCoverage_Report_XML_File_Report $report)
{
$functionObject = $report->getFunctionObject($function['functionName']);
$functionObject->setSignature($function['signature']);
$functionObject->setLines($function['startLine']);
$functionObject->setCrap($function['crap']);
$functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
}
private function processTests(array $tests)
{
$testsObject = $this->project->getTests();
foreach ($tests as $test => $result) {
if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
continue;
}
$testsObject->addTest($test, $result);
}
}
private function setTotals(PHP_CodeCoverage_Report_Node $node, PHP_CodeCoverage_Report_XML_Totals $totals)
{
$loc = $node->getLinesOfCode();
$totals->setNumLines(
$loc['loc'],
$loc['cloc'],
$loc['ncloc'],
$node->getNumExecutableLines(),
$node->getNumExecutedLines()
);
$totals->setNumClasses(
$node->getNumClasses(),
$node->getNumTestedClasses()
);
$totals->setNumTraits(
$node->getNumTraits(),
$node->getNumTestedTraits()
);
$totals->setNumMethods(
$node->getNumMethods(),
$node->getNumTestedMethods()
);
$totals->setNumFunctions(
$node->getNumFunctions(),
$node->getNumTestedFunctions()
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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);
}
if (!defined('T_FINALLY')) {
define('T_FINALLY', 1004);
}
if (!defined('T_YIELD')) {
define('T_YIELD', 1005);
}
// @codeCoverageIgnoreEnd
/**
* Renders a PHP_CodeCoverage_Report_Node_File node.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2014 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
{
/**
* Constructor.
*
* @param string $templatePath
* @param string $generator
* @param string $date
* @param integer $lowUpperBound
* @param integer $highLowerBound
*/
public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
{
parent::__construct(
$templatePath,
$generator,
$date,
$lowUpperBound,
$highLowerBound
);
}
/**
* @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' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
)
);
$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
* @param Text_Template $methodItemTemplate
* @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();
$testData = $node->getTestData();
$codeLines = $this->loadFile($node->getPath());
$lines = '';
$i = 1;
foreach ($codeLines as $line) {
$numTests = '';
$trClass = '';
$popoverContent = '';
$popoverTitle = '';
if (array_key_exists($i, $coverageData)) {
$numTests = count($coverageData[$i]);
if ($coverageData[$i] === null) {
$trClass = ' class="warning"';
} elseif ($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,
$line
);
$i++;
}
return $lines;
}
/**
* @param string $file
* @return array
*/
protected function loadFile($file)
{
$buffer = file_get_contents($file);
$tokens = token_get_all($buffer);
$result = array('');
$i = 0;
$stringFlag = false;
$fileEndsWithNewLine = substr($buffer, -1) == "\n";
unset($buffer);
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_FINALLY:
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:
case T_YIELD: {
$colour = 'keyword';
}
break;
default: {
$colour = 'default';
}
}
}
$result[$i] .= sprintf(
'<span class="%s">%s</span>',
$colour,
$line
);
}
if (isset($lines[$jj + 1])) {
$result[++$i] = '';
}
}
}
}
if ($fileEndsWithNewLine) {
unset($result[count($result)-1]);
}
return $result;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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 {
if ($item instanceof PHP_CodeCoverage_Report_Node_Directory) {
$data['name'] = sprintf(
'<a href="%s/index.html">%s</a>',
$item->getName(),
$item->getName()
);
$data['icon'] = '<span class="glyphicon glyphicon-folder-open"></span> ';
} else {
$data['name'] = sprintf(
'<a href="%s.html">%s</a>',
$item->getName(),
$item->getName()
);
$data['icon'] = '<span class="glyphicon glyphicon-file"></span> ';
}
}
return $this->renderItemTemplate(
new Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'),
$data
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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);
$complexity = $this->complexity($classes);
$coverageDistribution = $this->coverageDistribution($classes);
$insufficientCoverage = $this->insufficientCoverage($classes);
$projectRisks = $this->projectRisks($classes);
$template->setVar(
array(
'insufficient_coverage_classes' => $insufficientCoverage['class'],
'insufficient_coverage_methods' => $insufficientCoverage['method'],
'project_risks_classes' => $projectRisks['class'],
'project_risks_methods' => $projectRisks['method'],
'complexity_class' => $complexity['class'],
'complexity_method' => $complexity['method'],
'class_coverage_distribution' => $coverageDistribution['class'],
'method_coverage_distribution' => $coverageDistribution['method']
)
);
$template->renderTo($file);
}
/**
* Returns the data for the Class/Method Complexity charts.
*
* @param array $classes
* @return array
*/
protected function complexity(array $classes)
{
$result = array('class' => array(), 'method' => array());
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($className != '*') {
$methodName = $className . '::' . $methodName;
}
$result['method'][] = array(
$method['coverage'],
$method['ccn'],
sprintf(
'<a href="%s">%s</a>',
$method['link'],
$methodName
)
);
}
$result['class'][] = array(
$class['coverage'],
$class['ccn'],
sprintf(
'<a href="%s">%s</a>',
$class['link'],
$className
)
);
}
return array(
'class' => json_encode($result['class']),
'method' => json_encode($result['method'])
);
}
/**
* Returns the data for the Class / Method Coverage Distribution chart.
*
* @param array $classes
* @return array
*/
protected function coverageDistribution(array $classes)
{
$result = array(
'class' => 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
),
'method' => 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) {
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] == 0) {
$result['method']['0%']++;
} elseif ($method['coverage'] == 100) {
$result['method']['100%']++;
} else {
$key = floor($method['coverage'] / 10) * 10;
$key = $key . '-' . ($key + 10) . '%';
$result['method'][$key]++;
}
}
if ($class['coverage'] == 0) {
$result['class']['0%']++;
} elseif ($class['coverage'] == 100) {
$result['class']['100%']++;
} else {
$key = floor($class['coverage'] / 10) * 10;
$key = $key . '-' . ($key + 10) . '%';
$result['class'][$key]++;
}
}
return array(
'class' => json_encode(array_values($result['class'])),
'method' => json_encode(array_values($result['method']))
);
}
/**
* Returns the classes / methods with insufficient coverage.
*
* @param array $classes
* @return array
*/
protected function insufficientCoverage(array $classes)
{
$leastTestedClasses = array();
$leastTestedMethods = array();
$result = array('class' => '', 'method' => '');
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] < $this->highLowerBound) {
if ($className != '*') {
$key = $className . '::' . $methodName;
} else {
$key = $methodName;
}
$leastTestedMethods[$key] = $method['coverage'];
}
}
if ($class['coverage'] < $this->highLowerBound) {
$leastTestedClasses[$className] = $class['coverage'];
}
}
asort($leastTestedClasses);
asort($leastTestedMethods);
foreach ($leastTestedClasses as $className => $coverage) {
$result['class'] .= sprintf(
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
$classes[$className]['link'],
$className,
$coverage
);
}
foreach ($leastTestedMethods as $methodName => $coverage) {
list($class, $method) = explode('::', $methodName);
$result['method'] .= sprintf(
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
$classes[$class]['methods'][$method]['link'],
$methodName,
$coverage
);
}
return $result;
}
/**
* Returns the project risks according to the CRAP index.
*
* @param array $classes
* @return array
*/
protected function projectRisks(array $classes)
{
$classRisks = array();
$methodRisks = array();
$result = array('class' => '', 'method' => '');
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] < $this->highLowerBound &&
$method['ccn'] > 1) {
if ($className != '*') {
$key = $className . '::' . $methodName;
} else {
$key = $methodName;
}
$methodRisks[$key] = $method['crap'];
}
}
if ($class['coverage'] < $this->highLowerBound &&
$class['ccn'] > count($class['methods'])) {
$classRisks[$className] = $class['crap'];
}
}
arsort($classRisks);
arsort($methodRisks);
foreach ($classRisks as $className => $crap) {
$result['class'] .= sprintf(
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
$classes[$className]['link'],
$className,
$crap
);
}
foreach ($methodRisks as $methodName => $crap) {
list($class, $method) = explode('::', $methodName);
$result['method'] .= sprintf(
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
$classes[$class]['methods'][$method]['link'],
$methodName,
$crap
);
}
return $result;
}
protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
{
return sprintf(
' <li><a href="index.html">%s</a></li>' . "\n" .
' <li class="active">(Dashboard)</li>' . "\n",
$node->getName()
);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Code Coverage for {{full_path}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
<link href="{{path_to_root}}css/style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="{{path_to_root}}js/html5shiv.js"></script>
<script src="{{path_to_root}}js/respond.min.js"></script>
<![endif]-->
</head>
<body>
<header>
<div class="container">
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
{{breadcrumbs}}
</ol>
</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>
<hr/>
<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="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
</p>
</footer>
</div>
<script src="{{path_to_root}}js/jquery.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/holder.js" type="text/javascript"></script>
</body>
</html>
<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>
/*!
Holder - 2.3.1 - client side image placeholders
(c) 2012-2014 Ivan Malopinsky / http://imsky.co
Provided under the MIT License.
Commercial use requires attribution.
*/
var Holder = Holder || {};
(function (app, win) {
var system_config = {
use_svg: false,
use_canvas: false,
use_fallback: false
};
var instance_config = {};
var preempted = false;
canvas = document.createElement('canvas');
var dpr = 1, bsr = 1;
var resizable_images = [];
if (!canvas.getContext) {
system_config.use_fallback = true;
} else {
if (canvas.toDataURL("image/png")
.indexOf("data:image/png") < 0) {
//Android doesn't support data URI
system_config.use_fallback = true;
} else {
var ctx = canvas.getContext("2d");
}
}
if(!!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect){
system_config.use_svg = true;
system_config.use_canvas = false;
}
if(!system_config.use_fallback){
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
}
var ratio = dpr / bsr;
var settings = {
domain: "holder.js",
images: "img",
bgnodes: ".holderjs",
themes: {
"gray": {
background: "#eee",
foreground: "#aaa",
size: 12
},
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
},
"sky": {
background: "#0D8FDB",
foreground: "#fff",
size: 12
},
"vine": {
background: "#39DBAC",
foreground: "#1E292C",
size: 12
},
"lava": {
background: "#F8591A",
foreground: "#1C2846",
size: 12
}
},
stylesheet: ""
};
app.flags = {
dimensions: {
regex: /^(\d+)x(\d+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: +exec[1],
height: +exec[2]
}
}
},
fluid: {
regex: /^([0-9%]+)x([0-9%]+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) {
var exec = this.regex.exec(val);
return {
size: settings.themes.gray.size,
foreground: "#" + exec[2],
background: "#" + exec[1]
}
}
},
text: {
regex: /text\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
font: {
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
},
textmode: {
regex: /textmode\:(.*)/,
output: function(val){
return this.regex.exec(val)[1];
}
}
}
function text_size(width, height, template) {
height = parseInt(height, 10);
width = parseInt(width, 10);
var bigSide = Math.max(height, width)
var smallSide = Math.min(height, width)
var scale = 1 / 12;
var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);
return {
height: Math.round(Math.max(template.size, newHeight))
}
}
var svg_el = (function(){
//Prevent IE <9 from initializing SVG renderer
if(!window.XMLSerializer) return;
var serializer = new XMLSerializer();
var svg_ns = "http://www.w3.org/2000/svg"
var svg = document.createElementNS(svg_ns, "svg");
//IE throws an exception if this is set and Chrome requires it to be set
if(svg.webkitMatchesSelector){
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
}
var bg_el = document.createElementNS(svg_ns, "rect")
var text_el = document.createElementNS(svg_ns, "text")
var textnode_el = document.createTextNode(null)
text_el.setAttribute("text-anchor", "middle")
text_el.appendChild(textnode_el)
svg.appendChild(bg_el)
svg.appendChild(text_el)
return function(props){
svg.setAttribute("width",props.width);
svg.setAttribute("height", props.height);
bg_el.setAttribute("width", props.width);
bg_el.setAttribute("height", props.height);
bg_el.setAttribute("fill", props.template.background);
text_el.setAttribute("x", props.width/2)
text_el.setAttribute("y", props.height/2)
textnode_el.nodeValue=props.text
text_el.setAttribute("style", css_properties({
"fill": props.template.foreground,
"font-weight": "bold",
"font-size": props.text_height+"px",
"font-family":props.font,
"dominant-baseline":"central"
}))
return serializer.serializeToString(svg)
}
})()
function css_properties(props){
var ret = [];
for(p in props){
if(props.hasOwnProperty(p)){
ret.push(p+":"+props[p])
}
}
return ret.join(";")
}
function draw_canvas(args) {
var ctx = args.ctx,
dimensions = args.dimensions,
template = args.template,
ratio = args.ratio,
holder = args.holder,
literal = holder.textmode == "literal",
exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width * ratio,
height = dimensions.height * ratio;
var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
canvas.width = width;
canvas.height = height;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = template.background;
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = template.foreground;
ctx.font = "bold " + text_height + "px " + font;
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) {
var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
}
var text_width = ctx.measureText(text).width;
if (text_width / width >= 0.75) {
text_height = Math.floor(text_height * 0.75 * (width / text_width));
}
//Resetting font size if necessary
ctx.font = "bold " + (text_height * ratio) + "px " + font;
ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png");
}
function draw_svg(args){
var dimensions = args.dimensions,
template = args.template,
holder = args.holder,
literal = holder.textmode == "literal",
exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width,
height = dimensions.height;
var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) {
var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
}
var string = svg_el({
text: text,
width:width,
height:height,
text_height:text_height,
font:font,
template:template
})
return "data:image/svg+xml;base64,"+btoa(string);
}
function draw(args) {
if(instance_config.use_canvas && !instance_config.use_svg){
return draw_canvas(args);
}
else{
return draw_svg(args);
}
}
function render(mode, el, holder, src) {
var dimensions = holder.dimensions,
theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, {
text: text
}) : theme);
theme = (holder.font ? extend(theme, {
font: holder.font
}) : theme);
el.setAttribute("data-src", src);
holder.theme = theme;
el.holder_data = holder;
if (mode == "image") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (instance_config.use_fallback || !holder.auto) {
el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px";
}
if (instance_config.use_fallback) {
el.style.backgroundColor = theme.background;
} else {
el.setAttribute("src", draw({ctx: ctx, dimensions: dimensions, template: theme, ratio:ratio, holder: holder}));
if(holder.textmode && holder.textmode == "exact"){
resizable_images.push(el);
resizable_update(el);
}
}
} else if (mode == "background") {
if (!instance_config.use_fallback) {
el.style.backgroundImage = "url(" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + ")";
el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
}
} else if (mode == "fluid") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (dimensions.height.slice(-1) == "%") {
el.style.height = dimensions.height
} else if(holder.auto == null || !holder.auto){
el.style.height = dimensions.height + "px"
}
if (dimensions.width.slice(-1) == "%") {
el.style.width = dimensions.width
} else if(holder.auto == null || !holder.auto){
el.style.width = dimensions.width + "px"
}
if (el.style.display == "inline" || el.style.display === "" || el.style.display == "none") {
el.style.display = "block";
}
set_initial_dimensions(el)
if (instance_config.use_fallback) {
el.style.backgroundColor = theme.background;
} else {
resizable_images.push(el);
resizable_update(el);
}
}
}
function dimension_check(el, callback) {
var dimensions = {
height: el.clientHeight,
width: el.clientWidth
};
if (!dimensions.height && !dimensions.width) {
el.setAttribute("data-holder-invisible", true)
callback.call(this, el)
}
else{
el.removeAttribute("data-holder-invisible")
return dimensions;
}
}
function set_initial_dimensions(el){
if(el.holder_data){
var dimensions = dimension_check(el, app.invisible_error_fn( set_initial_dimensions))
if(dimensions){
var holder = el.holder_data;
holder.initial_dimensions = dimensions;
holder.fluid_data = {
fluid_height: holder.dimensions.height.slice(-1) == "%",
fluid_width: holder.dimensions.width.slice(-1) == "%",
mode: null
}
if(holder.fluid_data.fluid_width && !holder.fluid_data.fluid_height){
holder.fluid_data.mode = "width"
holder.fluid_data.ratio = holder.initial_dimensions.width / parseFloat(holder.dimensions.height)
}
else if(!holder.fluid_data.fluid_width && holder.fluid_data.fluid_height){
holder.fluid_data.mode = "height";
holder.fluid_data.ratio = parseFloat(holder.dimensions.width) / holder.initial_dimensions.height
}
}
}
}
function resizable_update(element) {
var images;
if (element.nodeType == null) {
images = resizable_images;
} else {
images = [element]
}
for (var i in images) {
if (!images.hasOwnProperty(i)) {
continue;
}
var el = images[i]
if (el.holder_data) {
var holder = el.holder_data;
var dimensions = dimension_check(el, app.invisible_error_fn( resizable_update))
if(dimensions){
if(holder.fluid){
if(holder.auto){
switch(holder.fluid_data.mode){
case "width":
dimensions.height = dimensions.width / holder.fluid_data.ratio;
break;
case "height":
dimensions.width = dimensions.height * holder.fluid_data.ratio;
break;
}
}
el.setAttribute("src", draw({
ctx: ctx,
dimensions: dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
if(holder.textmode && holder.textmode == "exact"){
holder.exact_dimensions = dimensions;
el.setAttribute("src", draw({
ctx: ctx,
dimensions: holder.dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
}
}
}
}
function parse_flags(flags, options) {
var ret = {
theme: extend(settings.themes.gray, {})
};
var render = false;
for (var fl = flags.length, j = 0; j < fl; j++) {
var flag = flags[j];
if (app.flags.dimensions.match(flag)) {
render = true;
ret.dimensions = app.flags.dimensions.output(flag);
} else if (app.flags.fluid.match(flag)) {
render = true;
ret.dimensions = app.flags.fluid.output(flag);
ret.fluid = true;
} else if (app.flags.textmode.match(flag)) {
ret.textmode = app.flags.textmode.output(flag)
} else if (app.flags.colors.match(flag)) {
ret.theme = app.flags.colors.output(flag);
} else if (options.themes[flag]) {
//If a theme is specified, it will override custom colors
if(options.themes.hasOwnProperty(flag)){
ret.theme = extend(options.themes[flag], {});
}
} else if (app.flags.font.match(flag)) {
ret.font = app.flags.font.output(flag);
} else if (app.flags.auto.match(flag)) {
ret.auto = true;
} else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(flag);
}
}
return render ? ret : false;
}
for (var flag in app.flags) {
if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) {
return val.match(this.regex)
}
}
app.invisible_error_fn = function(fn){
return function(el){
if(el.hasAttribute("data-holder-invisible")){
throw new Error("Holder: invisible placeholder")
}
}
}
app.add_theme = function (name, theme) {
name != null && theme != null && (settings.themes[name] = theme);
return app;
};
app.add_image = function (src, el) {
var node = selector(el);
if (node.length) {
for (var i = 0, l = node.length; i < l; i++) {
var img = document.createElement("img")
img.setAttribute("data-src", src);
node[i].appendChild(img);
}
}
return app;
};
app.run = function (o) {
instance_config = extend({}, system_config)
preempted = true;
var options = extend(settings, o),
images = [],
imageNodes = [],
bgnodes = [];
if(options.use_canvas != null && options.use_canvas){
instance_config.use_canvas = true;
instance_config.use_svg = false;
}
if (typeof (options.images) == "string") {
imageNodes = selector(options.images);
} else if (window.NodeList && options.images instanceof window.NodeList) {
imageNodes = options.images;
} else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images];
} else if(window.HTMLCollection && options.images instanceof window.HTMLCollection){
imageNodes = options.images
}
if (typeof (options.bgnodes) == "string") {
bgnodes = selector(options.bgnodes);
} else if (window.NodeList && options.elements instanceof window.NodeList) {
bgnodes = options.bgnodes;
} else if (window.Node && options.bgnodes instanceof window.Node) {
bgnodes = [options.bgnodes];
}
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style");
if (!holdercss) {
holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss);
}
if (!options.nocss) {
if (holdercss.styleSheet) {
holdercss.styleSheet.cssText += options.stylesheet;
} else {
holdercss.appendChild(document.createTextNode(options.stylesheet));
}
}
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
for (var l = bgnodes.length, i = 0; i < l; i++) {
var src = window.getComputedStyle(bgnodes[i], null)
.getPropertyValue("background-image");
var flags = src.match(cssregex);
var bgsrc = bgnodes[i].getAttribute("data-background-src");
if (flags) {
var holder = parse_flags(flags[1].split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
} else if (bgsrc != null) {
var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
}
}
for (l = images.length, i = 0; i < l; i++) {
var attr_data_src, attr_src;
attr_src = attr_data_src = src = null;
try {
attr_src = images[i].getAttribute("src");
attr_datasrc = images[i].getAttribute("data-src");
} catch (e) {}
if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {
src = attr_src;
} else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {
src = attr_datasrc;
}
if (src) {
var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1).split("/"), options);
if (holder) {
if (holder.fluid) {
render("fluid", images[i], holder, src)
} else {
render("image", images[i], holder, src);
}
}
}
}
return app;
};
contentLoaded(win, function () {
if (window.addEventListener) {
window.addEventListener("resize", resizable_update, false);
window.addEventListener("orientationchange", resizable_update, false);
} else {
window.attachEvent("onresize", resizable_update)
}
preempted || app.run({});
});
if (typeof define === "function" && define.amd) {
define([], function () {
return app;
});
}
//github.com/davidchambers/Base64.js
(function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
//getElementsByClassName polyfill
document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s})
//getComputedStyle polyfill
window.getComputedStyle||(window.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var n=/(\-([a-z]){1})/g;return t=="float"&&(t="styleFloat"),n.test(t)&&(t=t.replace(n,function(){return arguments[2].toUpperCase()})),e.currentStyle[t]?e.currentStyle[t]:null},this})
//http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}}
//https://gist.github.com/991057 by Jed Schmidt with modifications
function selector(a,b){var a=a.match(/^(\W)?(.*)/),b=b||document,c=b["getElement"+(a[1]?"#"==a[1]?"ById":"sByClassName":"sByTagName")],d=c.call(b,a[2]),e=[];return null!==d&&(e=d.length||0===d.length?d:[d]),e}
//shallow object property extend
function extend(a,b){
var c={};
for(var i in a){
if(a.hasOwnProperty(i)){
c[i]=a[i];
}
}
for(var i in b){
if(b.hasOwnProperty(i)){
c[i]=b[i];
}
}
return c
}
//hasOwnProperty polyfill
if (!Object.prototype.hasOwnProperty)
/*jshint -W001, -W103 */
Object.prototype.hasOwnProperty = function(prop) {
var proto = this.__proto__ || this.constructor.prototype;
return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);
}
/*jshint +W001, +W103 */
})(Holder, window);/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
* */
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);/*
HTML5 Shiv v3.7.0 | @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,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</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 dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",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);(function(){function t(e,t){return(new Date(t,e+1,0)).getDate()}function n(e,t,n){return function(r,i,s){var o=e(r),u=[];o<r&&t(o);if(s>1)while(o<i){var a=new Date(+o);n(a)%s===0&&u.push(a),t(o)}else while(o<i)u.push(new Date(+o)),t(o);return u}}var e=window.nv||{};e.version="1.1.15b",e.dev=!0,window.nv=e,e.tooltip=e.tooltip||{},e.utils=e.utils||{},e.models=e.models||{},e.charts={},e.graphs=[],e.logs={},e.dispatch=d3.dispatch("render_start","render_end"),e.dev&&(e.dispatch.on("render_start",function(t){e.logs.startTime=+(new Date)}),e.dispatch.on("render_end",function(t){e.logs.endTime=+(new Date),e.logs.totalTime=e.logs.endTime-e.logs.startTime,e.log("total",e.logs.totalTime)})),e.log=function(){if(e.dev&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(e.dev&&typeof console.log=="function"&&Function.prototype.bind){var t=Function.prototype.bind.call(console.log,console);t.apply(console,arguments)}return arguments[arguments.length-1]},e.render=function(n){n=n||1,e.render.active=!0,e.dispatch.render_start(),setTimeout(function(){var t,r;for(var i=0;i<n&&(r=e.render.queue[i]);i++)t=r.generate(),typeof r.callback==typeof Function&&r.callback(t),e.graphs.push(t);e.render.queue.splice(0,i),e.render.queue.length?setTimeout(arguments.callee,0):(e.dispatch.render_end(),e.render.active=!1)},0)},e.render.active=!1,e.render.queue=[],e.addGraph=function(t){typeof arguments[0]==typeof Function&&(t={generate:arguments[0],callback:arguments[1]}),e.render.queue.push(t),e.render.active||e.render()},e.identity=function(e){return e},e.strip=function(e){return e.replace(/(\s|&)/g,"")},d3.time.monthEnd=function(e){return new Date(e.getFullYear(),e.getMonth(),0)},d3.time.monthEnds=n(d3.time.monthEnd,function(e){e.setUTCDate(e.getUTCDate()+1),e.setDate(t(e.getMonth()+1,e.getFullYear()))},function(e){return e.getMonth()}),e.interactiveGuideline=function(){"use strict";function c(o){o.each(function(o){function g(){var e=d3.mouse(this),n=e[0],r=e[1],o=!0,a=!1;l&&(n=d3.event.offsetX,r=d3.event.offsetY,d3.event.target.tagName!=="svg"&&(o=!1),d3.event.target.className.baseVal.match("nv-legend")&&(a=!0)),o&&(n-=i.left,r-=i.top);if(n<0||r<0||n>p||r>d||d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined||a){if(l&&d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined&&d3.event.relatedTarget.className.match(t.nvPointerEventsClass))return;u.elementMouseout({mouseX:n,mouseY:r}),c.renderGuideLine(null);return}var f=s.invert(n);u.elementMousemove({mouseX:n,mouseY:r,pointXValue:f}),d3.event.type==="dblclick"&&u.elementDblclick({mouseX:n,mouseY:r,pointXValue:f})}var h=d3.select(this),p=n||960,d=r||400,v=h.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([o]),m=v.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");m.append("g").attr("class","nv-interactiveGuideLine");if(!f)return;f.on("mousemove",g,!0).on("mouseout",g,!0).on("dblclick",g),c.renderGuideLine=function(t){if(!a)return;var n=v.select(".nv-interactiveGuideLine").selectAll("line").data(t!=null?[e.utils.NaNtoZero(t)]:[],String);n.enter().append("line").attr("class","nv-guideline").attr("x1",function(e){return e}).attr("x2",function(e){return e}).attr("y1",d).attr("y2",0),n.exit().remove()}})}var t=e.models.tooltip(),n=null,r=null,i={left:0,top:0},s=d3.scale.linear(),o=d3.scale.linear(),u=d3.dispatch("elementMousemove","elementMouseout","elementDblclick"),a=!0,f=null,l=navigator.userAgent.indexOf("MSIE")!==-1;return c.dispatch=u,c.tooltip=t,c.margin=function(e){return arguments.length?(i.top=typeof e.top!="undefined"?e.top:i.top,i.left=typeof e.left!="undefined"?e.left:i.left,c):i},c.width=function(e){return arguments.length?(n=e,c):n},c.height=function(e){return arguments.length?(r=e,c):r},c.xScale=function(e){return arguments.length?(s=e,c):s},c.showGuideLine=function(e){return arguments.length?(a=e,c):a},c.svgContainer=function(e){return arguments.length?(f=e,c):f},c},e.interactiveBisect=function(e,t,n){"use strict";if(!e instanceof Array)return null;typeof n!="function"&&(n=function(e,t){return e.x});var r=d3.bisector(n).left,i=d3.max([0,r(e,t)-1]),s=n(e[i],i);typeof s=="undefined"&&(s=i);if(s===t)return i;var o=d3.min([i+1,e.length-1]),u=n(e[o],o);return typeof u=="undefined"&&(u=o),Math.abs(u-t)>=Math.abs(s-t)?i:o},e.nearestValueIndex=function(e,t,n){"use strict";var r=Infinity,i=null;return e.forEach(function(e,s){var o=Math.abs(t-e);o<=r&&o<n&&(r=o,i=s)}),i},function(){"use strict";window.nv.tooltip={},window.nv.models.tooltip=function(){function y(){if(a){var e=d3.select(a);e.node().tagName!=="svg"&&(e=e.select("svg"));var t=e.node()?e.attr("viewBox"):null;if(t){t=t.split(" ");var n=parseInt(e.style("width"))/t[2];l.left=l.left*n,l.top=l.top*n}}}function b(e){var t;a?t=d3.select(a):t=d3.select("body");var n=t.select(".nvtooltip");return n.node()===null&&(n=t.append("div").attr("class","nvtooltip "+(u?u:"xy-tooltip")).attr("id",h)),n.node().innerHTML=e,n.style("top",0).style("left",0).style("opacity",0),n.selectAll("div, table, td, tr").classed(p,!0),n.classed(p,!0),n.node()}function w(){if(!c)return;if(!g(n))return;y();var t=l.left,u=o!=null?o:l.top,h=b(m(n));f=h;if(a){var p=a.getElementsByTagName("svg")[0],d=p?p.getBoundingClientRect():a.getBoundingClientRect(),v={left:0,top:0};if(p){var E=p.getBoundingClientRect(),S=a.getBoundingClientRect(),x=E.top;if(x<0){var T=a.getBoundingClientRect();x=Math.abs(x)>T.height?0:x}v.top=Math.abs(x-S.top),v.left=Math.abs(E.left-S.left)}t+=a.offsetLeft+v.left-2*a.scrollLeft,u+=a.offsetTop+v.top-2*a.scrollTop}return s&&s>0&&(u=Math.floor(u/s)*s),e.tooltip.calcTooltipPosition([t,u],r,i,h),w}var t=null,n=null,r="w",i=50,s=25,o=null,u=null,a=null,f=null,l={left:null,top:null},c=!0,h="nvtooltip-"+Math.floor(Math.random()*1e5),p="nv-pointer-events-none",d=function(e,t){return e},v=function(e){return e},m=function(e){if(t!=null)return t;if(e==null)return"";var n=d3.select(document.createElement("table")),r=n.selectAll("thead").data([e]).enter().append("thead");r.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(v(e.value));var i=n.selectAll("tbody").data([e]).enter().append("tbody"),s=i.selectAll("tr").data(function(e){return e.series}).enter().append("tr").classed("highlight",function(e){return e.highlight});s.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(e){return e.color}),s.append("td").classed("key",!0).html(function(e){return e.key}),s.append("td").classed("value",!0).html(function(e,t){return d(e.value,t)}),s.selectAll("td").each(function(e){if(e.highlight){var t=d3.scale.linear().domain([0,1]).range(["#fff",e.color]),n=.6;d3.select(this).style("border-bottom-color",t(n)).style("border-top-color",t(n))}});var o=n.node().outerHTML;return e.footer!==undefined&&(o+="<div class='footer'>"+e.footer+"</div>"),o},g=function(e){return e&&e.series&&e.series.length>0?!0:!1};return w.nvPointerEventsClass=p,w.content=function(e){return arguments.length?(t=e,w):t},w.tooltipElem=function(){return f},w.contentGenerator=function(e){return arguments.length?(typeof e=="function"&&(m=e),w):m},w.data=function(e){return arguments.length?(n=e,w):n},w.gravity=function(e){return arguments.length?(r=e,w):r},w.distance=function(e){return arguments.length?(i=e,w):i},w.snapDistance=function(e){return arguments.length?(s=e,w):s},w.classes=function(e){return arguments.length?(u=e,w):u},w.chartContainer=function(e){return arguments.length?(a=e,w):a},w.position=function(e){return arguments.length?(l.left=typeof e.left!="undefined"?e.left:l.left,l.top=typeof e.top!="undefined"?e.top:l.top,w):l},w.fixedTop=function(e){return arguments.length?(o=e,w):o},w.enabled=function(e){return arguments.length?(c=e,w):c},w.valueFormatter=function(e){return arguments.length?(typeof e=="function"&&(d=e),w):d},w.headerFormatter=function(e){return arguments.length?(typeof e=="function"&&(v=e),w):v},w.id=function(){return h},w},e.tooltip.show=function(t,n,r,i,s,o){var u=document.createElement("div");u.className="nvtooltip "+(o?o:"xy-tooltip");var a=s;if(!s||s.tagName.match(/g|svg/i))a=document.getElementsByTagName("body")[0];u.style.left=0,u.style.top=0,u.style.opacity=0,u.innerHTML=n,a.appendChild(u),s&&(t[0]=t[0]-s.scrollLeft,t[1]=t[1]-s.scrollTop),e.tooltip.calcTooltipPosition(t,r,i,u)},e.tooltip.findFirstNonSVGParent=function(e){while(e.tagName.match(/^g|svg$/i)!==null)e=e.parentNode;return e},e.tooltip.findTotalOffsetTop=function(e,t){var n=t;do isNaN(e.offsetTop)||(n+=e.offsetTop);while(e=e.offsetParent);return n},e.tooltip.findTotalOffsetLeft=function(e,t){var n=t;do isNaN(e.offsetLeft)||(n+=e.offsetLeft);while(e=e.offsetParent);return n},e.tooltip.calcTooltipPosition=function(t,n,r,i){var s=parseInt(i.offsetHeight),o=parseInt(i.offsetWidth),u=e.utils.windowSize().width,a=e.utils.windowSize().height,f=window.pageYOffset,l=window.pageXOffset,c,h;a=window.innerWidth>=document.body.scrollWidth?a:a-16,u=window.innerHeight>=document.body.scrollHeight?u:u-16,n=n||"s",r=r||20;var p=function(t){return e.tooltip.findTotalOffsetTop(t,h)},d=function(t){return e.tooltip.findTotalOffsetLeft(t,c)};switch(n){case"e":c=t[0]-o-r,h=t[1]-s/2;var v=d(i),m=p(i);v<l&&(c=t[0]+r>l?t[0]+r:l-v+c),m<f&&(h=f-m+h),m+s>f+a&&(h=f+a-m+h-s);break;case"w":c=t[0]+r,h=t[1]-s/2;var v=d(i),m=p(i);v+o>u&&(c=t[0]-o-r),m<f&&(h=f+5),m+s>f+a&&(h=f+a-m+h-s);break;case"n":c=t[0]-o/2-5,h=t[1]+r;var v=d(i),m=p(i);v<l&&(c=l+5),v+o>u&&(c=c-o/2+5),m+s>f+a&&(h=f+a-m+h-s);break;case"s":c=t[0]-o/2,h=t[1]-s-r;var v=d(i),m=p(i);v<l&&(c=l+5),v+o>u&&(c=c-o/2+5),f>m&&(h=f);break;case"none":c=t[0],h=t[1]-r;var v=d(i),m=p(i)}return i.style.left=c+"px",i.style.top=h+"px",i.style.opacity=1,i.style.position="absolute",i},e.tooltip.cleanup=function(){var e=document.getElementsByClassName("nvtooltip"),t=[];while(e.length)t.push(e[0]),e[0].style.transitionDelay="0 !important",e[0].style.opacity=0,e[0].className="nvtooltip-pending-removal";setTimeout(function(){while(t.length){var e=t.pop();e.parentNode.removeChild(e)}},500)}}(),e.utils.windowSize=function(){var e={width:640,height:480};return document.body&&document.body.offsetWidth&&(e.width=document.body.offsetWidth,e.height=document.body.offsetHeight),document.compatMode=="CSS1Compat"&&document.documentElement&&document.documentElement.offsetWidth&&(e.width=document.documentElement.offsetWidth,e.height=document.documentElement.offsetHeight),window.innerWidth&&window.innerHeight&&(e.width=window.innerWidth,e.height=window.innerHeight),e},e.utils.windowResize=function(e){if(e===undefined)return;var t=window.onresize;window.onresize=function(n){typeof t=="function"&&t(n),e(n)}},e.utils.getColor=function(t){return arguments.length?Object.prototype.toString.call(t)==="[object Array]"?function(e,n){return e.color||t[n%t.length]}:t:e.utils.defaultColor()},e.utils.defaultColor=function(){var e=d3.scale.category20().range();return function(t,n){return t.color||e[n%e.length]}},e.utils.customTheme=function(e,t,n){t=t||function(e){return e.key},n=n||d3.scale.category20().range();var r=n.length;return function(i,s){var o=t(i);return r||(r=n.length),typeof e[o]!="undefined"?typeof e[o]=="function"?e[o]():e[o]:n[--r]}},e.utils.pjax=function(t,n){function r(r){d3.html(r,function(r){var i=d3.select(n).node();i.parentNode.replaceChild(d3.select(r).select(n).node(),i),e.utils.pjax(t,n)})}d3.selectAll(t).on("click",function(){history.pushState(this.href,this.textContent,this.href),r(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&r(d3.event.state)})},e.utils.calcApproxTextWidth=function(e){if(typeof e.style=="function"&&typeof e.text=="function"){var t=parseInt(e.style("font-size").replace("px","")),n=e.text().length;return n*t*.5}return 0},e.utils.NaNtoZero=function(e){return typeof e!="number"||isNaN(e)||e===null||e===Infinity?0:e},e.utils.optionsFunc=function(e){return e&&d3.map(e).forEach(function(e,t){typeof this[e]=="function"&&this[e](t)}.bind(this)),this},e.models.axis=function(){"use strict";function m(e){return e.each(function(e){var i=d3.select(this),m=i.selectAll("g.nv-wrap.nv-axis").data([e]),g=m.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),y=g.append("g"),b=m.select("g");p!==null?t.ticks(p):(t.orient()=="top"||t.orient()=="bottom")&&t.ticks(Math.abs(s.range()[1]-s.range()[0])/100),b.transition().call(t),v=v||t.scale();var w=t.tickFormat();w==null&&(w=v.tickFormat());var E=b.selectAll("text.nv-axislabel").data([o||null]);E.exit().remove();switch(t.orient()){case"top":E.enter().append("text").attr("class","nv-axislabel");var S=s.range().length==2?s.range()[1]:s.range()[s.range().length-1]+(s.range()[1]-s.range()[0]);E.attr("text-anchor","middle").attr("y",0).attr("x",S/2);if(u){var x=m.selectAll("g.nv-axisMaxMin").data(s.domain());x.enter().append("g").attr("class","nv-axisMaxMin").append("text"),x.exit().remove(),x.attr("transform",function(e,t){return"translate("+s(e)+",0)"}).select("text").attr("dy","-0.5em").attr("y",-t.tickPadding()).attr("text-anchor","middle").text(function(e,t){var n=w(e);return(""+n).match("NaN")?"":n}),x.transition().attr("transform",function(e,t){return"translate("+s.range()[t]+",0)"})}break;case"bottom":var T=36,N=30,C=b.selectAll("g").select("text");if(f%360){C.each(function(e,t){var n=this.getBBox().width;n>N&&(N=n)});var k=Math.abs(Math.sin(f*Math.PI/180)),T=(k?k*N:N)+30;C.attr("transform",function(e,t,n){return"rotate("+f+" 0,0)"}).style("text-anchor",f%360>0?"start":"end")}E.enter().append("text").attr("class","nv-axislabel");var S=s.range().length==2?s.range()[1]:s.range()[s.range().length-1]+(s.range()[1]-s.range()[0]);E.attr("text-anchor","middle").attr("y",T).attr("x",S/2);if(u){var x=m.selectAll("g.nv-axisMaxMin").data([s.domain()[0],s.domain()[s.domain().length-1]]);x.enter().append("g").attr("class","nv-axisMaxMin").append("text"),x.exit().remove(),x.attr("transform",function(e,t){return"translate("+(s(e)+(h?s.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",t.tickPadding()).attr("transform",function(e,t,n){return"rotate("+f+" 0,0)"}).style("text-anchor",f?f%360>0?"start":"end":"middle").text(function(e,t){var n=w(e);return(""+n).match("NaN")?"":n}),x.transition().attr("transform",function(e,t){return"translate("+(s(e)+(h?s.rangeBand()/2:0))+",0)"})}c&&C.attr("transform",function(e,t){return"translate(0,"+(t%2==0?"0":"12")+")"});break;case"right":E.enter().append("text").attr("class","nv-axislabel"),E.style("text-anchor",l?"middle":"begin").attr("transform",l?"rotate(90)":"").attr("y",l?-Math.max(n.right,r)+12:-10).attr("x",l?s.range()[0]/2:t.tickPadding());if(u){var x=m.selectAll("g.nv-axisMaxMin").data(s.domain());x.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(e,t){return"translate(0,"+s(e)+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",t.tickPadding()).style("text-anchor","start").text(function(e,t){var n=w(e);return(""+n).match("NaN")?"":n}),x.transition().attr("transform",function(e,t){return"translate(0,"+s.range()[t]+")"}).select("text").style("opacity",1)}break;case"left":E.enter().append("text").attr("class","nv-axislabel"),E.style("text-anchor",l?"middle":"end").attr("transform",l?"rotate(-90)":"").attr("y",l?-Math.max(n.left,r)+d:-10).attr("x",l?-s.range()[0]/2:-t.tickPadding());if(u){var x=m.selectAll("g.nv-axisMaxMin").data(s.domain());x.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(e,t){return"translate(0,"+v(e)+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-t.tickPadding()).attr("text-anchor","end").text(function(e,t){var n=w(e);return(""+n).match("NaN")?"":n}),x.transition().attr("transform",function(e,t){return"translate(0,"+s.range()[t]+")"}).select("text").style("opacity",1)}}E.text(function(e){return e}),u&&(t.orient()==="left"||t.orient()==="right")&&(b.selectAll("g").each(function(e,t){d3.select(this).select("text").attr("opacity",1);if(s(e)<s.range()[1]+10||s(e)>s.range()[0]-10)(e>1e-10||e<-1e-10)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0)}),s.domain()[0]==s.domain()[1]&&s.domain()[0]==0&&m.selectAll("g.nv-axisMaxMin").style("opacity",function(e,t){return t?0:1}));if(u&&(t.orient()==="top"||t.orient()==="bottom")){var L=[];m.selectAll("g.nv-axisMaxMin").each(function(e,t){try{t?L.push(s(e)-this.getBBox().width-4):L.push(s(e)+this.getBBox().width+4)}catch(n){t?L.push(s(e)-4):L.push(s(e)+4)}}),b.selectAll("g").each(function(e,t){if(s(e)<L[0]||s(e)>L[1])e>1e-10||e<-1e-10?d3.select(this).remove():d3.select(this).select("text").remove()})}a&&b.selectAll(".tick").filter(function(e){return!parseFloat(Math.round(e.__data__*1e5)/1e6)&&e.__data__!==undefined}).classed("zero",!0),v=s.copy()}),m}var t=d3.svg.axis(),n={top:0,right:0,bottom:0,left:0},r=75,i=60,s=d3.scale.linear(),o=null,u=!0,a=!0,f=0,l=!0,c=!1,h=!1,p=null,d=12;t.scale(s).orient("bottom").tickFormat(function(e){return e});var v;return m.axis=t,d3.rebind(m,t,"orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"),d3.rebind(m,s,"domain","range","rangeBand","rangeBands"),m.options=e.utils.optionsFunc.bind(m),m.margin=function(e){return arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=typeof e.right!="undefined"?e.right:n.right,n.bottom=typeof e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof e.left!="undefined"?e.left:n.left,m):n},m.width=function(e){return arguments.length?(r=e,m):r},m.ticks=function(e){return arguments.length?(p=e,m):p},m.height=function(e){return arguments.length?(i=e,m):i},m.axisLabel=function(e){return arguments.length?(o=e,m):o},m.showMaxMin=function(e){return arguments.length?(u=e,m):u},m.highlightZero=function(e){return arguments.length?(a=e,m):a},m.scale=function(e){return arguments.length?(s=e,t.scale(s),h=typeof s.rangeBands=="function",d3.rebind(m,s,"domain","range","rangeBand","rangeBands"),m):s},m.rotateYLabel=function(e){return arguments.length?(l=e,m):l},m.rotateLabels=function(e){return arguments.length?(f=e,m):f},m.staggerLabels=function(e){return arguments.length?(c=e,m):c},m.axisLabelDistance=function(e){return arguments.length?(d=e,m):d},m},e.models.bullet=function(){"use strict";function m(e){return e.each(function(e,n){var p=c-t.left-t.right,m=h-t.top-t.bottom,g=d3.select(this),y=i.call(this,e,n).slice().sort(d3.descending),b=s.call(this,e,n).slice().sort(d3.descending),w=o.call(this,e,n).slice().sort(d3.descending),E=u.call(this,e,n).slice(),S=a.call(this,e,n).slice(),x=f.call(this,e,n).slice(),T=d3.scale.linear().domain(d3.extent(d3.merge([l,y]))).range(r?[p,0]:[0,p]),N=this.__chart__||d3.scale.linear().domain([0,Infinity]).range(T.range());this.__chart__=T;var C=d3.min(y),k=d3.max(y),L=y[1],A=g.selectAll("g.nv-wrap.nv-bullet").data([e]),O=A.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),M=O.append("g"),_=A.select("g");M.append("rect").attr("class","nv-range nv-rangeMax"),M.append("rect").attr("class","nv-range nv-rangeAvg"),M.append("rect").attr("class","nv-range nv-rangeMin"),M.append("rect").attr("class","nv-measure"),M.append("path").attr("class","nv-markerTriangle"),A.attr("transform","translate("+t.left+","+t.top+")");var D=function(e){return Math.abs(N(e)-N(0))},P=function(e){return Math.abs(T(e)-T(0))},H=function(e){return e<0?N(e):N(0)},B=function(e){return e<0?T(e):T(0)};_.select("rect.nv-rangeMax").attr("height",m).attr("width",P(k>0?k:C)).attr("x",B(k>0?k:C)).datum(k>0?k:C),_.select("rect.nv-rangeAvg").attr("height",m).attr("width",P(L)).attr("x",B(L)).datum(L),_.select("rect.nv-rangeMin").attr("height",m).attr("width",P(k)).attr("x",B(k)).attr("width",P(k>0?C:k)).attr("x",B(k>0?C:k)).datum(k>0?C:k),_.select("rect.nv-measure").style("fill",d).attr("height",m/3).attr("y",m/3).attr("width",w<0?T(0)-T(w[0]):T(w[0])-T(0)).attr("x",B(w)).on("mouseover",function(){v.elementMouseover({value:w[0],label:x[0]||"Current",pos:[T(w[0]),m/2]})}).on("mouseout",function(){v.elementMouseout({value:w[0],label:x[0]||"Current"})});var j=m/6;b[0]?_.selectAll("path.nv-markerTriangle").attr("transform",function(e){return"translate("+T(b[0])+","+m/2+")"}).attr("d","M0,"+j+"L"+j+","+ -j+" "+ -j+","+ -j+"Z").on("mouseover",function(){v.elementMouseover({value:b[0],label:S[0]||"Previous",pos:[T(b[0]),m/2]})}).on("mouseout",function(){v.elementMouseout({value:b[0],label:S[0]||"Previous"})}):_.selectAll("path.nv-markerTriangle").remove(),A.selectAll(".nv-range").on("mouseover",function(e,t){var n=E[t]||(t?t==1?"Mean":"Minimum":"Maximum");v.elementMouseover({value:e,label:n,pos:[T(e),m/2]})}).on("mouseout",function(e,t){var n=E[t]||(t?t==1?"Mean":"Minimum":"Maximum");v.elementMouseout({value:e,label:n})})}),m}var t={top:0,right:0,bottom:0,left:0},n="left",r=!1,i=function(e){return e.ranges},s=function(e){return e.markers},o=function(e){return e.measures},u=function(e){return e.rangeLabels?e.rangeLabels:[]},a=function(e){return e.markerLabels?e.markerLabels:[]},f=function(e){return e.measureLabels?e.measureLabels:[]},l=[0],c=380,h=30,p=null,d=e.utils.getColor(["#1f77b4"]),v=d3.dispatch("elementMouseover","elementMouseout");return m.dispatch=v,m.options=e.utils.optionsFunc.bind(m),m.orient=function(e){return arguments.length?(n=e,r=n=="right"||n=="bottom",m):n},m.ranges=function(e){return arguments.length?(i=e,m):i},m.markers=function(e){return arguments.length?(s=e,m):s},m.measures=function(e){return arguments.length?(o=e,m):o},m.forceX=function(e){return arguments.length?(l=e,m):l},m.width=function(e){return arguments.length?(c=e,m):c},m.height=function(e){return arguments.length?(h=e,m):h},m.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,m):t},m.tickFormat=function(e){return arguments.length?(p=e,m):p},m.color=function(t){return arguments.length?(d=e.utils.getColor(t),m):d},m},e.models.bulletChart=function(){"use strict";function m(e){return e.each(function(n,h){var g=d3.select(this),y=(a||parseInt(g.style("width"))||960)-i.left-i.right,b=f-i.top-i.bottom,w=this;m.update=function(){m(e)},m.container=this;if(!n||!s.call(this,n,h)){var E=g.selectAll(".nv-noData").data([p]);return E.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),E.attr("x",i.left+y/2).attr("y",18+i.top+b/2).text(function(e){return e}),m}g.selectAll(".nv-noData").remove();var S=s.call(this,n,h).slice().sort(d3.descending),x=o.call(this,n,h).slice().sort(d3.descending),T=u.call(this,n,h).slice().sort(d3.descending),N=g.selectAll("g.nv-wrap.nv-bulletChart").data([n]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-bulletWrap"),k.append("g").attr("class","nv-titles"),N.attr("transform","translate("+i.left+","+i.top+")");var A=d3.scale.linear().domain([0,Math.max(S[0],x[0],T[0])]).range(r?[y,0]:[0,y]),O=this.__chart__||d3.scale.linear().domain([0,Infinity]).range(A.range());this.__chart__=A;var M=function(e){return Math.abs(O(e)-O(0))},_=function(e){return Math.abs(A(e)-A(0))},D=k.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(f-i.top-i.bottom)/2+")");D.append("text").attr("class","nv-title").text(function(e){return e.title}),D.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(e){return e.subtitle}),t.width(y).height(b);var P=L.select(".nv-bulletWrap");d3.transition(P).call(t);var H=l||A.tickFormat(y/100),B=L.selectAll("g.nv-tick").data(A.ticks(y/50),function(e){return this.textContent||H(e)}),j=B.enter().append("g").attr("class","nv-tick").attr("transform",function(e){return"translate("+O(e)+",0)"}).style("opacity",1e-6);j.append("line").attr("y1",b).attr("y2",b*7/6),j.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",b*7/6).text(H);var F=d3.transition(B).attr("transform",function(e){return"translate("+A(e)+",0)"}).style("opacity",1);F.select("line").attr("y1",b).attr("y2",b*7/6),F.select("text").attr("y",b*7/6),d3.transition(B.exit()).attr("transform",function(e){return"translate("+A(e)+",0)"}).style("opacity",1e-6).remove(),d.on("tooltipShow",function(e){e.key=n.title,c&&v(e,w.parentNode)})}),d3.timer.flush(),m}var t=e.models.bullet(),n="left",r=!1,i={top:5,right:40,bottom:20,left:120},s=function(e){return e.ranges},o=function(e){return e.markers},u=function(e){return e.measures},a=null,f=55,l=null,c=!0,h=function(e,t,n,r,i){return"<h3>"+t+"</h3>"+"<p>"+n+"</p>"},p="No Data Available.",d=d3.dispatch("tooltipShow","tooltipHide"),v=function(t,n){var r=t.pos[0]+(n.offsetLeft||0)+i.left,s=t.pos[1]+(n.offsetTop||0)+i.top,o=h(t.key,t.label,t.value,t,m);e.tooltip.show([r,s],o,t.value<0?"e":"w",null,n)};return t.dispatch.on("elementMouseover.tooltip",function(e){d.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){d.tooltipHide(e)}),d.on("tooltipHide",function(){c&&e.tooltip.cleanup()}),m.dispatch=d,m.bullet=t,d3.rebind(m,t,"color"),m.options=e.utils.optionsFunc.bind(m),m.orient=function(e){return arguments.length?(n=e,r=n=="right"||n=="bottom",m):n},m.ranges=function(e){return arguments.length?(s=e,m):s},m.markers=function(e){return arguments.length?(o=e,m):o},m.measures=function(e){return arguments.length?(u=e,m):u},m.width=function(e){return arguments.length?(a=e,m):a},m.height=function(e){return arguments.length?(f=e,m):f},m.margin=function(e){return arguments.length?(i.top=typeof e.top!="undefined"?e.top:i.top,i.right=typeof e.right!="undefined"?e.right:i.right,i.bottom=typeof e.bottom!="undefined"?e.bottom:i.bottom,i.left=typeof e.left!="undefined"?e.left:i.left,m):i},m.tickFormat=function(e){return arguments.length?(l=e,m):l},m.tooltips=function(e){return arguments.length?(c=e,m):c},m.tooltipContent=function(e){return arguments.length?(h=e,m):h},m.noData=function(e){return arguments.length?(p=e,m):p},m},e.models.cumulativeLineChart=function(){"use strict";function D(b){return b.each(function(b){function q(e,t){d3.select(D.container).style("cursor","ew-resize")}function R(e,t){M.x=d3.event.x,M.i=Math.round(O.invert(M.x)),rt()}function U(e,t){d3.select(D.container).style("cursor","auto"),x.index=M.i,k.stateChange(x)}function rt(){nt.data([M]);var e=D.transitionDuration();D.transitionDuration(0),D.update(),D.transitionDuration(e)}var A=d3.select(this).classed("nv-chart-"+S,!0),H=this,B=(f||parseInt(A.style("width"))||960)-u.left-u.right,j=(l||parseInt(A.style("height"))||400)-u.top-u.bottom;D.update=function(){A.transition().duration(L).call(D)},D.container=this,x.disabled=b.map(function(e){return!!e.disabled});if(!T){var F;T={};for(F in x)x[F]instanceof Array?T[F]=x[F].slice(0):T[F]=x[F]}var I=d3.behavior.drag().on("dragstart",q).on("drag",R).on("dragend",U);if(!b||!b.length||!b.filter(function(e){return e.values.length}).length){var z=A.selectAll(".nv-noData").data([N]);return z.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),z.attr("x",u.left+B/2).attr("y",u.top+j/2).text(function(e){return e}),D}A.selectAll(".nv-noData").remove(),w=t.xScale(),E=t.yScale();if(!y){var W=b.filter(function(e){return!e.disabled}).map(function(e,n){var r=d3.extent(e.values,t.y());return r[0]<-0.95&&(r[0]=-0.95),[(r[0]-r[1])/(1+r[1]),(r[1]-r[0])/(1+r[0])]}),X=[d3.min(W,function(e){return e[0]}),d3.max(W,function(e){return e[1]})];t.yDomain(X)}else t.yDomain(null);O.domain([0,b[0].values.length-1]).range([0,B]).clamp(!0);var b=P(M.i,b),V=g?"none":"all",$=A.selectAll("g.nv-wrap.nv-cumulativeLine").data([b]),J=$.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),K=$.select("g");J.append("g").attr("class","nv-interactive"),J.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),J.append("g").attr("class","nv-y nv-axis"),J.append("g").attr("class","nv-background"),J.append("g").attr("class","nv-linesWrap").style("pointer-events",V),J.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),J.append("g").attr("class","nv-legendWrap"),J.append("g").attr("class","nv-controlsWrap"),c&&(i.width(B),K.select(".nv-legendWrap").datum(b).call(i),u.top!=i.height()&&(u.top=i.height(),j=(l||parseInt(A.style("height"))||400)-u.top-u.bottom),K.select(".nv-legendWrap").attr("transform","translate(0,"+ -u.top+")"));if(m){var Q=[{key:"Re-scale y-axis",disabled:!y}];s.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),K.select(".nv-controlsWrap").datum(Q).attr("transform","translate(0,"+ -u.top+")").call(s)}$.attr("transform","translate("+u.left+","+u.top+")"),d&&K.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)");var G=b.filter(function(e){return e.tempDisabled});$.select(".tempDisabled").remove(),G.length&&$.append("text").attr("class","tempDisabled").attr("x",B/2).attr("y","-.71em").style("text-anchor","end").text(G.map(function(e){return e.key}).join(", ")+" values cannot be calculated for this time period."),g&&(o.width(B).height(j).margin({left:u.left,top:u.top}).svgContainer(A).xScale(w),$.select(".nv-interactive").call(o)),J.select(".nv-background").append("rect"),K.select(".nv-background rect").attr("width",B).attr("height",j),t.y(function(e){return e.display.y}).width(B).height(j).color(b.map(function(e,t){return e.color||a(e,t)}).filter(function(e,t){return!b[t].disabled&&!b[t].tempDisabled}));var Y=K.select(".nv-linesWrap").datum(b.filter(function(e){return!e.disabled&&!e.tempDisabled}));Y.call(t),b.forEach(function(e,t){e.seriesIndex=t});var Z=b.filter(function(e){return!e.disabled&&!!C(e)}),et=K.select(".nv-avgLinesWrap").selectAll("line").data(Z,function(e){return e.key}),tt=function(e){var t=E(C(e));return t<0?0:t>j?j:t};et.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(e,n){return t.color()(e,e.seriesIndex)}).attr("x1",0).attr("x2",B).attr("y1",tt).attr("y2",tt),et.style("stroke-opacity",function(e){var t=E(C(e));return t<0||t>j?0:1}).attr("x1",0).attr("x2",B).attr("y1",tt).attr("y2",tt),et.exit().remove();var nt=Y.selectAll(".nv-indexLine").data([M]);nt.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(I),nt.attr("transform",function(e){return"translate("+O(e.i)+",0)"}).attr("height",j),h&&(n.scale(w).ticks(Math.min(b[0].values.length,B/70)).tickSize(-j,0),K.select(".nv-x.nv-axis").attr("transform","translate(0,"+E.range()[0]+")"),d3.transition(K.select(".nv-x.nv-axis")).call(n)),p&&(r.scale(E).ticks(j/36).tickSize(-B,0),d3.transition(K.select(".nv-y.nv-axis")).call(r)),K.select(".nv-background rect").on("click",function(){M.x=d3.mouse(this)[0],M.i=Math.round(O.invert(M.x)),x.index=M.i,k.stateChange(x),rt()}),t.dispatch.on("elementClick",function(e){M.i=e.pointIndex,M.x=O(M.i),x.index=M.i,k.stateChange(x),rt()}),s.dispatch.on("legendClick",function(e,t){e.disabled=!e.disabled,y=!e.disabled,x.rescaleY=y,k.stateChange(x),D.update()}),i.dispatch.on("stateChange",function(e){x.disabled=e.disabled,k.stateChange(x),D.update()}),o.dispatch.on("elementMousemove",function(i){t.clearHighlights();var s,f,l,c=[];b.filter(function(e,t){return e.seriesIndex=t,!e.disabled}).forEach(function(n,r){f=e.interactiveBisect(n.values,i.pointXValue,D.x()),t.highlightPoint(r,f,!0);var o=n.values[f];if(typeof o=="undefined")return;typeof s=="undefined"&&(s=o),typeof l=="undefined"&&(l=D.xScale()(D.x()(o,f))),c.push({key:n.key,value:D.y()(o,f),color:a(n,n.seriesIndex)})});if(c.length>2){var h=D.yScale().invert(i.mouseY),p=Math.abs(D.yScale().domain()[0]-D.yScale().domain()[1]),d=.03*p,m=e.nearestValueIndex(c.map(function(e){return e.value}),h,d);m!==null&&(c[m].highlight=!0)}var g=n.tickFormat()(D.x()(s,f),f);o.tooltip.position({left:l+u.left,top:i.mouseY+u.top}).chartContainer(H.parentNode).enabled(v).valueFormatter(function(e,t){return r.tickFormat()(e)}).data({value:g,series:c})(),o.renderGuideLine(l)}),o.dispatch.on("elementMouseout",function(e){k.tooltipHide(),t.clearHighlights()}),k.on("tooltipShow",function(e){v&&_(e,H.parentNode)}),k.on("changeState",function(e){typeof e.disabled!="undefined"&&(b.forEach(function(t,n){t.disabled=e.disabled[n]}),x.disabled=e.disabled),typeof e.index!="undefined"&&(M.i=e.index,M.x=O(M.i),x.index=e.index,nt.data([M])),typeof e.rescaleY!="undefined"&&(y=e.rescaleY),D.update()})}),D}function P(e,n){return n.map(function(n,r){if(!n.values)return n;var i=t.y()(n.values[e],e);return i<-0.95&&!A?(n.tempDisabled=!0,n):(n.tempDisabled=!1,n.values=
n.values.map(function(e,n){return e.display={y:(t.y()(e,n)-i)/(1+i)},e}),n)})}var t=e.models.line(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.interactiveGuideline(),u={top:30,right:30,bottom:50,left:60},a=e.utils.defaultColor(),f=null,l=null,c=!0,h=!0,p=!0,d=!1,v=!0,m=!0,g=!1,y=!0,b=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},w,E,S=t.id(),x={index:0,rescaleY:y},T=null,N="No Data Available.",C=function(e){return e.average},k=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),L=250,A=!1;n.orient("bottom").tickPadding(7),r.orient(d?"right":"left"),s.updateState(!1);var O=d3.scale.linear(),M={i:0,x:0},_=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=b(i.series.key,a,f,i,D);e.tooltip.show([o,u],l,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],k.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){k.tooltipHide(e)}),k.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),D.dispatch=k,D.lines=t,D.legend=i,D.xAxis=n,D.yAxis=r,D.interactiveLayer=o,d3.rebind(D,t,"defined","isArea","x","y","xScale","yScale","size","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","useVoronoi","id"),D.options=e.utils.optionsFunc.bind(D),D.margin=function(e){return arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof e.right!="undefined"?e.right:u.right,u.bottom=typeof e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof e.left!="undefined"?e.left:u.left,D):u},D.width=function(e){return arguments.length?(f=e,D):f},D.height=function(e){return arguments.length?(l=e,D):l},D.color=function(t){return arguments.length?(a=e.utils.getColor(t),i.color(a),D):a},D.rescaleY=function(e){return arguments.length?(y=e,D):y},D.showControls=function(e){return arguments.length?(m=e,D):m},D.useInteractiveGuideline=function(e){return arguments.length?(g=e,e===!0&&(D.interactive(!1),D.useVoronoi(!1)),D):g},D.showLegend=function(e){return arguments.length?(c=e,D):c},D.showXAxis=function(e){return arguments.length?(h=e,D):h},D.showYAxis=function(e){return arguments.length?(p=e,D):p},D.rightAlignYAxis=function(e){return arguments.length?(d=e,r.orient(e?"right":"left"),D):d},D.tooltips=function(e){return arguments.length?(v=e,D):v},D.tooltipContent=function(e){return arguments.length?(b=e,D):b},D.state=function(e){return arguments.length?(x=e,D):x},D.defaultState=function(e){return arguments.length?(T=e,D):T},D.noData=function(e){return arguments.length?(N=e,D):N},D.average=function(e){return arguments.length?(C=e,D):C},D.transitionDuration=function(e){return arguments.length?(L=e,D):L},D.noErrorCheck=function(e){return arguments.length?(A=e,D):A},D},e.models.discreteBar=function(){"use strict";function E(e){return e.each(function(e){var i=n-t.left-t.right,E=r-t.top-t.bottom,S=d3.select(this);e.forEach(function(e,t){e.values.forEach(function(e){e.series=t})});var T=p&&d?[]:e.map(function(e){return e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0}})});s.domain(p||d3.merge(T).map(function(e){return e.x})).rangeBands(v||[0,i],.1),o.domain(d||d3.extent(d3.merge(T).map(function(e){return e.y}).concat(f))),c?o.range(m||[E-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]):o.range(m||[E,0]),b=b||s,w=w||o.copy().range([o(0),o(0)]);var N=S.selectAll("g.nv-wrap.nv-discretebar").data([e]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-groups"),N.attr("transform","translate("+t.left+","+t.top+")");var A=N.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),A.exit().transition().style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),A.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}),A.transition().style("stroke-opacity",1).style("fill-opacity",.75);var O=A.selectAll("g.nv-bar").data(function(e){return e.values});O.exit().remove();var M=O.enter().append("g").attr("transform",function(e,t,n){return"translate("+(s(u(e,t))+s.rangeBand()*.05)+", "+o(0)+")"}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),g.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),g.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){g.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){g.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()});M.append("rect").attr("height",0).attr("width",s.rangeBand()*.9/e.length),c?(M.append("text").attr("text-anchor","middle"),O.select("text").text(function(e,t){return h(a(e,t))}).transition().attr("x",s.rangeBand()*.9/2).attr("y",function(e,t){return a(e,t)<0?o(a(e,t))-o(0)+12:-4})):O.selectAll("text").remove(),O.attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(e,t){return e.color||l(e,t)}).style("stroke",function(e,t){return e.color||l(e,t)}).select("rect").attr("class",y).transition().attr("width",s.rangeBand()*.9/e.length),O.transition().attr("transform",function(e,t){var n=s(u(e,t))+s.rangeBand()*.05,r=a(e,t)<0?o(0):o(0)-o(a(e,t))<1?o(0)-1:o(a(e,t));return"translate("+n+", "+r+")"}).select("rect").attr("height",function(e,t){return Math.max(Math.abs(o(a(e,t))-o(d&&d[0]||0))||1)}),b=s.copy(),w=o.copy()}),E}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.ordinal(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=[0],l=e.utils.defaultColor(),c=!1,h=d3.format(",.2f"),p,d,v,m,g=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),y="discreteBar",b,w;return E.dispatch=g,E.options=e.utils.optionsFunc.bind(E),E.x=function(e){return arguments.length?(u=e,E):u},E.y=function(e){return arguments.length?(a=e,E):a},E.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,E):t},E.width=function(e){return arguments.length?(n=e,E):n},E.height=function(e){return arguments.length?(r=e,E):r},E.xScale=function(e){return arguments.length?(s=e,E):s},E.yScale=function(e){return arguments.length?(o=e,E):o},E.xDomain=function(e){return arguments.length?(p=e,E):p},E.yDomain=function(e){return arguments.length?(d=e,E):d},E.xRange=function(e){return arguments.length?(v=e,E):v},E.yRange=function(e){return arguments.length?(m=e,E):m},E.forceY=function(e){return arguments.length?(f=e,E):f},E.color=function(t){return arguments.length?(l=e.utils.getColor(t),E):l},E.id=function(e){return arguments.length?(i=e,E):i},E.showValues=function(e){return arguments.length?(c=e,E):c},E.valueFormat=function(e){return arguments.length?(h=e,E):h},E.rectClass=function(e){return arguments.length?(y=e,E):y},E},e.models.discreteBarChart=function(){"use strict";function w(e){return e.each(function(e){var u=d3.select(this),p=this,E=(s||parseInt(u.style("width"))||960)-i.left-i.right,S=(o||parseInt(u.style("height"))||400)-i.top-i.bottom;w.update=function(){g.beforeUpdate(),u.transition().duration(y).call(w)},w.container=this;if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var T=u.selectAll(".nv-noData").data([m]);return T.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),T.attr("x",i.left+E/2).attr("y",i.top+S/2).text(function(e){return e}),w}u.selectAll(".nv-noData").remove(),d=t.xScale(),v=t.yScale().clamp(!0);var N=u.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([e]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),k=C.append("defs"),L=N.select("g");C.append("g").attr("class","nv-x nv-axis"),C.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),C.append("g").attr("class","nv-barsWrap"),L.attr("transform","translate("+i.left+","+i.top+")"),l&&L.select(".nv-y.nv-axis").attr("transform","translate("+E+",0)"),t.width(E).height(S);var A=L.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));A.transition().call(t),k.append("clipPath").attr("id","nv-x-label-clip-"+t.id()).append("rect"),L.select("#nv-x-label-clip-"+t.id()+" rect").attr("width",d.rangeBand()*(c?2:1)).attr("height",16).attr("x",-d.rangeBand()/(c?1:2));if(a){n.scale(d).ticks(E/100).tickSize(-S,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+(v.range()[0]+(t.showValues()&&v.domain()[0]<0?16:0))+")"),L.select(".nv-x.nv-axis").transition().call(n);var O=L.select(".nv-x.nv-axis").selectAll("g");c&&O.selectAll("text").attr("transform",function(e,t,n){return"translate(0,"+(n%2==0?"5":"17")+")"})}f&&(r.scale(v).ticks(S/36).tickSize(-E,0),L.select(".nv-y.nv-axis").transition().call(r)),L.select(".nv-zeroLine line").attr("x1",0).attr("x2",E).attr("y1",v(0)).attr("y2",v(0)),g.on("tooltipShow",function(e){h&&b(e,p.parentNode)})}),w}var t=e.models.discreteBar(),n=e.models.axis(),r=e.models.axis(),i={top:15,right:10,bottom:50,left:60},s=null,o=null,u=e.utils.getColor(),a=!0,f=!0,l=!1,c=!1,h=!0,p=function(e,t,n,r,i){return"<h3>"+t+"</h3>"+"<p>"+n+"</p>"},d,v,m="No Data Available.",g=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate"),y=250;n.orient("bottom").highlightZero(!1).showMaxMin(!1).tickFormat(function(e){return e}),r.orient(l?"right":"left").tickFormat(d3.format(",.1f"));var b=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=p(i.series.key,a,f,i,w);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+i.left,e.pos[1]+i.top],g.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){g.tooltipHide(e)}),g.on("tooltipHide",function(){h&&e.tooltip.cleanup()}),w.dispatch=g,w.discretebar=t,w.xAxis=n,w.yAxis=r,d3.rebind(w,t,"x","y","xDomain","yDomain","xRange","yRange","forceX","forceY","id","showValues","valueFormat"),w.options=e.utils.optionsFunc.bind(w),w.margin=function(e){return arguments.length?(i.top=typeof e.top!="undefined"?e.top:i.top,i.right=typeof e.right!="undefined"?e.right:i.right,i.bottom=typeof e.bottom!="undefined"?e.bottom:i.bottom,i.left=typeof e.left!="undefined"?e.left:i.left,w):i},w.width=function(e){return arguments.length?(s=e,w):s},w.height=function(e){return arguments.length?(o=e,w):o},w.color=function(n){return arguments.length?(u=e.utils.getColor(n),t.color(u),w):u},w.showXAxis=function(e){return arguments.length?(a=e,w):a},w.showYAxis=function(e){return arguments.length?(f=e,w):f},w.rightAlignYAxis=function(e){return arguments.length?(l=e,r.orient(e?"right":"left"),w):l},w.staggerLabels=function(e){return arguments.length?(c=e,w):c},w.tooltips=function(e){return arguments.length?(h=e,w):h},w.tooltipContent=function(e){return arguments.length?(p=e,w):p},w.noData=function(e){return arguments.length?(m=e,w):m},w.transitionDuration=function(e){return arguments.length?(y=e,w):y},w},e.models.distribution=function(){"use strict";function l(e){return e.each(function(e){var a=n-(i==="x"?t.left+t.right:t.top+t.bottom),l=i=="x"?"y":"x",c=d3.select(this);f=f||u;var h=c.selectAll("g.nv-distribution").data([e]),p=h.enter().append("g").attr("class","nvd3 nv-distribution"),d=p.append("g"),v=h.select("g");h.attr("transform","translate("+t.left+","+t.top+")");var m=v.selectAll("g.nv-dist").data(function(e){return e},function(e){return e.key});m.enter().append("g"),m.attr("class",function(e,t){return"nv-dist nv-series-"+t}).style("stroke",function(e,t){return o(e,t)});var g=m.selectAll("line.nv-dist"+i).data(function(e){return e.values});g.enter().append("line").attr(i+"1",function(e,t){return f(s(e,t))}).attr(i+"2",function(e,t){return f(s(e,t))}),m.exit().selectAll("line.nv-dist"+i).transition().attr(i+"1",function(e,t){return u(s(e,t))}).attr(i+"2",function(e,t){return u(s(e,t))}).style("stroke-opacity",0).remove(),g.attr("class",function(e,t){return"nv-dist"+i+" nv-dist"+i+"-"+t}).attr(l+"1",0).attr(l+"2",r),g.transition().attr(i+"1",function(e,t){return u(s(e,t))}).attr(i+"2",function(e,t){return u(s(e,t))}),f=u.copy()}),l}var t={top:0,right:0,bottom:0,left:0},n=400,r=8,i="x",s=function(e){return e[i]},o=e.utils.defaultColor(),u=d3.scale.linear(),a,f;return l.options=e.utils.optionsFunc.bind(l),l.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,l):t},l.width=function(e){return arguments.length?(n=e,l):n},l.axis=function(e){return arguments.length?(i=e,l):i},l.size=function(e){return arguments.length?(r=e,l):r},l.getData=function(e){return arguments.length?(s=d3.functor(e),l):s},l.scale=function(e){return arguments.length?(u=e,l):u},l.color=function(t){return arguments.length?(o=e.utils.getColor(t),l):o},l},e.models.historicalBar=function(){"use strict";function w(E){return E.each(function(w){var E=n-t.left-t.right,S=r-t.top-t.bottom,T=d3.select(this);s.domain(d||d3.extent(w[0].values.map(u).concat(f))),c?s.range(m||[E*.5/w[0].values.length,E*(w[0].values.length-.5)/w[0].values.length]):s.range(m||[0,E]),o.domain(v||d3.extent(w[0].values.map(a).concat(l))).range(g||[S,0]),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]-s.domain()[0]*.01,s.domain()[1]+s.domain()[1]*.01]):s.domain([-1,1])),o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]+o.domain()[0]*.01,o.domain()[1]-o.domain()[1]*.01]):o.domain([-1,1]));var N=T.selectAll("g.nv-wrap.nv-historicalBar-"+i).data([w[0].values]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+i),k=C.append("defs"),L=C.append("g"),A=N.select("g");L.append("g").attr("class","nv-bars"),N.attr("transform","translate("+t.left+","+t.top+")"),T.on("click",function(e,t){y.chartClick({data:e,index:t,pos:d3.event,id:i})}),k.append("clipPath").attr("id","nv-chart-clip-path-"+i).append("rect"),N.select("#nv-chart-clip-path-"+i+" rect").attr("width",E).attr("height",S),A.attr("clip-path",h?"url(#nv-chart-clip-path-"+i+")":"");var O=N.select(".nv-bars").selectAll(".nv-bar").data(function(e){return e},function(e,t){return u(e,t)});O.exit().remove();var M=O.enter().append("rect").attr("x",0).attr("y",function(t,n){return e.utils.NaNtoZero(o(Math.max(0,a(t,n))))}).attr("height",function(t,n){return e.utils.NaNtoZero(Math.abs(o(a(t,n))-o(0)))}).attr("transform",function(e,t){return"translate("+(s(u(e,t))-E/w[0].values.length*.45)+",0)"}).on("mouseover",function(e,t){if(!b)return;d3.select(this).classed("hover",!0),y.elementMouseover({point:e,series:w[0],pos:[s(u(e,t)),o(a(e,t))],pointIndex:t,seriesIndex:0,e:d3.event})}).on("mouseout",function(e,t){if(!b)return;d3.select(this).classed("hover",!1),y.elementMouseout({point:e,series:w[0],pointIndex:t,seriesIndex:0,e:d3.event})}).on("click",function(e,t){if(!b)return;y.elementClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()}).on("dblclick",function(e,t){if(!b)return;y.elementDblClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()});O.attr("fill",function(e,t){return p(e,t)}).attr("class",function(e,t,n){return(a(e,t)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+n+"-"+t}).transition().attr("transform",function(e,t){return"translate("+(s(u(e,t))-E/w[0].values.length*.45)+",0)"}).attr("width",E/w[0].values.length*.9),O.transition().attr("y",function(t,n){var r=a(t,n)<0?o(0):o(0)-o(a(t,n))<1?o(0)-1:o(a(t,n));return e.utils.NaNtoZero(r)}).attr("height",function(t,n){return e.utils.NaNtoZero(Math.max(Math.abs(o(a(t,n))-o(0)),1))})}),w}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=[],l=[0],c=!1,h=!0,p=e.utils.defaultColor(),d,v,m,g,y=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),b=!0;return w.highlightPoint=function(e,t){d3.select(".nv-historicalBar-"+i).select(".nv-bars .nv-bar-0-"+e).classed("hover",t)},w.clearHighlights=function(){d3.select(".nv-historicalBar-"+i).select(".nv-bars .nv-bar.hover").classed("hover",!1)},w.dispatch=y,w.options=e.utils.optionsFunc.bind(w),w.x=function(e){return arguments.length?(u=e,w):u},w.y=function(e){return arguments.length?(a=e,w):a},w.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,w):t},w.width=function(e){return arguments.length?(n=e,w):n},w.height=function(e){return arguments.length?(r=e,w):r},w.xScale=function(e){return arguments.length?(s=e,w):s},w.yScale=function(e){return arguments.length?(o=e,w):o},w.xDomain=function(e){return arguments.length?(d=e,w):d},w.yDomain=function(e){return arguments.length?(v=e,w):v},w.xRange=function(e){return arguments.length?(m=e,w):m},w.yRange=function(e){return arguments.length?(g=e,w):g},w.forceX=function(e){return arguments.length?(f=e,w):f},w.forceY=function(e){return arguments.length?(l=e,w):l},w.padData=function(e){return arguments.length?(c=e,w):c},w.clipEdge=function(e){return arguments.length?(h=e,w):h},w.color=function(t){return arguments.length?(p=e.utils.getColor(t),w):p},w.id=function(e){return arguments.length?(i=e,w):i},w.interactive=function(e){return arguments.length?(b=!1,w):b},w},e.models.historicalBarChart=function(){"use strict";function x(e){return e.each(function(d){var T=d3.select(this),N=this,C=(u||parseInt(T.style("width"))||960)-s.left-s.right,k=(a||parseInt(T.style("height"))||400)-s.top-s.bottom;x.update=function(){T.transition().duration(E).call(x)},x.container=this,g.disabled=d.map(function(e){return!!e.disabled});if(!y){var L;y={};for(L in g)g[L]instanceof Array?y[L]=g[L].slice(0):y[L]=g[L]}if(!d||!d.length||!d.filter(function(e){return e.values.length}).length){var A=T.selectAll(".nv-noData").data([b]);return A.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),A.attr("x",s.left+C/2).attr("y",s.top+k/2).text(function(e){return e}),x}T.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale();var O=T.selectAll("g.nv-wrap.nv-historicalBarChart").data([d]),M=O.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),_=O.select("g");M.append("g").attr("class","nv-x nv-axis"),M.append("g").attr("class","nv-y nv-axis"),M.append("g").attr("class","nv-barsWrap"),M.append("g").attr("class","nv-legendWrap"),f&&(i.width(C),_.select(".nv-legendWrap").datum(d).call(i),s.top!=i.height()&&(s.top=i.height(),k=(a||parseInt(T.style("height"))||400)-s.top-s.bottom),O.select(".nv-legendWrap").attr("transform","translate(0,"+ -s.top+")")),O.attr("transform","translate("+s.left+","+s.top+")"),h&&_.select(".nv-y.nv-axis").attr("transform","translate("+C+",0)"),t.width(C).height(k).color(d.map(function(e,t){return e.color||o(e,t)}).filter(function(e,t){return!d[t].disabled}));var D=_.select(".nv-barsWrap").datum(d.filter(function(e){return!e.disabled}));D.transition().call(t),l&&(n.scale(v).tickSize(-k,0),_.select(".nv-x.nv-axis").attr("transform","translate(0,"+m.range()[0]+")"),_.select(".nv-x.nv-axis").transition().call(n)),c&&(r.scale(m).ticks(k/36).tickSize(-C,0),_.select(".nv-y.nv-axis").transition().call(r)),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,d.filter(function(e){return!e.disabled}).length||d.map(function(e){return e.disabled=!1,O.selectAll(".nv-series").classed("disabled",!1),e}),g.disabled=d.map(function(e){return!!e.disabled}),w.stateChange(g),e.transition().call(x)}),i.dispatch.on("legendDblclick",function(e){d.forEach(function(e){e.disabled=!0}),e.disabled=!1,g.disabled=d.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),w.on("tooltipShow",function(e){p&&S(e,N.parentNode)}),w.on("changeState",function(e){typeof e.disabled!="undefined"&&(d.forEach(function(t,n){t.disabled=e.disabled[n]}),g.disabled=e.disabled),x.update()})}),x}var t=e.models.historicalBar(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s={top:30,right:90,bottom:50,left:90},o=e.utils.defaultColor(),u=null,a=null,f=!1,l=!0,c=!0,h=!1,p=!0,d=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},v,m,g={},y=null,b="No Data Available.",w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),E=250;n.orient("bottom").tickPadding(7),r.orient(h?"right":"left");var S=function(i,s){if(s){var o=d3.select(s).select("svg"),u=o.node()?o.attr("viewBox"):null;if(u){u=u.split(" ");var a=parseInt(o.style("width"))/u[2];i.pos[0]=i.pos[0]*a,i.pos[1]=i.pos[1]*a}}var f=i.pos[0]+(s.offsetLeft||0),l=i.pos[1]+(s.offsetTop||0),c=n.tickFormat()(t.x()(i.point,i.pointIndex)),h=r.tickFormat()(t.y()(i.point,i.pointIndex)),p=d(i.series.key,c,h,i,x);e.tooltip.show([f,l],p,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+s.left,e.pos[1]+s.top],w.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){w.tooltipHide(e)}),w.on("tooltipHide",function(){p&&e.tooltip.cleanup()}),x.dispatch=w,x.bars=t,x.legend=i,x.xAxis=n,x.yAxis=r,d3.rebind(x,t,"defined","isArea","x","y","size","xScale","yScale","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","id","interpolate","highlightPoint","clearHighlights","interactive"),x.options=e.utils.optionsFunc.bind(x),x.margin=function(e){return arguments.length?(s.top=typeof e.top!="undefined"?e.top:s.top,s.right=typeof e.right!="undefined"?e.right:s.right,s.bottom=typeof e.bottom!="undefined"?e.bottom:s.bottom,s.left=typeof e.left!="undefined"?e.left:s.left,x):s},x.width=function(e){return arguments.length?(u=e,x):u},x.height=function(e){return arguments.length?(a=e,x):a},x.color=function(t){return arguments.length?(o=e.utils.getColor(t),i.color(o),x):o},x.showLegend=function(e){return arguments.length?(f=e,x):f},x.showXAxis=function(e){return arguments.length?(l=e,x):l},x.showYAxis=function(e){return arguments.length?(c=e,x):c},x.rightAlignYAxis=function(e){return arguments.length?(h=e,r.orient(e?"right":"left"),x):h},x.tooltips=function(e){return arguments.length?(p=e,x):p},x.tooltipContent=function(e){return arguments.length?(d=e,x):d},x.state=function(e){return arguments.length?(g=e,x):g},x.defaultState=function(e){return arguments.length?(y=e,x):y},x.noData=function(e){return arguments.length?(b=e,x):b},x.transitionDuration=function(e){return arguments.length?(E=e,x):E},x},e.models.indentedTree=function(){"use strict";function g(e){return e.each(function(e){function k(e,t,n){d3.event.stopPropagation();if(d3.event.shiftKey&&!n)return d3.event.shiftKey=!1,e.values&&e.values.forEach(function(e){(e.values||e._values)&&k(e,0,!0)}),!0;if(!O(e))return!0;e.values?(e._values=e.values,e.values=null):(e.values=e._values,e._values=null),g.update()}function L(e){return e._values&&e._values.length?h:e.values&&e.values.length?p:""}function A(e){return e._values&&e._values.length}function O(e){var t=e.values||e._values;return t&&t.length}var t=1,n=d3.select(this),i=d3.layout.tree().children(function(e){return e.values}).size([r,f]);g.update=function(){n.transition().duration(600).call(g)},e[0]||(e[0]={key:a});var s=i.nodes(e[0]),y=d3.select(this).selectAll("div").data([[s]]),b=y.enter().append("div").attr("class","nvd3 nv-wrap nv-indentedtree"),w=b.append("table"),E=y.select("table").attr("width","100%").attr("class",c);if(o){var S=w.append("thead"),x=S.append("tr");l.forEach(function(e){x.append("th").attr("width",e.width?e.width:"10%").style("text-align",e.type=="numeric"?"right":"left").append("span").text(e.label)})}var T=E.selectAll("tbody").data(function(e){return e});T.enter().append("tbody"),t=d3.max(s,function(e){return e.depth}),i.size([r,t*f]);var N=T.selectAll("tr").data(function(e){return e.filter(function(e){return u&&!e.children?u(e):!0})},function(e,t){return e.id||e.id||++m});N.exit().remove(),N.select("img.nv-treeicon").attr("src",L).classed("folded",A);var C=N.enter().append("tr");l.forEach(function(e,t){var n=C.append("td").style("padding-left",function(e){return(t?0:e.depth*f+12+(L(e)?0:16))+"px"},"important").style("text-align",e.type=="numeric"?"right":"left");t==0&&n.append("img").classed("nv-treeicon",!0).classed("nv-folded",A).attr("src",L).style("width","14px").style("height","14px").style("padding","0 1px").style("display",function(e){return L(e)?"inline-block":"none"}).on("click",k),n.each(function(n){!t&&v(n)?d3.select(this).append("a").attr("href",v).attr("class",d3.functor(e.classes)).append("span"):d3.select(this).append("span"),d3.select(this).select("span").attr("class",d3.functor(e.classes)).text(function(t){return e.format?e.format(t):t[e.key]||"-"})}),e.showCount&&(n.append("span").attr("class","nv-childrenCount"),N.selectAll("span.nv-childrenCount").text(function(e){return e.values&&e.values.length||e._values&&e._values.length?"("+(e.values&&e.values.filter(function(e){return u?u(e):!0}).length||e._values&&e._values.filter(function(e){return u?u(e):!0}).length||0)+")":""}))}),N.order().on("click",function(e){d.elementClick({row:this,data:e,pos:[e.x,e.y]})}).on("dblclick",function(e){d.elementDblclick({row:this,data:e,pos:[e.x,e.y]})}).on("mouseover",function(e){d.elementMouseover({row:this,data:e,pos:[e.x,e.y]})}).on("mouseout",function(e){d.elementMouseout({row:this,data:e,pos:[e.x,e.y]})})}),g}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e4),o=!0,u=!1,a="No Data Available.",f=20,l=[{key:"key",label:"Name",type:"text"}],c=null,h="images/grey-plus.png",p="images/grey-minus.png",d=d3.dispatch("elementClick","elementDblclick","elementMouseover","elementMouseout"),v=function(e){return e.url},m=0;return g.options=e.utils.optionsFunc.bind(g),g.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,g):t},g.width=function(e){return arguments.length?(n=e,g):n},g.height=function(e){return arguments.length?(r=e,g):r},g.color=function(t){return arguments.length?(i=e.utils.getColor(t),scatter.color(i),g):i},g.id=function(e){return arguments.length?(s=e,g):s},g.header=function(e){return arguments.length?(o=e,g):o},g.noData=function(e){return arguments.length?(a=e,g):a},g.filterZero=function(e){return arguments.length?(u=e,g):u},g.columns=function(e){return arguments.length?(l=e,g):l},g.tableClass=function(e){return arguments.length?(c=e,g):c},g.iconOpen=function(e){return arguments.length?(h=e,g):h},g.iconClose=function(e){return arguments.length?(p=e,g):p},g.getUrl=function(e){return arguments.length?(v=e,g):v},g},e.models.legend=function(){"use strict";function c(h){return h.each(function(c){var h=n-t.left-t.right,p=d3.select(this),d=p.selectAll("g.nv-legend").data([c]),v=d.enter().append("g").attr("class","nvd3 nv-legend").append("g"),m=d.select("g");d.attr("transform","translate("+t.left+","+t.top+")");var g=m.selectAll(".nv-series").data(function(e){return e}),y=g.enter().append("g").attr("class","nv-series").on("mouseover",function(e,t){l.legendMouseover(e,t)}).on("mouseout",function(e,t){l.legendMouseout(e,t)}).on("click",function(e,t){l.legendClick(e,t),a&&(f?(c.forEach(function(e){e.disabled=!0}),e.disabled=!1):(e.disabled=!e.disabled,c.every(function(e){return e.disabled})&&c.forEach(function(e){e.disabled=!1})),l.stateChange({disabled:c.map(function(e){return!!e.disabled})}))}).on("dblclick",function(e,t){l.legendDblclick(e,t),a&&(c.forEach(function(e){e.disabled=!0}),e.disabled=!1,l.stateChange({disabled:c.map(function(e){return!!e.disabled})}))});y.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),y.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8"),g.classed("disabled",function(e){return e.disabled}),g.exit().remove(),g.select("circle").style("fill",function(e,t){return e.color||s(e,t)}).style("stroke",function(e,t){return e.color||s(e,t)}),g.select("text").text(i);if(o){var b=[];g.each(function(t,n){var r=d3.select(this).select("text"),i;try{i=r.getComputedTextLength();if(i<=0)throw Error()}catch(s){i=e.utils.calcApproxTextWidth(r)}b.push(i+28)});var w=0,E=0,S=[];while(E<h&&w<b.length)S[w]=b[w],E+=b[w++];w===0&&(w=1);while(E>h&&w>1){S=[],w--;for(var x=0;x<b.length;x++)b[x]>(S[x%w]||0)&&(S[x%w]=b[x]);E=S.reduce(function(e,t,n,r){return e+t})}var T=[];for(var N=0,C=0;N<w;N++)T[N]=C,C+=S[N];g.attr("transform",function(e,t){return"translate("+T[t%w]+","+(5+Math.floor(t/w)*20)+")"}),u?m.attr("transform","translate("+(n-t.right-E)+","+t.top+")"):m.attr("transform","translate(0,"+t.top+")"),r=t.top+t.bottom+Math.ceil(b.length/w)*20}else{var k=5,L=5,A=0,O;g.attr("transform",function(e,r){var i=d3.select(this).select("text").node().getComputedTextLength()+28;return O=L,n<t.left+t.right+O+i&&(L=O=5,k+=20),L+=i,L>A&&(A=L),"translate("+O+","+k+")"}),m.attr("transform","translate("+(n-t.right-A)+","+t.top+")"),r=t.top+t.bottom+k+15}}),c}var t={top:5,right:0,bottom:5,left:0},n=400,r=20,i=function(e){return e.key},s=e.utils.defaultColor(),o=!0,u=!0,a=!0,f=!1,l=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange");return c.dispatch=l,c.options=e.utils.optionsFunc.bind(c),c.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,c):t},c.width=function(e){return arguments.length?(n=e,c):n},c.height=function(e){return arguments.length?(r=e,c):r},c.key=function(e){return arguments.length?(i=e,c):i},c.color=function(t){return arguments.length?(s=e.utils.getColor(t),c):s},c.align=function(e){return arguments.length?(o=e,c):o},c.rightAlign=function(e){return arguments.length?(u=e,c):u},c.updateState=function(e){return arguments.length?(a=e,c):a},c.radioButtonMode=function(e){return arguments.length?(f=e,c):f},c},e.models.line=function(){"use strict";function m(g){return g.each(function(m){var g=r-n.left-n.right,b=i-n.top-n.bottom,w=d3.select(this);c=t.xScale(),h=t.yScale(),d=d||c,v=v||h;var E=w.selectAll("g.nv-wrap.nv-line").data([m]),S=E.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),T=S.append("defs"),N=S.append("g"),C=E.select("g");N.append("g").attr("class","nv-groups"),N.append("g").attr("class","nv-scatterWrap"),E.attr("transform","translate("+n.left+","+n.top+")"),t.width(g).height(b);var k=E.select(".nv-scatterWrap");k.transition().call(t),T.append("clipPath").attr("id","nv-edge-clip-"+t.id()).append("rect"),E.select("#nv-edge-clip-"+t.id()+" rect").attr("width",g).attr("height",b),C.attr("clip-path",l?"url(#nv-edge-clip-"+t.id()+")":""),k.attr("clip-path",l?"url(#nv-edge-clip-"+t.id()+")":"");var L=E.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});L.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),L.exit().remove(),L.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}).style("fill",function(e,t){return s(e,t)}).style("stroke",function(e,t){return s(e,t)}),L.transition().style("stroke-opacity",1).style("fill-opacity",.5);var A=L.selectAll("path.nv-area").data(function(e){return f(e)?[e]:[]});A.enter().append("path").attr("class","nv-area").attr("d",function(t){return d3.svg.area().interpolate(p).defined(a).x(function(t,n){return e.
utils.NaNtoZero(d(o(t,n)))}).y0(function(t,n){return e.utils.NaNtoZero(v(u(t,n)))}).y1(function(e,t){return v(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[t.values])}),L.exit().selectAll("path.nv-area").remove(),A.transition().attr("d",function(t){return d3.svg.area().interpolate(p).defined(a).x(function(t,n){return e.utils.NaNtoZero(c(o(t,n)))}).y0(function(t,n){return e.utils.NaNtoZero(h(u(t,n)))}).y1(function(e,t){return h(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[t.values])});var O=L.selectAll("path.nv-line").data(function(e){return[e.values]});O.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(p).defined(a).x(function(t,n){return e.utils.NaNtoZero(d(o(t,n)))}).y(function(t,n){return e.utils.NaNtoZero(v(u(t,n)))})),O.transition().attr("d",d3.svg.line().interpolate(p).defined(a).x(function(t,n){return e.utils.NaNtoZero(c(o(t,n)))}).y(function(t,n){return e.utils.NaNtoZero(h(u(t,n)))})),d=c.copy(),v=h.copy()}),m}var t=e.models.scatter(),n={top:0,right:0,bottom:0,left:0},r=960,i=500,s=e.utils.defaultColor(),o=function(e){return e.x},u=function(e){return e.y},a=function(e,t){return!isNaN(u(e,t))&&u(e,t)!==null},f=function(e){return e.area},l=!1,c,h,p="linear";t.size(16).sizeDomain([16,256]);var d,v;return m.dispatch=t.dispatch,m.scatter=t,d3.rebind(m,t,"id","interactive","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","forceX","forceY","forceSize","clipVoronoi","useVoronoi","clipRadius","padData","highlightPoint","clearHighlights"),m.options=e.utils.optionsFunc.bind(m),m.margin=function(e){return arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=typeof e.right!="undefined"?e.right:n.right,n.bottom=typeof e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof e.left!="undefined"?e.left:n.left,m):n},m.width=function(e){return arguments.length?(r=e,m):r},m.height=function(e){return arguments.length?(i=e,m):i},m.x=function(e){return arguments.length?(o=e,t.x(e),m):o},m.y=function(e){return arguments.length?(u=e,t.y(e),m):u},m.clipEdge=function(e){return arguments.length?(l=e,m):l},m.color=function(n){return arguments.length?(s=e.utils.getColor(n),t.color(s),m):s},m.interpolate=function(e){return arguments.length?(p=e,m):p},m.defined=function(e){return arguments.length?(a=e,m):a},m.isArea=function(e){return arguments.length?(f=d3.functor(e),m):f},m},e.models.lineChart=function(){"use strict";function N(m){return m.each(function(m){var C=d3.select(this),k=this,L=(a||parseInt(C.style("width"))||960)-o.left-o.right,A=(f||parseInt(C.style("height"))||400)-o.top-o.bottom;N.update=function(){C.transition().duration(x).call(N)},N.container=this,b.disabled=m.map(function(e){return!!e.disabled});if(!w){var O;w={};for(O in b)b[O]instanceof Array?w[O]=b[O].slice(0):w[O]=b[O]}if(!m||!m.length||!m.filter(function(e){return e.values.length}).length){var M=C.selectAll(".nv-noData").data([E]);return M.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),M.attr("x",o.left+L/2).attr("y",o.top+A/2).text(function(e){return e}),N}C.selectAll(".nv-noData").remove(),g=t.xScale(),y=t.yScale();var _=C.selectAll("g.nv-wrap.nv-lineChart").data([m]),D=_.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),P=_.select("g");D.append("rect").style("opacity",0),D.append("g").attr("class","nv-x nv-axis"),D.append("g").attr("class","nv-y nv-axis"),D.append("g").attr("class","nv-linesWrap"),D.append("g").attr("class","nv-legendWrap"),D.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",L).attr("height",A>0?A:0),l&&(i.width(L),P.select(".nv-legendWrap").datum(m).call(i),o.top!=i.height()&&(o.top=i.height(),A=(f||parseInt(C.style("height"))||400)-o.top-o.bottom),_.select(".nv-legendWrap").attr("transform","translate(0,"+ -o.top+")")),_.attr("transform","translate("+o.left+","+o.top+")"),p&&P.select(".nv-y.nv-axis").attr("transform","translate("+L+",0)"),d&&(s.width(L).height(A).margin({left:o.left,top:o.top}).svgContainer(C).xScale(g),_.select(".nv-interactive").call(s)),t.width(L).height(A).color(m.map(function(e,t){return e.color||u(e,t)}).filter(function(e,t){return!m[t].disabled}));var H=P.select(".nv-linesWrap").datum(m.filter(function(e){return!e.disabled}));H.transition().call(t),c&&(n.scale(g).ticks(L/100).tickSize(-A,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),P.select(".nv-x.nv-axis").transition().call(n)),h&&(r.scale(y).ticks(A/36).tickSize(-L,0),P.select(".nv-y.nv-axis").transition().call(r)),i.dispatch.on("stateChange",function(e){b=e,S.stateChange(b),N.update()}),s.dispatch.on("elementMousemove",function(i){t.clearHighlights();var a,f,l,c=[];m.filter(function(e,t){return e.seriesIndex=t,!e.disabled}).forEach(function(n,r){f=e.interactiveBisect(n.values,i.pointXValue,N.x()),t.highlightPoint(r,f,!0);var s=n.values[f];if(typeof s=="undefined")return;typeof a=="undefined"&&(a=s),typeof l=="undefined"&&(l=N.xScale()(N.x()(s,f))),c.push({key:n.key,value:N.y()(s,f),color:u(n,n.seriesIndex)})});if(c.length>2){var h=N.yScale().invert(i.mouseY),p=Math.abs(N.yScale().domain()[0]-N.yScale().domain()[1]),d=.03*p,g=e.nearestValueIndex(c.map(function(e){return e.value}),h,d);g!==null&&(c[g].highlight=!0)}var y=n.tickFormat()(N.x()(a,f));s.tooltip.position({left:l+o.left,top:i.mouseY+o.top}).chartContainer(k.parentNode).enabled(v).valueFormatter(function(e,t){return r.tickFormat()(e)}).data({value:y,series:c})(),s.renderGuideLine(l)}),s.dispatch.on("elementMouseout",function(e){S.tooltipHide(),t.clearHighlights()}),S.on("tooltipShow",function(e){v&&T(e,k.parentNode)}),S.on("changeState",function(e){typeof e.disabled!="undefined"&&m.length===e.disabled.length&&(m.forEach(function(t,n){t.disabled=e.disabled[n]}),b.disabled=e.disabled),N.update()})}),N}var t=e.models.line(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.interactiveGuideline(),o={top:30,right:20,bottom:50,left:60},u=e.utils.defaultColor(),a=null,f=null,l=!0,c=!0,h=!0,p=!1,d=!1,v=!0,m=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},g,y,b={},w=null,E="No Data Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),x=250;n.orient("bottom").tickPadding(7),r.orient(p?"right":"left");var T=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=m(i.series.key,a,f,i,N);e.tooltip.show([o,u],l,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),N.dispatch=S,N.lines=t,N.legend=i,N.xAxis=n,N.yAxis=r,N.interactiveLayer=s,d3.rebind(N,t,"defined","isArea","x","y","size","xScale","yScale","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","useVoronoi","id","interpolate"),N.options=e.utils.optionsFunc.bind(N),N.margin=function(e){return arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof e.right!="undefined"?e.right:o.right,o.bottom=typeof e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof e.left!="undefined"?e.left:o.left,N):o},N.width=function(e){return arguments.length?(a=e,N):a},N.height=function(e){return arguments.length?(f=e,N):f},N.color=function(t){return arguments.length?(u=e.utils.getColor(t),i.color(u),N):u},N.showLegend=function(e){return arguments.length?(l=e,N):l},N.showXAxis=function(e){return arguments.length?(c=e,N):c},N.showYAxis=function(e){return arguments.length?(h=e,N):h},N.rightAlignYAxis=function(e){return arguments.length?(p=e,r.orient(e?"right":"left"),N):p},N.useInteractiveGuideline=function(e){return arguments.length?(d=e,e===!0&&(N.interactive(!1),N.useVoronoi(!1)),N):d},N.tooltips=function(e){return arguments.length?(v=e,N):v},N.tooltipContent=function(e){return arguments.length?(m=e,N):m},N.state=function(e){return arguments.length?(b=e,N):b},N.defaultState=function(e){return arguments.length?(w=e,N):w},N.noData=function(e){return arguments.length?(E=e,N):E},N.transitionDuration=function(e){return arguments.length?(x=e,N):x},N},e.models.linePlusBarChart=function(){"use strict";function T(e){return e.each(function(e){var l=d3.select(this),c=this,v=(a||parseInt(l.style("width"))||960)-u.left-u.right,N=(f||parseInt(l.style("height"))||400)-u.top-u.bottom;T.update=function(){l.transition().call(T)},b.disabled=e.map(function(e){return!!e.disabled});if(!w){var C;w={};for(C in b)b[C]instanceof Array?w[C]=b[C].slice(0):w[C]=b[C]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var k=l.selectAll(".nv-noData").data([E]);return k.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),k.attr("x",u.left+v/2).attr("y",u.top+N/2).text(function(e){return e}),T}l.selectAll(".nv-noData").remove();var L=e.filter(function(e){return!e.disabled&&e.bar}),A=e.filter(function(e){return!e.bar});m=A.filter(function(e){return!e.disabled}).length&&A.filter(function(e){return!e.disabled})[0].values.length?t.xScale():n.xScale(),g=n.yScale(),y=t.yScale();var O=d3.select(this).selectAll("g.nv-wrap.nv-linePlusBar").data([e]),M=O.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),_=O.select("g");M.append("g").attr("class","nv-x nv-axis"),M.append("g").attr("class","nv-y1 nv-axis"),M.append("g").attr("class","nv-y2 nv-axis"),M.append("g").attr("class","nv-barsWrap"),M.append("g").attr("class","nv-linesWrap"),M.append("g").attr("class","nv-legendWrap"),p&&(o.width(v/2),_.select(".nv-legendWrap").datum(e.map(function(e){return e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.bar?" (left axis)":" (right axis)"),e})).call(o),u.top!=o.height()&&(u.top=o.height(),N=(f||parseInt(l.style("height"))||400)-u.top-u.bottom),_.select(".nv-legendWrap").attr("transform","translate("+v/2+","+ -u.top+")")),O.attr("transform","translate("+u.left+","+u.top+")"),t.width(v).height(N).color(e.map(function(e,t){return e.color||h(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar})),n.width(v).height(N).color(e.map(function(e,t){return e.color||h(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar}));var D=_.select(".nv-barsWrap").datum(L.length?L:[{values:[]}]),P=_.select(".nv-linesWrap").datum(A[0]&&!A[0].disabled?A:[{values:[]}]);d3.transition(D).call(n),d3.transition(P).call(t),r.scale(m).ticks(v/100).tickSize(-N,0),_.select(".nv-x.nv-axis").attr("transform","translate(0,"+g.range()[0]+")"),d3.transition(_.select(".nv-x.nv-axis")).call(r),i.scale(g).ticks(N/36).tickSize(-v,0),d3.transition(_.select(".nv-y1.nv-axis")).style("opacity",L.length?1:0).call(i),s.scale(y).ticks(N/36).tickSize(L.length?0:-v,0),_.select(".nv-y2.nv-axis").style("opacity",A.length?1:0).attr("transform","translate("+v+",0)"),d3.transition(_.select(".nv-y2.nv-axis")).call(s),o.dispatch.on("stateChange",function(e){b=e,S.stateChange(b),T.update()}),S.on("tooltipShow",function(e){d&&x(e,c.parentNode)}),S.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),b.disabled=t.disabled),T.update()})}),T}var t=e.models.line(),n=e.models.historicalBar(),r=e.models.axis(),i=e.models.axis(),s=e.models.axis(),o=e.models.legend(),u={top:30,right:60,bottom:50,left:60},a=null,f=null,l=function(e){return e.x},c=function(e){return e.y},h=e.utils.defaultColor(),p=!0,d=!0,v=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},m,g,y,b={},w=null,E="No Data Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState");n.padData(!0),t.clipEdge(!1).padData(!0),r.orient("bottom").tickPadding(7).highlightZero(!1),i.orient("left"),s.orient("right");var x=function(n,o){var u=n.pos[0]+(o.offsetLeft||0),a=n.pos[1]+(o.offsetTop||0),f=r.tickFormat()(t.x()(n.point,n.pointIndex)),l=(n.series.bar?i:s).tickFormat()(t.y()(n.point,n.pointIndex)),c=v(n.series.key,f,l,n,T);e.tooltip.show([u,a],c,n.value<0?"n":"s",null,o)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),n.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],S.tooltipShow(e)}),n.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){d&&e.tooltip.cleanup()}),T.dispatch=S,T.legend=o,T.lines=t,T.bars=n,T.xAxis=r,T.y1Axis=i,T.y2Axis=s,d3.rebind(T,t,"defined","size","clipVoronoi","interpolate"),T.options=e.utils.optionsFunc.bind(T),T.x=function(e){return arguments.length?(l=e,t.x(e),n.x(e),T):l},T.y=function(e){return arguments.length?(c=e,t.y(e),n.y(e),T):c},T.margin=function(e){return arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof e.right!="undefined"?e.right:u.right,u.bottom=typeof e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof e.left!="undefined"?e.left:u.left,T):u},T.width=function(e){return arguments.length?(a=e,T):a},T.height=function(e){return arguments.length?(f=e,T):f},T.color=function(t){return arguments.length?(h=e.utils.getColor(t),o.color(h),T):h},T.showLegend=function(e){return arguments.length?(p=e,T):p},T.tooltips=function(e){return arguments.length?(d=e,T):d},T.tooltipContent=function(e){return arguments.length?(v=e,T):v},T.state=function(e){return arguments.length?(b=e,T):b},T.defaultState=function(e){return arguments.length?(w=e,T):w},T.noData=function(e){return arguments.length?(E=e,T):E},T},e.models.lineWithFocusChart=function(){"use strict";function k(e){return e.each(function(e){function U(e){var t=+(e=="e"),n=t?1:-1,r=M/3;return"M"+.5*n+","+r+"A6,6 0 0 "+t+" "+6.5*n+","+(r+6)+"V"+(2*r-6)+"A6,6 0 0 "+t+" "+.5*n+","+2*r+"Z"+"M"+2.5*n+","+(r+8)+"V"+(2*r-8)+"M"+4.5*n+","+(r+8)+"V"+(2*r-8)}function z(){a.empty()||a.extent(w),I.data([a.empty()?g.domain():w]).each(function(e,t){var n=g(e[0])-v.range()[0],r=v.range()[1]-g(e[1]);d3.select(this).select(".left").attr("width",n<0?0:n),d3.select(this).select(".right").attr("x",g(e[1])).attr("width",r<0?0:r)})}function W(){w=a.empty()?null:a.extent();var n=a.empty()?g.domain():a.extent();if(Math.abs(n[0]-n[1])<=1)return;T.brush({extent:n,brush:a}),z();var s=H.select(".nv-focus .nv-linesWrap").datum(e.filter(function(e){return!e.disabled}).map(function(e,r){return{key:e.key,values:e.values.filter(function(e,r){return t.x()(e,r)>=n[0]&&t.x()(e,r)<=n[1]})}}));s.transition().duration(N).call(t),H.select(".nv-focus .nv-x.nv-axis").transition().duration(N).call(r),H.select(".nv-focus .nv-y.nv-axis").transition().duration(N).call(i)}var S=d3.select(this),L=this,A=(h||parseInt(S.style("width"))||960)-f.left-f.right,O=(p||parseInt(S.style("height"))||400)-f.top-f.bottom-d,M=d-l.top-l.bottom;k.update=function(){S.transition().duration(N).call(k)},k.container=this;if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var _=S.selectAll(".nv-noData").data([x]);return _.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),_.attr("x",f.left+A/2).attr("y",f.top+O/2).text(function(e){return e}),k}S.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale(),g=n.xScale(),y=n.yScale();var D=S.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([e]),P=D.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),H=D.select("g");P.append("g").attr("class","nv-legendWrap");var B=P.append("g").attr("class","nv-focus");B.append("g").attr("class","nv-x nv-axis"),B.append("g").attr("class","nv-y nv-axis"),B.append("g").attr("class","nv-linesWrap");var j=P.append("g").attr("class","nv-context");j.append("g").attr("class","nv-x nv-axis"),j.append("g").attr("class","nv-y nv-axis"),j.append("g").attr("class","nv-linesWrap"),j.append("g").attr("class","nv-brushBackground"),j.append("g").attr("class","nv-x nv-brush"),b&&(u.width(A),H.select(".nv-legendWrap").datum(e).call(u),f.top!=u.height()&&(f.top=u.height(),O=(p||parseInt(S.style("height"))||400)-f.top-f.bottom-d),H.select(".nv-legendWrap").attr("transform","translate(0,"+ -f.top+")")),D.attr("transform","translate("+f.left+","+f.top+")"),t.width(A).height(O).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),n.defined(t.defined()).width(A).height(M).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),H.select(".nv-context").attr("transform","translate(0,"+(O+f.bottom+l.top)+")");var F=H.select(".nv-context .nv-linesWrap").datum(e.filter(function(e){return!e.disabled}));d3.transition(F).call(n),r.scale(v).ticks(A/100).tickSize(-O,0),i.scale(m).ticks(O/36).tickSize(-A,0),H.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+O+")"),a.x(g).on("brush",function(){var e=k.transitionDuration();k.transitionDuration(0),W(),k.transitionDuration(e)}),w&&a.extent(w);var I=H.select(".nv-brushBackground").selectAll("g").data([w||a.extent()]),q=I.enter().append("g");q.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),q.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var R=H.select(".nv-x.nv-brush").call(a);R.selectAll("rect").attr("height",M),R.selectAll(".resize").append("path").attr("d",U),W(),s.scale(g).ticks(A/100).tickSize(-M,0),H.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),d3.transition(H.select(".nv-context .nv-x.nv-axis")).call(s),o.scale(y).ticks(M/36).tickSize(-A,0),d3.transition(H.select(".nv-context .nv-y.nv-axis")).call(o),H.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),u.dispatch.on("stateChange",function(e){k.update()}),T.on("tooltipShow",function(e){E&&C(e,L.parentNode)})}),k}var t=e.models.line(),n=e.models.line(),r=e.models.axis(),i=e.models.axis(),s=e.models.axis(),o=e.models.axis(),u=e.models.legend(),a=d3.svg.brush(),f={top:30,right:30,bottom:30,left:60},l={top:0,right:30,bottom:20,left:60},c=e.utils.defaultColor(),h=null,p=null,d=100,v,m,g,y,b=!0,w=null,E=!0,S=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},x="No Data Available.",T=d3.dispatch("tooltipShow","tooltipHide","brush"),N=250;t.clipEdge(!0),n.interactive(!1),r.orient("bottom").tickPadding(5),i.orient("left"),s.orient("bottom").tickPadding(5),o.orient("left");var C=function(n,s){var o=n.pos[0]+(s.offsetLeft||0),u=n.pos[1]+(s.offsetTop||0),a=r.tickFormat()(t.x()(n.point,n.pointIndex)),f=i.tickFormat()(t.y()(n.point,n.pointIndex)),l=S(n.series.key,a,f,n,k);e.tooltip.show([o,u],l,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+f.left,e.pos[1]+f.top],T.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),T.on("tooltipHide",function(){E&&e.tooltip.cleanup()}),k.dispatch=T,k.legend=u,k.lines=t,k.lines2=n,k.xAxis=r,k.yAxis=i,k.x2Axis=s,k.y2Axis=o,d3.rebind(k,t,"defined","isArea","size","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","id"),k.options=e.utils.optionsFunc.bind(k),k.x=function(e){return arguments.length?(t.x(e),n.x(e),k):t.x},k.y=function(e){return arguments.length?(t.y(e),n.y(e),k):t.y},k.margin=function(e){return arguments.length?(f.top=typeof e.top!="undefined"?e.top:f.top,f.right=typeof e.right!="undefined"?e.right:f.right,f.bottom=typeof e.bottom!="undefined"?e.bottom:f.bottom,f.left=typeof e.left!="undefined"?e.left:f.left,k):f},k.margin2=function(e){return arguments.length?(l=e,k):l},k.width=function(e){return arguments.length?(h=e,k):h},k.height=function(e){return arguments.length?(p=e,k):p},k.height2=function(e){return arguments.length?(d=e,k):d},k.color=function(t){return arguments.length?(c=e.utils.getColor(t),u.color(c),k):c},k.showLegend=function(e){return arguments.length?(b=e,k):b},k.tooltips=function(e){return arguments.length?(E=e,k):E},k.tooltipContent=function(e){return arguments.length?(S=e,k):S},k.interpolate=function(e){return arguments.length?(t.interpolate(e),n.interpolate(e),k):t.interpolate()},k.noData=function(e){return arguments.length?(x=e,k):x},k.xTickFormat=function(e){return arguments.length?(r.tickFormat(e),s.tickFormat(e),k):r.tickFormat()},k.yTickFormat=function(e){return arguments.length?(i.tickFormat(e),o.tickFormat(e),k):i.tickFormat()},k.brushExtent=function(e){return arguments.length?(w=e,k):w},k.transitionDuration=function(e){return arguments.length?(N=e,k):N},k},e.models.linePlusBarWithFocusChart=function(){"use strict";function B(e){return e.each(function(e){function nt(e){var t=+(e=="e"),n=t?1:-1,r=q/3;return"M"+.5*n+","+r+"A6,6 0 0 "+t+" "+6.5*n+","+(r+6)+"V"+(2*r-6)+"A6,6 0 0 "+t+" "+.5*n+","+2*r+"Z"+"M"+2.5*n+","+(r+8)+"V"+(2*r-8)+"M"+4.5*n+","+(r+8)+"V"+(2*r-8)}function rt(){h.empty()||h.extent(x),Z.data([h.empty()?k.domain():x]).each(function(e,t){var n=k(e[0])-k.range()[0],r=k.range()[1]-k(e[1]);d3.select(this).select(".left").attr("width",n<0?0:n),d3.select(this).select(".right").attr("x",k(e[1])).attr("width",r<0?0:r)})}function it(){x=h.empty()?null:h.extent(),S=h.empty()?k.domain():h.extent(),D.brush({extent:S,brush:h}),rt(),r.width(F).height(I).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar})),t.width(F).height(I).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar}));var n=J.select(".nv-focus .nv-barsWrap").datum(U.length?U.map(function(e,t){return{key:e.key,values:e.values.filter(function(e,t){return r.x()(e,t)>=S[0]&&r.x()(e,t)<=S[1]})}}):[{values:[]}]),i=J.select(".nv-focus .nv-linesWrap").datum(z[0].disabled?[{values:[]}]:z.map(function(e,n){return{key:e.key,values:e.values.filter(function(e,n){return t.x()(e,n)>=S[0]&&t.x()(e,n)<=S[1]})}}));U.length?C=r.xScale():C=t.xScale(),s.scale(C).ticks(F/100).tickSize(-I,0),s.domain([Math.ceil(S[0]),Math.floor(S[1])]),J.select(".nv-x.nv-axis").transition().duration(P).call(s),n.transition().duration(P).call(r),i.transition().duration(P).call(t),J.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L.range()[0]+")"),u.scale(L).ticks(I/36).tickSize(-F,0),J.select(".nv-focus .nv-y1.nv-axis").style("opacity",U.length?1:0),a.scale(A).ticks(I/36).tickSize(U.length?0:-F,0),J.select(".nv-focus .nv-y2.nv-axis").style("opacity",z.length?1:0).attr("transform","translate("+C.range()[1]+",0)"),J.select(".nv-focus .nv-y1.nv-axis").transition().duration(P).call(u),J.select(".nv-focus .nv-y2.nv-axis").transition().duration(P).call(a)}var N=d3.select(this),j=this,F=(v||parseInt(N.style("width"))||960)-p.left-p.right,I=(m||parseInt(N.style("height"))||400)-p.top-p.bottom-g,q=g-d.top-d.bottom;B.update=function(){N.transition().duration(P).call(B)},B.container=this;if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var R=N.selectAll(".nv-noData").data([_]);return R.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),R.attr("x",p.left+F/2).attr("y",p.top+I/2).text(function(e){return e}),B}N.selectAll(".nv-noData").remove();var U=e.filter(function(e){return!e.disabled&&e.bar}),z=e.filter(function(e){return!e.bar});C=r.xScale(),k=o.scale(),L=r.yScale(),A=t.yScale(),O=i.yScale(),M=n.yScale();var W=e.filter(function(e){return!e.disabled&&e.bar}).map(function(e){return e.values.map(function(e,t){return{x:y(e,t),y:b(e,t)}})}),X=e.filter(function(e){return!e.disabled&&!e.bar}).map(function(e){return e.values.map(function(e,t){return{x:y(e,t),y:b(e,t)}})});C.range([0,F]),k.domain(d3.extent(d3.merge(W.concat(X)),function(e){return e.x})).range([0,F]);var V=N.selectAll("g.nv-wrap.nv-linePlusBar").data([e]),$=V.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),J=V.select("g");$.append("g").attr("class","nv-legendWrap");var K=$.append("g").attr("class","nv-focus");K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y1 nv-axis"),K.append("g").attr("class","nv-y2 nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-linesWrap");var Q=$.append("g").attr("class","nv-context");Q.append("g").attr("class","nv-x nv-axis"),Q.append("g").attr("class","nv-y1 nv-axis"),Q.append("g").attr("class","nv-y2 nv-axis"),Q.append("g").attr("class","nv-barsWrap"),Q.append("g").attr("class","nv-linesWrap"),Q.append("g").attr("class","nv-brushBackground"),Q.append("g").attr("class","nv-x nv-brush"),E&&(c.width(F/2),J.select(".nv-legendWrap").datum(e.map(function(e){return e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.bar?" (left axis)":" (right axis)"),e})).call(c),p.top!=c.height()&&(p.top=c.height(),I=(m||parseInt(N.style("height"))||400)-p.top-p.bottom-g),J.select(".nv-legendWrap").attr("transform","translate("+F/2+","+ -p.top+")")),V.attr("transform","translate("+p.left+","+p.top+")"),i.width(F).height(q).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar})),n.width(F).height(q).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar}));var G=J.select(".nv-context .nv-barsWrap").datum(U.length?U:[{values:[]}]),Y=J.select(".nv-context .nv-linesWrap").datum(z[0].disabled?[{values:[]}]:z);J.select(".nv-context").attr("transform","translate(0,"+(I+p.bottom+d.top)+")"),G.transition().call(i),Y.transition().call(n),h.x(k).on("brush",it),x&&h.extent(x);var Z=J.select(".nv-brushBackground").selectAll("g").data([x||h.extent()]),et=Z.enter().append("g");et.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",q),et.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",q);var tt=J.select(".nv-x.nv-brush").call(h);tt.selectAll("rect").attr("height",q),tt.selectAll(".resize").append("path").attr("d",nt),o.ticks(F/100).tickSize(-q,0),J.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+O.range()[0]+")"),J.select(".nv-context .nv-x.nv-axis").transition().call(o),f.scale(O).ticks(q/36).tickSize(-F,0),J.select(".nv-context .nv-y1.nv-axis").style("opacity",U.length?1:0).attr("transform","translate(0,"+k.range()[0]+")"),J.select(".nv-context .nv-y1.nv-axis").transition().call(f),l.scale(M).ticks(q/36).tickSize(U.length?0:-F,0),J.select(".nv-context .nv-y2.nv-axis").style("opacity",z.length?1:0).attr("transform","translate("+k.range()[1]+",0)"),J.select(".nv-context .nv-y2.nv-axis").transition().call(l),c.dispatch.on("stateChange",function(e){B.update()}),D.on("tooltipShow",function(e){T&&H(e,j.parentNode)}),it()}),B}var t=e.models.line(),n=e.models.line(),r=e.models.historicalBar(),i=e.models.historicalBar(),s=e.models.axis(),o=e.models.axis(),u=e.models.axis(),a=e.models.axis(),f=e.models.axis(),l=e.models.axis(),c=e.models.legend(),h=d3.svg.brush(),p={top:30,right:30,bottom:30,left:60},d={top:0,right:30,bottom:20,left:60},v=null,m=null,g=100,y=function(e){return e.x},b=function(e){return e.y},w=e.utils.defaultColor(),E=!0,S,x=null,T=!0,N=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},C,k,L,A,O,M,_="No Data Available.",D=d3.dispatch("tooltipShow","tooltipHide","brush"),P=0;t.clipEdge(!0),n.interactive(!1),s.orient("bottom").tickPadding(5),u.orient("left"),a.orient("right"),o.orient("bottom").tickPadding(5),f.orient("left"),l.orient("right");var H=function(n,r){S&&(n.pointIndex+=Math.ceil(S[0]));var i=n.pos[0]+(r.offsetLeft||0),o=n.pos[1]+(r.offsetTop||0),f=s.tickFormat()(t.x()(n.point,n.pointIndex)),l=(n.series.bar?u:a).tickFormat()(t.y()(n.point,n.pointIndex)),c=N(n.series.key,f,l,n,B);e.tooltip.show([i,o],c,n.value<0?"n":"s",null,r)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+p.left,e.pos[1]+p.top],D.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){D.tooltipHide(e)}),r.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+p.left,e.pos[1]+p.top],D.tooltipShow(e)}),r.dispatch.on("elementMouseout.tooltip",function(e){D.tooltipHide(e)}),D.on("tooltipHide",function(){T&&e.tooltip.cleanup()}),B.dispatch=D,B.legend=c,B.lines=t,B.lines2=n,B.bars=r,B.bars2=i,B.xAxis=s,B.x2Axis=o,B.y1Axis=u,B.y2Axis=a,B.y3Axis=f,B.y4Axis=l,d3.rebind(B,t,"defined","size","clipVoronoi","interpolate"),B.options=e.utils.optionsFunc.bind(B),B.x=function(e){return arguments.length?(y=e,t.x(e),r.x(e),B):y},B.y=function(e){return arguments.length?(b=e,t.y(e),r.y(e),B):b},B.margin=function(e){return arguments.length?(p.top=typeof e.top!="undefined"?e.top:p.top,p.right=typeof e.right!="undefined"?e.right:p.right,p.bottom=typeof e.bottom!="undefined"?e.bottom:p.bottom,p.left=typeof e.left!="undefined"?e.left:p.left,B):p},B.width=function(e){return arguments.length?(v=e,B):v},B.height=function(e){return arguments.length?(m=e,B):m},B.color=function(t){return arguments.length?(w=e.utils.getColor(t),c.color(w),B):w},B.showLegend=function(e){return arguments.length?(E=e,B):E},B.tooltips=function(e){return arguments.length?(T=e,B):T},B.tooltipContent=function(e){return arguments.length?(N=e,B):N},B.noData=function(e){return arguments.length?(_=e,B):_},B.brushExtent=function(e){return arguments.length?(x=e,B):x},B},e.models.multiBar=function(){"use strict";function C(e){return e.each(function(e){var C=n-t.left-t.right,k=r-t.top-t.bottom,L=d3.select(this);d&&e.length&&(d=[{values:e[0].values.map(function(e){return{x:e.x,y:0,series:e.series,size:.01}})}]),c&&(e=d3.layout.stack().offset(h).values(function(e){return e.values}).y(a)(!e.length&&d?d:e)),e.forEach(function(e,t){e.values.forEach(function(e){e.series=t})}),c&&e[0].values.map(function(t,n){var r=0,i=0;e.map(function(e){var t=e.values[n];t.size=Math.abs(t.y),t.y<0?(t.y1=i,i-=t.size):(t.y1=t.size+r,r+=t.size)})});var A=y&&b?[]:e.map(function(e){return e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0,y1:e.y1}})});i.domain(y||d3.merge(A).map(function(e){return e.x})).rangeBands(w||[0,C],S),s.domain(b||d3.extent(d3.merge(A).map(function(e){return c?e.y>0?e.y1:e.y1+e.y:e.y}).concat(f))).range(E||[k,0]),i.domain()[0]===i.domain()[1]&&(i.domain()[0]?i.domain([i.domain()[0]-i.domain()[0]*.01,i.domain()[1]+i.domain()[1]*.01]):i.domain([-1,1])),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]+s.domain()[0]*.01,s.domain()[1]-s.domain()[1]*.01]):s.domain([-1,1])),T=T||i,N=N||s;var O=L.selectAll("g.nv-wrap.nv-multibar").data([e]),M=O.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),_=M.append("defs"),D=M.append("g"),P=O.select("g");D.append("g").attr("class","nv-groups"),O.attr("transform","translate("+t.left+","+t.top+")"),_.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),O.select("#nv-edge-clip-"+o+" rect").attr("width",C).attr("height",k),P.attr("clip-path",l?"url(#nv-edge-clip-"+o+")":"");var H=O.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e,t){return t});H.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),H.exit().transition().selectAll("rect.nv-bar").delay(function(t,n){return n*g/e[0].values.length}).attr("y",function(e){return c?N(e.y0):N(0)}).attr("height",0).remove(),H.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}).style("fill",function(e,t){return p(e,t)}).style("stroke",function(e,t){return p(e,t)}),H.transition().style("stroke-opacity",1).style("fill-opacity",.75);var B=H.selectAll("rect.nv-bar").data(function(t){return d&&!e.length?d.values:t.values});B.exit().remove();var j=B.enter().append("rect").attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(t,n,r){return c?0:r*i.rangeBand()/e.length}).attr("y",function(e){return N(c?e.y0:0)}).attr("height",0).attr("width",i.rangeBand()/(c?1:e.length)).attr("transform",function(e,t){return"translate("+i(u(e,t))+",0)"});B.style("fill",function(e,t,n){return p(e,n,t)}).style("stroke",function(e,t,n){return p(e,n,t)}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),x.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),x.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){x.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length
,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){x.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}),B.attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}).transition().attr("transform",function(e,t){return"translate("+i(u(e,t))+",0)"}),v&&(m||(m=e.map(function(){return!0})),B.style("fill",function(e,t,n){return d3.rgb(v(e,t)).darker(m.map(function(e,t){return t}).filter(function(e,t){return!m[t]})[n]).toString()}).style("stroke",function(e,t,n){return d3.rgb(v(e,t)).darker(m.map(function(e,t){return t}).filter(function(e,t){return!m[t]})[n]).toString()})),c?B.transition().delay(function(t,n){return n*g/e[0].values.length}).attr("y",function(e,t){return s(c?e.y1:0)}).attr("height",function(e,t){return Math.max(Math.abs(s(e.y+(c?e.y0:0))-s(c?e.y0:0)),1)}).attr("x",function(t,n){return c?0:t.series*i.rangeBand()/e.length}).attr("width",i.rangeBand()/(c?1:e.length)):B.transition().delay(function(t,n){return n*g/e[0].values.length}).attr("x",function(t,n){return t.series*i.rangeBand()/e.length}).attr("width",i.rangeBand()/e.length).attr("y",function(e,t){return a(e,t)<0?s(0):s(0)-s(a(e,t))<1?s(0)-1:s(a(e,t))||0}).attr("height",function(e,t){return Math.max(Math.abs(s(a(e,t))-s(0)),1)||0}),T=i.copy(),N=s.copy()}),C}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=d3.scale.ordinal(),s=d3.scale.linear(),o=Math.floor(Math.random()*1e4),u=function(e){return e.x},a=function(e){return e.y},f=[0],l=!0,c=!1,h="zero",p=e.utils.defaultColor(),d=!1,v=null,m,g=1200,y,b,w,E,S=.1,x=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),T,N;return C.dispatch=x,C.options=e.utils.optionsFunc.bind(C),C.x=function(e){return arguments.length?(u=e,C):u},C.y=function(e){return arguments.length?(a=e,C):a},C.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,C):t},C.width=function(e){return arguments.length?(n=e,C):n},C.height=function(e){return arguments.length?(r=e,C):r},C.xScale=function(e){return arguments.length?(i=e,C):i},C.yScale=function(e){return arguments.length?(s=e,C):s},C.xDomain=function(e){return arguments.length?(y=e,C):y},C.yDomain=function(e){return arguments.length?(b=e,C):b},C.xRange=function(e){return arguments.length?(w=e,C):w},C.yRange=function(e){return arguments.length?(E=e,C):E},C.forceY=function(e){return arguments.length?(f=e,C):f},C.stacked=function(e){return arguments.length?(c=e,C):c},C.stackOffset=function(e){return arguments.length?(h=e,C):h},C.clipEdge=function(e){return arguments.length?(l=e,C):l},C.color=function(t){return arguments.length?(p=e.utils.getColor(t),C):p},C.barColor=function(t){return arguments.length?(v=e.utils.getColor(t),C):v},C.disabled=function(e){return arguments.length?(m=e,C):m},C.id=function(e){return arguments.length?(o=e,C):o},C.hideable=function(e){return arguments.length?(d=e,C):d},C.delay=function(e){return arguments.length?(g=e,C):g},C.groupSpacing=function(e){return arguments.length?(S=e,C):S},C},e.models.multiBarChart=function(){"use strict";function A(e){return e.each(function(e){var b=d3.select(this),O=this,M=(u||parseInt(b.style("width"))||960)-o.left-o.right,_=(a||parseInt(b.style("height"))||400)-o.top-o.bottom;A.update=function(){b.transition().duration(k).call(A)},A.container=this,S.disabled=e.map(function(e){return!!e.disabled});if(!x){var D;x={};for(D in S)S[D]instanceof Array?x[D]=S[D].slice(0):x[D]=S[D]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var P=b.selectAll(".nv-noData").data([T]);return P.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),P.attr("x",o.left+M/2).attr("y",o.top+_/2).text(function(e){return e}),A}b.selectAll(".nv-noData").remove(),w=t.xScale(),E=t.yScale();var H=b.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([e]),B=H.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),j=H.select("g");B.append("g").attr("class","nv-x nv-axis"),B.append("g").attr("class","nv-y nv-axis"),B.append("g").attr("class","nv-barsWrap"),B.append("g").attr("class","nv-legendWrap"),B.append("g").attr("class","nv-controlsWrap"),c&&(i.width(M-C()),t.barColor()&&e.forEach(function(e,t){e.color=d3.rgb("#ccc").darker(t*1.5).toString()}),j.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),_=(a||parseInt(b.style("height"))||400)-o.top-o.bottom),j.select(".nv-legendWrap").attr("transform","translate("+C()+","+ -o.top+")"));if(l){var F=[{key:"Grouped",disabled:t.stacked()},{key:"Stacked",disabled:!t.stacked()}];s.width(C()).color(["#444","#444","#444"]),j.select(".nv-controlsWrap").datum(F).attr("transform","translate(0,"+ -o.top+")").call(s)}H.attr("transform","translate("+o.left+","+o.top+")"),d&&j.select(".nv-y.nv-axis").attr("transform","translate("+M+",0)"),t.disabled(e.map(function(e){return e.disabled})).width(M).height(_).color(e.map(function(e,t){return e.color||f(e,t)}).filter(function(t,n){return!e[n].disabled}));var I=j.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));I.transition().call(t);if(h){n.scale(w).ticks(M/100).tickSize(-_,0),j.select(".nv-x.nv-axis").attr("transform","translate(0,"+E.range()[0]+")"),j.select(".nv-x.nv-axis").transition().call(n);var q=j.select(".nv-x.nv-axis > g").selectAll("g");q.selectAll("line, text").style("opacity",1);if(m){var R=function(e,t){return"translate("+e+","+t+")"},U=5,z=17;q.selectAll("text").attr("transform",function(e,t,n){return R(0,n%2==0?U:z)});var W=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;j.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(e,t){return R(0,t===0||W%2!==0?z:U)})}v&&q.filter(function(t,n){return n%Math.ceil(e[0].values.length/(M/100))!==0}).selectAll("text, line").style("opacity",0),g&&q.selectAll(".tick text").attr("transform","rotate("+g+" 0,0)").style("text-anchor",g>0?"start":"end"),j.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}p&&(r.scale(E).ticks(_/36).tickSize(-M,0),j.select(".nv-y.nv-axis").transition().call(r)),i.dispatch.on("stateChange",function(e){S=e,N.stateChange(S),A.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;F=F.map(function(e){return e.disabled=!0,e}),e.disabled=!1;switch(e.key){case"Grouped":t.stacked(!1);break;case"Stacked":t.stacked(!0)}S.stacked=t.stacked(),N.stateChange(S),A.update()}),N.on("tooltipShow",function(e){y&&L(e,O.parentNode)}),N.on("changeState",function(n){typeof n.disabled!="undefined"&&(e.forEach(function(e,t){e.disabled=n.disabled[t]}),S.disabled=n.disabled),typeof n.stacked!="undefined"&&(t.stacked(n.stacked),S.stacked=n.stacked),A.update()})}),A}var t=e.models.multiBar(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o={top:30,right:20,bottom:50,left:60},u=null,a=null,f=e.utils.defaultColor(),l=!0,c=!0,h=!0,p=!0,d=!1,v=!0,m=!1,g=0,y=!0,b=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" on "+t+"</p>"},w,E,S={stacked:!1},x=null,T="No Data Available.",N=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),C=function(){return l?180:0},k=250;t.stacked(!1),n.orient("bottom").tickPadding(7).highlightZero(!0).showMaxMin(!1).tickFormat(function(e){return e}),r.orient(d?"right":"left").tickFormat(d3.format(",.1f")),s.updateState(!1);var L=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=b(i.series.key,a,f,i,A);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],N.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){N.tooltipHide(e)}),N.on("tooltipHide",function(){y&&e.tooltip.cleanup()}),A.dispatch=N,A.multibar=t,A.legend=i,A.xAxis=n,A.yAxis=r,d3.rebind(A,t,"x","y","xDomain","yDomain","xRange","yRange","forceX","forceY","clipEdge","id","stacked","stackOffset","delay","barColor","groupSpacing"),A.options=e.utils.optionsFunc.bind(A),A.margin=function(e){return arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof e.right!="undefined"?e.right:o.right,o.bottom=typeof e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof e.left!="undefined"?e.left:o.left,A):o},A.width=function(e){return arguments.length?(u=e,A):u},A.height=function(e){return arguments.length?(a=e,A):a},A.color=function(t){return arguments.length?(f=e.utils.getColor(t),i.color(f),A):f},A.showControls=function(e){return arguments.length?(l=e,A):l},A.showLegend=function(e){return arguments.length?(c=e,A):c},A.showXAxis=function(e){return arguments.length?(h=e,A):h},A.showYAxis=function(e){return arguments.length?(p=e,A):p},A.rightAlignYAxis=function(e){return arguments.length?(d=e,r.orient(e?"right":"left"),A):d},A.reduceXTicks=function(e){return arguments.length?(v=e,A):v},A.rotateLabels=function(e){return arguments.length?(g=e,A):g},A.staggerLabels=function(e){return arguments.length?(m=e,A):m},A.tooltip=function(e){return arguments.length?(b=e,A):b},A.tooltips=function(e){return arguments.length?(y=e,A):y},A.tooltipContent=function(e){return arguments.length?(b=e,A):b},A.state=function(e){return arguments.length?(S=e,A):S},A.defaultState=function(e){return arguments.length?(x=e,A):x},A.noData=function(e){return arguments.length?(T=e,A):T},A.transitionDuration=function(e){return arguments.length?(k=e,A):k},A},e.models.multiBarHorizontal=function(){"use strict";function C(e){return e.each(function(e){var i=n-t.left-t.right,y=r-t.top-t.bottom,C=d3.select(this);p&&(e=d3.layout.stack().offset("zero").values(function(e){return e.values}).y(a)(e)),e.forEach(function(e,t){e.values.forEach(function(e){e.series=t})}),p&&e[0].values.map(function(t,n){var r=0,i=0;e.map(function(e){var t=e.values[n];t.size=Math.abs(t.y),t.y<0?(t.y1=i-t.size,i-=t.size):(t.y1=r,r+=t.size)})});var k=b&&w?[]:e.map(function(e){return e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0,y1:e.y1}})});s.domain(b||d3.merge(k).map(function(e){return e.x})).rangeBands(E||[0,y],.1),o.domain(w||d3.extent(d3.merge(k).map(function(e){return p?e.y>0?e.y1+e.y:e.y1:e.y}).concat(f))),d&&!p?o.range(S||[o.domain()[0]<0?m:0,i-(o.domain()[1]>0?m:0)]):o.range(S||[0,i]),T=T||s,N=N||d3.scale.linear().domain(o.domain()).range([o(0),o(0)]);var L=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([e]),A=L.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),O=A.append("defs"),M=A.append("g"),_=L.select("g");M.append("g").attr("class","nv-groups"),L.attr("transform","translate("+t.left+","+t.top+")");var D=L.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e,t){return t});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().transition().style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}).style("fill",function(e,t){return l(e,t)}).style("stroke",function(e,t){return l(e,t)}),D.transition().style("stroke-opacity",1).style("fill-opacity",.75);var P=D.selectAll("g.nv-bar").data(function(e){return e.values});P.exit().remove();var H=P.enter().append("g").attr("transform",function(t,n,r){return"translate("+N(p?t.y0:0)+","+(p?0:r*s.rangeBand()/e.length+s(u(t,n)))+")"});H.append("rect").attr("width",0).attr("height",s.rangeBand()/(p?1:e.length)),P.on("mouseover",function(t,n){d3.select(this).classed("hover",!0),x.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[o(a(t,n)+(p?t.y0:0)),s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),x.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){x.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length,o(a(t,n)+(p?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){x.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length,o(a(t,n)+(p?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}),H.append("text"),d&&!p?(P.select("text").attr("text-anchor",function(e,t){return a(e,t)<0?"end":"start"}).attr("y",s.rangeBand()/(e.length*2)).attr("dy",".32em").text(function(e,t){return g(a(e,t))}),P.transition().select("text").attr("x",function(e,t){return a(e,t)<0?-4:o(a(e,t))-o(0)+4})):P.selectAll("text").text(""),v&&!p?(H.append("text").classed("nv-bar-label",!0),P.select("text.nv-bar-label").attr("text-anchor",function(e,t){return a(e,t)<0?"start":"end"}).attr("y",s.rangeBand()/(e.length*2)).attr("dy",".32em").text(function(e,t){return u(e,t)}),P.transition().select("text.nv-bar-label").attr("x",function(e,t){return a(e,t)<0?o(0)-o(a(e,t))+4:-4})):P.selectAll("text.nv-bar-label").text(""),P.attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}),c&&(h||(h=e.map(function(){return!0})),P.style("fill",function(e,t,n){return d3.rgb(c(e,t)).darker(h.map(function(e,t){return t}).filter(function(e,t){return!h[t]})[n]).toString()}).style("stroke",function(e,t,n){return d3.rgb(c(e,t)).darker(h.map(function(e,t){return t}).filter(function(e,t){return!h[t]})[n]).toString()})),p?P.transition().attr("transform",function(e,t){return"translate("+o(e.y1)+","+s(u(e,t))+")"}).select("rect").attr("width",function(e,t){return Math.abs(o(a(e,t)+e.y0)-o(e.y0))}).attr("height",s.rangeBand()):P.transition().attr("transform",function(t,n){return"translate("+(a(t,n)<0?o(a(t,n)):o(0))+","+(t.series*s.rangeBand()/e.length+s(u(t,n)))+")"}).select("rect").attr("height",s.rangeBand()/e.length).attr("width",function(e,t){return Math.max(Math.abs(o(a(e,t))-o(0)),1)}),T=s.copy(),N=o.copy()}),C}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.ordinal(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=[0],l=e.utils.defaultColor(),c=null,h,p=!1,d=!1,v=!1,m=60,g=d3.format(",.2f"),y=1200,b,w,E,S,x=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),T,N;return C.dispatch=x,C.options=e.utils.optionsFunc.bind(C),C.x=function(e){return arguments.length?(u=e,C):u},C.y=function(e){return arguments.length?(a=e,C):a},C.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,C):t},C.width=function(e){return arguments.length?(n=e,C):n},C.height=function(e){return arguments.length?(r=e,C):r},C.xScale=function(e){return arguments.length?(s=e,C):s},C.yScale=function(e){return arguments.length?(o=e,C):o},C.xDomain=function(e){return arguments.length?(b=e,C):b},C.yDomain=function(e){return arguments.length?(w=e,C):w},C.xRange=function(e){return arguments.length?(E=e,C):E},C.yRange=function(e){return arguments.length?(S=e,C):S},C.forceY=function(e){return arguments.length?(f=e,C):f},C.stacked=function(e){return arguments.length?(p=e,C):p},C.color=function(t){return arguments.length?(l=e.utils.getColor(t),C):l},C.barColor=function(t){return arguments.length?(c=e.utils.getColor(t),C):c},C.disabled=function(e){return arguments.length?(h=e,C):h},C.id=function(e){return arguments.length?(i=e,C):i},C.delay=function(e){return arguments.length?(y=e,C):y},C.showValues=function(e){return arguments.length?(d=e,C):d},C.showBarLabels=function(e){return arguments.length?(v=e,C):v},C.valueFormat=function(e){return arguments.length?(g=e,C):g},C.valuePadding=function(e){return arguments.length?(m=e,C):m},C},e.models.multiBarHorizontalChart=function(){"use strict";function C(e){return e.each(function(e){var d=d3.select(this),m=this,k=(u||parseInt(d.style("width"))||960)-o.left-o.right,L=(a||parseInt(d.style("height"))||400)-o.top-o.bottom;C.update=function(){d.transition().duration(T).call(C)},C.container=this,b.disabled=e.map(function(e){return!!e.disabled});if(!w){var A;w={};for(A in b)b[A]instanceof Array?w[A]=b[A].slice(0):w[A]=b[A]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var O=d.selectAll(".nv-noData").data([E]);return O.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),O.attr("x",o.left+k/2).attr("y",o.top+L/2).text(function(e){return e}),C}d.selectAll(".nv-noData").remove(),g=t.xScale(),y=t.yScale();var M=d.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([e]),_=M.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),D=M.select("g");_.append("g").attr("class","nv-x nv-axis"),_.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),_.append("g").attr("class","nv-barsWrap"),_.append("g").attr("class","nv-legendWrap"),_.append("g").attr("class","nv-controlsWrap"),c&&(i.width(k-x()),t.barColor()&&e.forEach(function(e,t){e.color=d3.rgb("#ccc").darker(t*1.5).toString()}),D.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),L=(a||parseInt(d.style("height"))||400)-o.top-o.bottom),D.select(".nv-legendWrap").attr("transform","translate("+x()+","+ -o.top+")"));if(l){var P=[{key:"Grouped",disabled:t.stacked()},{key:"Stacked",disabled:!t.stacked()}];s.width(x()).color(["#444","#444","#444"]),D.select(".nv-controlsWrap").datum(P).attr("transform","translate(0,"+ -o.top+")").call(s)}M.attr("transform","translate("+o.left+","+o.top+")"),t.disabled(e.map(function(e){return e.disabled})).width(k).height(L).color(e.map(function(e,t){return e.color||f(e,t)}).filter(function(t,n){return!e[n].disabled}));var H=D.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));H.transition().call(t);if(h){n.scale(g).ticks(L/24).tickSize(-k,0),D.select(".nv-x.nv-axis").transition().call(n);var B=D.select(".nv-x.nv-axis").selectAll("g");B.selectAll("line, text")}p&&(r.scale(y).ticks(k/100).tickSize(-L,0),D.select(".nv-y.nv-axis").attr("transform","translate(0,"+L+")"),D.select(".nv-y.nv-axis").transition().call(r)),D.select(".nv-zeroLine line").attr("x1",y(0)).attr("x2",y(0)).attr("y1",0).attr("y2",-L),i.dispatch.on("stateChange",function(e){b=e,S.stateChange(b),C.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;P=P.map(function(e){return e.disabled=!0,e}),e.disabled=!1;switch(e.key){case"Grouped":t.stacked(!1);break;case"Stacked":t.stacked(!0)}b.stacked=t.stacked(),S.stateChange(b),C.update()}),S.on("tooltipShow",function(e){v&&N(e,m.parentNode)}),S.on("changeState",function(n){typeof n.disabled!="undefined"&&(e.forEach(function(e,t){e.disabled=n.disabled[t]}),b.disabled=n.disabled),typeof n.stacked!="undefined"&&(t.stacked(n.stacked),b.stacked=n.stacked),C.update()})}),C}var t=e.models.multiBarHorizontal(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend().height(30),s=e.models.legend().height(30),o={top:30,right:20,bottom:50,left:60},u=null,a=null,f=e.utils.defaultColor(),l=!0,c=!0,h=!0,p=!0,d=!1,v=!0,m=function(e,t,n,r,i){return"<h3>"+e+" - "+t+"</h3>"+"<p>"+n+"</p>"},g,y,b={stacked:d},w=null,E="No Data Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),x=function(){return l?180:0},T=250;t.stacked(d),n.orient("left").tickPadding(5).highlightZero(!1).showMaxMin(!1).tickFormat(function(e){return e}),r.orient("bottom").tickFormat(d3.format(",.1f")),s.updateState(!1);var N=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=m(i.series.key,a,f,i,C);e.tooltip.show([o,u],l,i.value<0?"e":"w",null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),C.dispatch=S,C.multibar=t,C.legend=i,C.xAxis=n,C.yAxis=r,d3.rebind(C,t,"x","y","xDomain","yDomain","xRange","yRange","forceX","forceY","clipEdge","id","delay","showValues","showBarLabels","valueFormat","stacked","barColor"),C.options=e.utils.optionsFunc.bind(C),C.margin=function(e){return arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof e.right!="undefined"?e.right:o.right,o.bottom=typeof e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof e.left!="undefined"?e.left:o.left,C):o},C.width=function(e){return arguments.length?(u=e,C):u},C.height=function(e){return arguments.length?(a=e,C):a},C.color=function(t){return arguments.length?(f=e.utils.getColor(t),i.color(f),C):f},C.showControls=function(e){return arguments.length?(l=e,C):l},C.showLegend=function(e){return arguments.length?(c=e,C):c},C.showXAxis=function(e){return arguments.length?(h=e,C):h},C.showYAxis=function(e){return arguments.length?(p=e,C):p},C.tooltip=function(e){return arguments.length?(m=e,C):m},C.tooltips=function(e){return arguments.length?(v=e,C):v},C.tooltipContent=function(e){return arguments.length?(m=e,C):m},C.state=function(e){return arguments.length?(b=e,C):b},C.defaultState=function(e){return arguments.length?(w=e,C):w},C.noData=function(e){return arguments.length?(E=e,C):E},C.transitionDuration=function(e){return arguments.length?(T=e,C):T},C},e.models.multiChart=function(){"use strict";function C(e){return e.each(function(e){var u=d3.select(this),f=this;C.update=function(){u.transition().call(C)},C.container=this;var k=(r||parseInt(u.style("width"))||960)-t.left-t.right,L=(i||parseInt(u.style("height"))||400)-t.top-t.bottom,A=e.filter(function(e){return!e.disabled&&e.type=="line"&&e.yAxis==1}),O=e.filter(function(e){return!e.disabled&&e.type=="line"&&e.yAxis==2}),M=e.filter(function(e){return!e.disabled&&e.type=="bar"&&e.yAxis==1}),_=e.filter(function(e){return!e.disabled&&e.type=="bar"&&e.yAxis==2}),D=e.filter(function(e){return!e.disabled&&e.type=="area"&&e.yAxis==1}),P=e.filter(function(e){return!e.disabled&&e.type=="area"&&e.yAxis==2}),H=e.filter(function(e){return!e.disabled&&e.yAxis==1}).map(function(e){return e.values.map(function(e,t){return{x:e.x,y:e.y}})}),B=e.filter(function(e){return!e.disabled&&e.yAxis==2}).map(function(e){return e.values.map(function(e,t){return{x:e.x,y:e.y}})});a.domain(d3.extent(d3.merge(H.concat(B)),function(e){return e.x})).range([0,k]);var j=u.selectAll("g.wrap.multiChart").data([e]),F=j.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");F.append("g").attr("class","x axis"),F.append("g").attr("class","y1 axis"),F.append("g").attr("class","y2 axis"),F.append("g").attr("class","lines1Wrap"),F.append("g").attr("class","lines2Wrap"),F.append("g").attr("class","bars1Wrap"),F.append("g").attr("class","bars2Wrap"),F.append("g").attr("class","stack1Wrap"),F.append("g").attr("class","stack2Wrap"),F.append("g").attr("class","legendWrap");var I=j.select("g");s&&(x.width(k/2),I.select(".legendWrap").datum(e.map(function(e){return e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.yAxis==1?"":" (right axis)"),e})).call(x),t.top!=x.height()&&(t.top=x.height(),L=(i||parseInt(u.style("height"))||400)-t.top-t.bottom),I.select(".legendWrap").attr("transform","translate("+k/2+","+ -t.top+")")),d.width(k).height(L).interpolate("monotone").color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="line"})),v.width(k).height(L).interpolate("monotone").color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="line"})),m.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="bar"})),g.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="bar"})),y.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="area"})),b.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="area"})),I.attr("transform","translate("+t.left+","+t.top+")");var q=I.select(".lines1Wrap").datum(A),R=I.select(".bars1Wrap").datum(M),U=I.select(".stack1Wrap").datum(D),z=I.select(".lines2Wrap").datum(O),W=I.select(".bars2Wrap").datum(_),X=I.select(".stack2Wrap").datum(P),V=D.length?D.map(function(e){return e.values}).reduce(function(e,t){return e.map(function(e,n){return{x:e.x,y:e.y+t[n].y}})}).concat([{x:0,y:0}]):[],$=P.length?P.map(function(e){return e.values}).reduce(function(e,t){return e.map(function(e,n){return{x:e.x,y:e.y+t[n].y}})}).concat([{x:0,y:0}]):[];h.domain(l||d3.extent(d3.merge(H).concat(V),function(e){return e.y})).range([0,L]),p.domain(c||d3.extent(d3.merge(B).concat($),function(e){return e.y})).range([0,L]),d.yDomain(h.domain()),m.yDomain(h.domain()),y.yDomain(h.domain()),v.yDomain(p.domain()),g.yDomain(p.domain()),b.yDomain(p.domain()),D.length&&d3.transition(U).call(y),P.length&&d3.transition(X).call(b),M.length&&d3.transition(R).call(m),_.length&&d3.transition(W).call(g),A.length&&d3.transition(q).call(d),O.length&&d3.transition(z).call(v),w.ticks(k/100).tickSize(-L,0),I.select(".x.axis").attr("transform","translate(0,"+L+")"),d3.transition(I.select(".x.axis")).call(w),E.ticks(L/36).tickSize(-k,0),d3.transition(I.select(".y1.axis")).call(E),S.ticks(L/36).tickSize(-k,0),d3.transition(I.select(".y2.axis")).call(S),I.select(".y2.axis").style("opacity",B.length?1:0).attr("transform","translate("+a.range()[1]+",0)"),x.dispatch.on("stateChange",function(e){C.update()}),T.on("tooltipShow",function(e){o&&N(e,f.parentNode)})}),C}var t={top:30,right:20,bottom:50,left:60},n=d3.scale.category20().range(),r=null,i=null,s=!0,o=!0,u=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},a,f,l,c,a=d3.scale.linear(),h=d3.scale.linear(),p=d3.scale.linear(),d=e.models.line().yScale(h),v=e.models.line().yScale(p),m=e.models.multiBar().stacked(!1).yScale(h),g=e.models.multiBar().stacked(!1).yScale(p),y=e.models.stackedArea().yScale(h),b=e.models.stackedArea().yScale(p),w=e.models.axis().scale(a).orient("bottom").tickPadding(5),E=e.models.axis().scale(h).orient("left"),S=e.models.axis().scale(p).orient("right"),x=e.models.legend().height(30),T=d3.dispatch("tooltipShow","tooltipHide"),N=function(t,n){var r=t.pos[0]+(n.offsetLeft||0),i=t.pos[1]+(n.offsetTop||0),s=w.tickFormat()(d.x()(t.point,t.pointIndex)),o=(t.series.yAxis==2?S:E).tickFormat()(d.y()(t.point,t.pointIndex)),a=u(t.series.key,s,o,t,C);e.tooltip.show([r,i],a,undefined,undefined,n.offsetParent)};return d.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),d.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),m.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),m.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),g.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),g.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),y.dispatch.on("tooltipShow",function(e){if(!Math.round(y.y()(e.point)*100))return setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1;e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),y.dispatch.on("tooltipHide",function(e){T.tooltipHide(e)}),b.dispatch.on("tooltipShow",function(e){if(!Math.round(b.y()(e.point)*100))return setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1;e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),b.dispatch.on("tooltipHide",function(e){T.tooltipHide(e)}),d.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),d.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),T.on("tooltipHide",function(){o&&e.tooltip.cleanup()}),C.dispatch=T,C.lines1=d,C.lines2=v,C.bars1=m,C.bars2=g,C.stack1=y,C.stack2=b,C.xAxis=w,C.yAxis1=E,C.yAxis2=S,C.options=e.utils.optionsFunc.bind(C),C.x=function(e){return arguments.length?(getX=e,d.x(e),m.x(e),C):getX},C.y=function(e){return arguments.length?(getY=e,d.y(e),m.y(e),C):getY},C.yDomain1=function(e){return arguments.length?(l=e,C):l},C.yDomain2=function(e){return arguments.length?(c=e,C):c},C.margin=function(e){return arguments.length?(t=e,C):t},C.width=function(e){return arguments.length?(r=e,C):r},C.height=function(e){return arguments.length?(i=e,C):i},C.color=function(e){return arguments.length?(n=e,x.color(e),C):n},C.showLegend=function(e){return arguments.length?(s=e,C):s},C.tooltips=function(e){return arguments.length?(o=e,C):o},C.tooltipContent=function(e){return arguments.length?(u=e,C):u},C},e.models.ohlcBar=function(){"use strict";function x(e){return e.each(function(e){var g=n-t.left-t.right,x=r-t.top-t.bottom,T=d3.select(this);s.domain(y||d3.extent(e[0].values.map(u).concat(p))),v?s.range(w||[g*.5/e[0].values.length,g*(e[0].values.length-.5)/e[0].values.length]):s.range(w||[0,g]),o.domain(b||[d3.min(e[0].values.map(h).concat(d)),d3.max(e[0].values.map(c).concat(d))]).range(E||[x,0]),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]-s.domain()[0]*.01,s.domain()[1]+s.domain()[1]*.01]):s.domain([-1,1])),o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]+o.domain()[0]*.01,o.domain()[1]-o.domain()[1]*.01]):o.domain([-1,1]));var N=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([e[0].values]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),k=C.append("defs"),L=C.append("g"),A=N.select("g");L.append("g").attr("class","nv-ticks"),N.attr("transform","translate("+t.left+","+t.top+")"),T.on("click",function(e,t){S.chartClick({data:e,index:t,pos:d3.event,id:i})}),k.append("clipPath").attr("id","nv-chart-clip-path-"+i).append("rect"),N.select("#nv-chart-clip-path-"+i+" rect").attr("width",g).attr("height",x),A.attr("clip-path",m?"url(#nv-chart-clip-path-"+i+")":"");var O=N.select(".nv-ticks").selectAll(".nv-tick").data(function(e){return e});O.exit().remove();var M=O.enter().append("path").attr("class",function(e,t,n){return(f(e,t)>l(e,t)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+n+"-"+t}).attr("d",function(t,n){var r=g/e[0].values.length*.9;return"m0,0l0,"+(o(f(t,n))-o(c(t,n)))+"l"+ -r/2+",0l"+r/2+",0l0,"+(o(h(t,n))-o(f(t,n)))+"l0,"+(o(l(t,n))-o(h(t,n)))+"l"+r/2+",0l"+ -r/2+",0z"}).attr("transform",function(e,t){return"translate("+s(u(e,t))+","+o(c(e,t))+")"}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),S.elementMouseover({point:t,series:e[0],pos:[s(u(t,n)),o(a(t,n))],pointIndex:n,seriesIndex:0,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),S.elementMouseout({point:t,series:e[0],pointIndex:n,seriesIndex:0,e:d3.event})}).on("click",function(e,t){S.elementClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()}).on("dblclick",function(e,t){S.elementDblClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()});O.attr("class",function(e,t,n){return(f(e,t)>l(e,t)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+n+"-"+t}),d3.transition(O).attr("transform",function(e,t){return"translate("+s(u(e,t))+","+o(c(e,t))+")"}).attr("d",function(t,n){var r=g/e[0].values.length*.9;return"m0,0l0,"+(o(f(t,n))-o(c(t,n)))+"l"+ -r/2+",0l"+r/2+",0l0,"+(o(h(t,n))-o(f(t,n)))+"l0,"+(o(l(t,n))-o(h(t,n)))+"l"+r/2+",0l"+ -r/2+",0z"})}),x}var t={top:0
,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=function(e){return e.open},l=function(e){return e.close},c=function(e){return e.high},h=function(e){return e.low},p=[],d=[],v=!1,m=!0,g=e.utils.defaultColor(),y,b,w,E,S=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return x.dispatch=S,x.options=e.utils.optionsFunc.bind(x),x.x=function(e){return arguments.length?(u=e,x):u},x.y=function(e){return arguments.length?(a=e,x):a},x.open=function(e){return arguments.length?(f=e,x):f},x.close=function(e){return arguments.length?(l=e,x):l},x.high=function(e){return arguments.length?(c=e,x):c},x.low=function(e){return arguments.length?(h=e,x):h},x.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,x):t},x.width=function(e){return arguments.length?(n=e,x):n},x.height=function(e){return arguments.length?(r=e,x):r},x.xScale=function(e){return arguments.length?(s=e,x):s},x.yScale=function(e){return arguments.length?(o=e,x):o},x.xDomain=function(e){return arguments.length?(y=e,x):y},x.yDomain=function(e){return arguments.length?(b=e,x):b},x.xRange=function(e){return arguments.length?(w=e,x):w},x.yRange=function(e){return arguments.length?(E=e,x):E},x.forceX=function(e){return arguments.length?(p=e,x):p},x.forceY=function(e){return arguments.length?(d=e,x):d},x.padData=function(e){return arguments.length?(v=e,x):v},x.clipEdge=function(e){return arguments.length?(m=e,x):m},x.color=function(t){return arguments.length?(g=e.utils.getColor(t),x):g},x.id=function(e){return arguments.length?(i=e,x):i},x},e.models.pie=function(){"use strict";function S(e){return e.each(function(e){function q(e){var t=(e.startAngle+e.endAngle)*90/Math.PI-90;return t>90?t-180:t}function R(e){e.endAngle=isNaN(e.endAngle)?0:e.endAngle,e.startAngle=isNaN(e.startAngle)?0:e.startAngle,m||(e.innerRadius=0);var t=d3.interpolate(this._current,e);return this._current=t(0),function(e){return A(t(e))}}function U(e){e.innerRadius=0;var t=d3.interpolate({startAngle:0,endAngle:0},e);return function(e){return A(t(e))}}var o=n-t.left-t.right,f=r-t.top-t.bottom,S=Math.min(o,f)/2,x=S-S/5,T=d3.select(this),N=T.selectAll(".nv-wrap.nv-pie").data(e),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+u),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-pie"),k.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+t.left+","+t.top+")"),L.select(".nv-pie").attr("transform","translate("+o/2+","+f/2+")"),L.select(".nv-pieLabels").attr("transform","translate("+o/2+","+f/2+")"),T.on("click",function(e,t){E.chartClick({data:e,index:t,pos:d3.event,id:u})});var A=d3.svg.arc().outerRadius(x);y&&A.startAngle(y),b&&A.endAngle(b),m&&A.innerRadius(S*w);var O=d3.layout.pie().sort(null).value(function(e){return e.disabled?0:s(e)}),M=N.select(".nv-pie").selectAll(".nv-slice").data(O),_=N.select(".nv-pieLabels").selectAll(".nv-label").data(O);M.exit().remove(),_.exit().remove();var D=M.enter().append("g").attr("class","nv-slice").on("mouseover",function(e,t){d3.select(this).classed("hover",!0),E.elementMouseover({label:i(e.data),value:s(e.data),point:e.data,pointIndex:t,pos:[d3.event.pageX,d3.event.pageY],id:u})}).on("mouseout",function(e,t){d3.select(this).classed("hover",!1),E.elementMouseout({label:i(e.data),value:s(e.data),point:e.data,index:t,id:u})}).on("click",function(e,t){E.elementClick({label:i(e.data),value:s(e.data),point:e.data,index:t,pos:d3.event,id:u}),d3.event.stopPropagation()}).on("dblclick",function(e,t){E.elementDblClick({label:i(e.data),value:s(e.data),point:e.data,index:t,pos:d3.event,id:u}),d3.event.stopPropagation()});M.attr("fill",function(e,t){return a(e,t)}).attr("stroke",function(e,t){return a(e,t)});var P=D.append("path").each(function(e){this._current=e});M.select("path").transition().attr("d",A).attrTween("d",R);if(l){var H=d3.svg.arc().innerRadius(0);c&&(H=A),h&&(H=d3.svg.arc().outerRadius(A.outerRadius())),_.enter().append("g").classed("nv-label",!0).each(function(e,t){var n=d3.select(this);n.attr("transform",function(e){if(g){e.outerRadius=x+10,e.innerRadius=x+15;var t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+H.centroid(e)+") rotate("+t+")"}return e.outerRadius=S+10,e.innerRadius=S+15,"translate("+H.centroid(e)+")"}),n.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),n.append("text").style("text-anchor",g?(e.startAngle+e.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var B={},j=14,F=140,I=function(e){return Math.floor(e[0]/F)*F+","+Math.floor(e[1]/j)*j};_.transition().attr("transform",function(e){if(g){e.outerRadius=x+10,e.innerRadius=x+15;var t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+H.centroid(e)+") rotate("+t+")"}e.outerRadius=S+10,e.innerRadius=S+15;var n=H.centroid(e),r=I(n);return B[r]&&(n[1]-=j),B[I(n)]=!0,"translate("+n+")"}),_.select(".nv-label text").style("text-anchor",g?(d.startAngle+d.endAngle)/2<Math.PI?"start":"end":"middle").text(function(e,t){var n=(e.endAngle-e.startAngle)/(2*Math.PI),r={key:i(e.data),value:s(e.data),percent:d3.format("%")(n)};return e.value&&n>v?r[p]:""})}}),S}var t={top:0,right:0,bottom:0,left:0},n=500,r=500,i=function(e){return e.x},s=function(e){return e.y},o=function(e){return e.description},u=Math.floor(Math.random()*1e4),a=e.utils.defaultColor(),f=d3.format(",.2f"),l=!0,c=!0,h=!1,p="key",v=.02,m=!1,g=!1,y=!1,b=!1,w=.5,E=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return S.dispatch=E,S.options=e.utils.optionsFunc.bind(S),S.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,S):t},S.width=function(e){return arguments.length?(n=e,S):n},S.height=function(e){return arguments.length?(r=e,S):r},S.values=function(t){return e.log("pie.values() is no longer supported."),S},S.x=function(e){return arguments.length?(i=e,S):i},S.y=function(e){return arguments.length?(s=d3.functor(e),S):s},S.description=function(e){return arguments.length?(o=e,S):o},S.showLabels=function(e){return arguments.length?(l=e,S):l},S.labelSunbeamLayout=function(e){return arguments.length?(g=e,S):g},S.donutLabelsOutside=function(e){return arguments.length?(h=e,S):h},S.pieLabelsOutside=function(e){return arguments.length?(c=e,S):c},S.labelType=function(e){return arguments.length?(p=e,p=p||"key",S):p},S.donut=function(e){return arguments.length?(m=e,S):m},S.donutRatio=function(e){return arguments.length?(w=e,S):w},S.startAngle=function(e){return arguments.length?(y=e,S):y},S.endAngle=function(e){return arguments.length?(b=e,S):b},S.id=function(e){return arguments.length?(u=e,S):u},S.color=function(t){return arguments.length?(a=e.utils.getColor(t),S):a},S.valueFormat=function(e){return arguments.length?(f=e,S):f},S.labelThreshold=function(e){return arguments.length?(v=e,S):v},S},e.models.pieChart=function(){"use strict";function v(e){return e.each(function(e){var u=d3.select(this),a=this,f=(i||parseInt(u.style("width"))||960)-r.left-r.right,d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom;v.update=function(){u.transition().call(v)},v.container=this,l.disabled=e.map(function(e){return!!e.disabled});if(!c){var m;c={};for(m in l)l[m]instanceof Array?c[m]=l[m].slice(0):c[m]=l[m]}if(!e||!e.length){var g=u.selectAll(".nv-noData").data([h]);return g.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),g.attr("x",r.left+f/2).attr("y",r.top+d/2).text(function(e){return e}),v}u.selectAll(".nv-noData").remove();var y=u.selectAll("g.nv-wrap.nv-pieChart").data([e]),b=y.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),w=y.select("g");b.append("g").attr("class","nv-pieWrap"),b.append("g").attr("class","nv-legendWrap"),o&&(n.width(f).key(t.x()),y.select(".nv-legendWrap").datum(e).call(n),r.top!=n.height()&&(r.top=n.height(),d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom),y.select(".nv-legendWrap").attr("transform","translate(0,"+ -r.top+")")),y.attr("transform","translate("+r.left+","+r.top+")"),t.width(f).height(d);var E=w.select(".nv-pieWrap").datum([e]);d3.transition(E).call(t),n.dispatch.on("stateChange",function(e){l=e,p.stateChange(l),v.update()}),t.dispatch.on("elementMouseout.tooltip",function(e){p.tooltipHide(e)}),p.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),l.disabled=t.disabled),v.update()})}),v}var t=e.models.pie(),n=e.models.legend(),r={top:30,right:20,bottom:20,left:20},i=null,s=null,o=!0,u=e.utils.defaultColor(),a=!0,f=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+t+"</p>"},l={},c=null,h="No Data Available.",p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),d=function(n,r){var i=t.description()(n.point)||t.x()(n.point),s=n.pos[0]+(r&&r.offsetLeft||0),o=n.pos[1]+(r&&r.offsetTop||0),u=t.valueFormat()(t.y()(n.point)),a=f(i,u,n,v);e.tooltip.show([s,o],a,n.value<0?"n":"s",null,r)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+r.left,e.pos[1]+r.top],p.tooltipShow(e)}),p.on("tooltipShow",function(e){a&&d(e)}),p.on("tooltipHide",function(){a&&e.tooltip.cleanup()}),v.legend=n,v.dispatch=p,v.pie=t,d3.rebind(v,t,"valueFormat","values","x","y","description","id","showLabels","donutLabelsOutside","pieLabelsOutside","labelType","donut","donutRatio","labelThreshold"),v.options=e.utils.optionsFunc.bind(v),v.margin=function(e){return arguments.length?(r.top=typeof e.top!="undefined"?e.top:r.top,r.right=typeof e.right!="undefined"?e.right:r.right,r.bottom=typeof e.bottom!="undefined"?e.bottom:r.bottom,r.left=typeof e.left!="undefined"?e.left:r.left,v):r},v.width=function(e){return arguments.length?(i=e,v):i},v.height=function(e){return arguments.length?(s=e,v):s},v.color=function(r){return arguments.length?(u=e.utils.getColor(r),n.color(u),t.color(u),v):u},v.showLegend=function(e){return arguments.length?(o=e,v):o},v.tooltips=function(e){return arguments.length?(a=e,v):a},v.tooltipContent=function(e){return arguments.length?(f=e,v):f},v.state=function(e){return arguments.length?(l=e,v):l},v.defaultState=function(e){return arguments.length?(c=e,v):c},v.noData=function(e){return arguments.length?(h=e,v):h},v},e.models.scatter=function(){"use strict";function I(q){return q.each(function(I){function Q(){if(!g)return!1;var e,i=d3.merge(I.map(function(e,t){return e.values.map(function(e,n){var r=f(e,n),i=l(e,n);return[o(r)+Math.random()*1e-7,u(i)+Math.random()*1e-7,t,n,e]}).filter(function(e,t){return b(e[4],t)})}));if(D===!0){if(x){var a=X.select("defs").selectAll(".nv-point-clips").data([s]).enter();a.append("clipPath").attr("class","nv-point-clips").attr("id","nv-points-clip-"+s);var c=X.select("#nv-points-clip-"+s).selectAll("circle").data(i);c.enter().append("circle").attr("r",T),c.exit().remove(),c.attr("cx",function(e){return e[0]}).attr("cy",function(e){return e[1]}),X.select(".nv-point-paths").attr("clip-path","url(#nv-points-clip-"+s+")")}i.length&&(i.push([o.range()[0]-20,u.range()[0]-20,null,null]),i.push([o.range()[1]+20,u.range()[1]+20,null,null]),i.push([o.range()[0]-20,u.range()[0]+20,null,null]),i.push([o.range()[1]+20,u.range()[1]-20,null,null]));var h=d3.geom.polygon([[-10,-10],[-10,r+10],[n+10,r+10],[n+10,-10]]),p=d3.geom.voronoi(i).map(function(e,t){return{data:h.clip(e),series:i[t][2],point:i[t][3]}}),d=X.select(".nv-point-paths").selectAll("path").data(p);d.enter().append("path").attr("class",function(e,t){return"nv-path-"+t}),d.exit().remove(),d.attr("d",function(e){return e.data.length===0?"M 0 0":"M"+e.data.join("L")+"Z"});var v=function(e,n){if(F)return 0;var r=I[e.series];if(typeof r=="undefined")return;var i=r.values[e.point];n({point:i,series:r,pos:[o(f(i,e.point))+t.left,u(l(i,e.point))+t.top],seriesIndex:e.series,pointIndex:e.point})};d.on("click",function(e){v(e,_.elementClick)}).on("mouseover",function(e){v(e,_.elementMouseover)}).on("mouseout",function(e,t){v(e,_.elementMouseout)})}else X.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(e,n){if(F||!I[e.series])return 0;var r=I[e.series],i=r.values[n];_.elementClick({point:i,series:r,pos:[o(f(i,n))+t.left,u(l(i,n))+t.top],seriesIndex:e.series,pointIndex:n})}).on("mouseover",function(e,n){if(F||!I[e.series])return 0;var r=I[e.series],i=r.values[n];_.elementMouseover({point:i,series:r,pos:[o(f(i,n))+t.left,u(l(i,n))+t.top],seriesIndex:e.series,pointIndex:n})}).on("mouseout",function(e,t){if(F||!I[e.series])return 0;var n=I[e.series],r=n.values[t];_.elementMouseout({point:r,series:n,seriesIndex:e.series,pointIndex:t})});F=!1}var q=n-t.left-t.right,R=r-t.top-t.bottom,U=d3.select(this);I.forEach(function(e,t){e.values.forEach(function(e){e.series=t})});var W=N&&C&&A?[]:d3.merge(I.map(function(e){return e.values.map(function(e,t){return{x:f(e,t),y:l(e,t),size:c(e,t)}})}));o.domain(N||d3.extent(W.map(function(e){return e.x}).concat(d))),w&&I[0]?o.range(k||[(q*E+q)/(2*I[0].values.length),q-q*(1+E)/(2*I[0].values.length)]):o.range(k||[0,q]),u.domain(C||d3.extent(W.map(function(e){return e.y}).concat(v))).range(L||[R,0]),a.domain(A||d3.extent(W.map(function(e){return e.size}).concat(m))).range(O||[16,256]);if(o.domain()[0]===o.domain()[1]||u.domain()[0]===u.domain()[1])M=!0;o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]-o.domain()[0]*.01,o.domain()[1]+o.domain()[1]*.01]):o.domain([-1,1])),u.domain()[0]===u.domain()[1]&&(u.domain()[0]?u.domain([u.domain()[0]-u.domain()[0]*.01,u.domain()[1]+u.domain()[1]*.01]):u.domain([-1,1])),isNaN(o.domain()[0])&&o.domain([-1,1]),isNaN(u.domain()[0])&&u.domain([-1,1]),P=P||o,H=H||u,B=B||a;var X=U.selectAll("g.nv-wrap.nv-scatter").data([I]),V=X.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+s+(M?" nv-single-point":"")),$=V.append("defs"),J=V.append("g"),K=X.select("g");J.append("g").attr("class","nv-groups"),J.append("g").attr("class","nv-point-paths"),X.attr("transform","translate("+t.left+","+t.top+")"),$.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),X.select("#nv-edge-clip-"+s+" rect").attr("width",q).attr("height",R>0?R:0),K.attr("clip-path",S?"url(#nv-edge-clip-"+s+")":""),F=!0;var G=X.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});G.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),G.exit().remove(),G.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}),G.transition().style("fill",function(e,t){return i(e,t)}).style("stroke",function(e,t){return i(e,t)}).style("stroke-opacity",1).style("fill-opacity",.5);if(p){var Y=G.selectAll("circle.nv-point").data(function(e){return e.values},y);Y.enter().append("circle").style("fill",function(e,t){return e.color}).style("stroke",function(e,t){return e.color}).attr("cx",function(t,n){return e.utils.NaNtoZero(P(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(H(l(t,n)))}).attr("r",function(e,t){return Math.sqrt(a(c(e,t))/Math.PI)}),Y.exit().remove(),G.exit().selectAll("path.nv-point").transition().attr("cx",function(t,n){return e.utils.NaNtoZero(o(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(u(l(t,n)))}).remove(),Y.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0).classed("hover",!1)}),Y.transition().attr("cx",function(t,n){return e.utils.NaNtoZero(o(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(u(l(t,n)))}).attr("r",function(e,t){return Math.sqrt(a(c(e,t))/Math.PI)})}else{var Y=G.selectAll("path.nv-point").data(function(e){return e.values});Y.enter().append("path").style("fill",function(e,t){return e.color}).style("stroke",function(e,t){return e.color}).attr("transform",function(e,t){return"translate("+P(f(e,t))+","+H(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return a(c(e,t))})),Y.exit().remove(),G.exit().selectAll("path.nv-point").transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).remove(),Y.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0).classed("hover",!1)}),Y.transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return a(c(e,t))}))}clearTimeout(j),j=setTimeout(Q,300),P=o.copy(),H=u.copy(),B=a.copy()}),I}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=d3.scale.linear(),u=d3.scale.linear(),a=d3.scale.linear(),f=function(e){return e.x},l=function(e){return e.y},c=function(e){return e.size||1},h=function(e){return e.shape||"circle"},p=!0,d=[],v=[],m=[],g=!0,y=null,b=function(e){return!e.notActive},w=!1,E=.1,S=!1,x=!0,T=function(){return 25},N=null,C=null,k=null,L=null,A=null,O=null,M=!1,_=d3.dispatch("elementClick","elementMouseover","elementMouseout"),D=!0,P,H,B,j,F=!1;return I.clearHighlights=function(){d3.selectAll(".nv-chart-"+s+" .nv-point.hover").classed("hover",!1)},I.highlightPoint=function(e,t,n){d3.select(".nv-chart-"+s+" .nv-series-"+e+" .nv-point-"+t).classed("hover",n)},_.on("elementMouseover.point",function(e){g&&I.highlightPoint(e.seriesIndex,e.pointIndex,!0)}),_.on("elementMouseout.point",function(e){g&&I.highlightPoint(e.seriesIndex,e.pointIndex,!1)}),I.dispatch=_,I.options=e.utils.optionsFunc.bind(I),I.x=function(e){return arguments.length?(f=d3.functor(e),I):f},I.y=function(e){return arguments.length?(l=d3.functor(e),I):l},I.size=function(e){return arguments.length?(c=d3.functor(e),I):c},I.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,I):t},I.width=function(e){return arguments.length?(n=e,I):n},I.height=function(e){return arguments.length?(r=e,I):r},I.xScale=function(e){return arguments.length?(o=e,I):o},I.yScale=function(e){return arguments.length?(u=e,I):u},I.zScale=function(e){return arguments.length?(a=e,I):a},I.xDomain=function(e){return arguments.length?(N=e,I):N},I.yDomain=function(e){return arguments.length?(C=e,I):C},I.sizeDomain=function(e){return arguments.length?(A=e,I):A},I.xRange=function(e){return arguments.length?(k=e,I):k},I.yRange=function(e){return arguments.length?(L=e,I):L},I.sizeRange=function(e){return arguments.length?(O=e,I):O},I.forceX=function(e){return arguments.length?(d=e,I):d},I.forceY=function(e){return arguments.length?(v=e,I):v},I.forceSize=function(e){return arguments.length?(m=e,I):m},I.interactive=function(e){return arguments.length?(g=e,I):g},I.pointKey=function(e){return arguments.length?(y=e,I):y},I.pointActive=function(e){return arguments.length?(b=e,I):b},I.padData=function(e){return arguments.length?(w=e,I):w},I.padDataOuter=function(e){return arguments.length?(E=e,I):E},I.clipEdge=function(e){return arguments.length?(S=e,I):S},I.clipVoronoi=function(e){return arguments.length?(x=e,I):x},I.useVoronoi=function(e){return arguments.length?(D=e,D===!1&&(x=!1),I):D},I.clipRadius=function(e){return arguments.length?(T=e,I):T},I.color=function(t){return arguments.length?(i=e.utils.getColor(t),I):i},I.shape=function(e){return arguments.length?(h=e,I):h},I.onlyCircles=function(e){return arguments.length?(p=e,I):p},I.id=function(e){return arguments.length?(s=e,I):s},I.singlePoint=function(e){return arguments.length?(M=e,I):M},I},e.models.scatterChart=function(){"use strict";function F(e){return e.each(function(e){function K(){if(T)return X.select(".nv-point-paths").style("pointer-events","all"),!1;X.select(".nv-point-paths").style("pointer-events","none");var i=d3.mouse(this);h.distortion(x).focus(i[0]),p.distortion(x).focus(i[1]),X.select(".nv-scatterWrap").call(t),b&&X.select(".nv-x.nv-axis").call(n),w&&X.select(".nv-y.nv-axis").call(r),X.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),X.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var C=d3.select(this),k=this,L=(f||parseInt(C.style("width"))||960)-a.left-a.right,I=(l||parseInt(C.style("height"))||400)-a.top-a.bottom;F.update=function(){C.transition().duration(D).call(F)},F.container=this,A.disabled=e.map(function(e){return!!e.disabled});if(!O){var q;O={};for(q in A)A[q]instanceof Array?O[q]=A[q].slice(0):O[q]=A[q]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var R=C.selectAll(".nv-noData").data([_]);return R.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),R.attr("x",a.left+L/2).attr("y",a.top+I/2).text(function(e){return e}),F}C.selectAll(".nv-noData").remove(),P=P||h,H=H||p;var U=C.selectAll("g.nv-wrap.nv-scatterChart").data([e]),z=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+t.id()),W=z.append("g"),X=U.select("g");W.append("rect").attr("class","nvd3 nv-background"),W.append("g").attr("class","nv-x nv-axis"),W.append("g").attr("class","nv-y nv-axis"),W.append("g").attr("class","nv-scatterWrap"),W.append("g").attr("class","nv-distWrap"),W.append("g").attr("class","nv-legendWrap"),W.append("g").attr("class","nv-controlsWrap");if(y){var V=S?L/2:L;i.width(V),U.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),I=(l||parseInt(C.style("height"))||400)-a.top-a.bottom),U.select(".nv-legendWrap").attr("transform","translate("+(L-V)+","+ -a.top+")")}S&&(s.width(180).color(["#444"]),X.select(".nv-controlsWrap").datum(j).attr("transform","translate(0,"+ -a.top+")").call(s)),U.attr("transform","translate("+a.left+","+a.top+")"),E&&X.select(".nv-y.nv-axis").attr("transform","translate("+L+",0)"),t.width(L).height(I).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),d!==0&&t.xDomain(null),v!==0&&t.yDomain(null),U.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t);if(d!==0){var $=h.domain()[1]-h.domain()[0];t.xDomain([h.domain()[0]-d*$,h.domain()[1]+d*$])}if(v!==0){var J=p.domain()[1]-p.domain()[0];t.yDomain([p.domain()[0]-v*J,p.domain()[1]+v*J])}(v!==0||d!==0)&&U.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),b&&(n.scale(h).ticks(n.ticks()&&n.ticks().length?n.ticks():L/100).tickSize(-I,0),X.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n)),w&&(r.scale(p).ticks(r.ticks()&&r.ticks().length?r.ticks():I/36).tickSize(-L,0),X.select(".nv-y.nv-axis").call(r)),m&&(o.getData(t.x()).scale(h).width(L).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),W.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),X.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),g&&(u.getData(t.y()).scale(p).width(I).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),W.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),X.select(".nv-distributionY").attr("transform","translate("+(E?L:-u.size())+",0)").datum(e.filter(function(e){return!e.disabled})).call(u)),d3.fisheye&&(X.select(".nv-background").attr("width",L).attr("height",I),X.select(".nv-background").on("mousemove",K),X.select(".nv-background").on("click",function(){T=!T}),t.dispatch.on("elementClick.freezeFisheye",function(){T=!T})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,x=e.disabled?0:2.5,X.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),X.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(x).focus(0),p.distortion(x).focus(0),X.select(".nv-scatterWrap").call(t),X.select(".nv-x.nv-axis").call(n),X.select(".nv-y.nv-axis").call(r)):T=!1,F.update()}),i.dispatch.on("stateChange",function(e){A.disabled=e.disabled,M.stateChange(A),F.update()}),t.dispatch.on("elementMouseover.tooltip",function(e){d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",function(t,n){return e.pos[1]-I}),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],M.tooltipShow(e)}),M.on("tooltipShow",function(e){N&&B(e,k.parentNode)}),M.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),A.disabled=t.disabled),F.update()}),P=h.copy(),H=p.copy()}),F}var t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=0,v=0,m=!1,g=!1,y=!0,b=!0,w=!0,E=!1,S=!!d3.fisheye,x=0,T=!1,N=!0,C=function(e,t,n){return"<strong>"+t+"</strong>"},k=function(e,t,n){return"<strong>"+n+"</strong>"},L=null,A={},O=null,M=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),_="No Data Available.",D=250;t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient(E?"right":"left").tickPadding(10),o.axis("x"),u.axis("y"),s.updateState(!1);var P,H,B=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));C!=null&&e.tooltip.show([f,l],C(i.series.key,v,m,i,F),"n",1,s,"x-nvtooltip"),k!=null&&e.tooltip.show([c,d],k(i.series.key,v,m,i,F),"e",1,s,"y-nvtooltip"),L!=null&&e.tooltip.show([o,u],L(i.series.key,v,m,i,F),i.value<0?"n":"s",null,s)},j=[{key:"Magnify",disabled:!0}];return t.dispatch.on("elementMouseout.tooltip",function(e){M.tooltipHide(e),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",u.size())}),M.on("tooltipHide",function(){N&&e.tooltip.cleanup()}),F.dispatch=M,F.scatter=t,F.legend=i,F.controls=s,F.xAxis=n,F.yAxis=r,F.distX=o,F.distY=u,d3.rebind(F,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),F.options=e.utils.optionsFunc.bind(F),F.margin=function(e){return arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof e.right!="undefined"?e.right:a.right,a.bottom=typeof e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof e.left!="undefined"?e.left:a.left,F):a},F.width=function(e){return arguments.length?(f=e,F):f},F.height=function(e){return arguments.length?(l=e,F):l},F.color=function(t){return arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.color(c),F):c},F.showDistX=function(e){return arguments.length?(m=e,F):m},F.showDistY=function(e){return arguments.length?(g=e,F):g},F.showControls=function(e){return arguments.length?(S=e,F):S},F.showLegend=function(e){return arguments.length?(y=e,F):y},F.showXAxis=function(e){return arguments.length?(b=e,F):b},F.showYAxis=function(e){return arguments.length?(w=e,F):w},F.rightAlignYAxis=function(e){return arguments.length?(E=e,r.orient(e?"right":"left"),F):E},F.fisheye=function(e){return arguments.length?(x=e,F):x},F.xPadding=function(e){return arguments.length?(d=e,F):d},F.yPadding=function(e){return arguments.length?(v=e,F):v},F.tooltips=function(e){return arguments.length?(N=e,F):N},F.tooltipContent=function(e){return arguments.length?(L=e,F):L},F.tooltipXContent=function(e){return arguments.length?(C=e,F):C},F.tooltipYContent=function(e){return arguments.length?(k=e,F):k},F.state=function(e){return arguments.length?(A=e,F):A},F.defaultState=function(e){return arguments.length?(O=e,F):O},F.noData=function(e){return arguments.length?(_=e,F):_},F.transitionDuration=function(e){return arguments.length?(D=e,F):D},F},e.models.scatterPlusLineChart=function(){"use strict";function B(e){return e.each(function(e){function $(){if(S)return z.select(".nv-point-paths").style("pointer-events","all"),!1;z.select(".nv-point-paths").style("pointer-events","none");var i=d3.mouse(this);h.distortion(E).focus(i[0]),p.distortion(E).focus(i[1]),z.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),g&&z.select(".nv-x.nv-axis").call(n),y&&z.select(".nv-y.nv-axis").call(r),z.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),z.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var T=d3.select(this),N=this,C=(f||parseInt(T.style("width"))||960)-a.left-a.right,j=(l||parseInt(T.style("height"))||400)-a.top-a.bottom;B.update=function(){T.transition().duration(M).call(B)},B.container=this,k.disabled=e.map(function(e){return!!e.disabled});if(!L){var F;L={};for(F in k)k[F]instanceof Array?L[F]=k[F].slice(0):L[F]=k[F]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var I=T.selectAll(".nv-noData").data([O]);return I.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),I.attr("x",a.left+C/2).attr("y",a.top+j/2).text(function(e){return e}),B}T.selectAll(".nv-noData").remove(),h=t.xScale(),p=t.yScale(),_=_||h,D=D||p;var q=T.selectAll("g.nv-wrap.nv-scatterChart").data([e]),R=q.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+t.id()),U=R.append("g"),z=q.select("g");U.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),U.append("g").attr("class","nv-x nv-axis"),U.append("g").attr("class","nv-y nv-axis"),U.append("g").attr("class","nv-scatterWrap"),U.append("g").attr("class","nv-regressionLinesWrap"),U.append("g").attr("class","nv-distWrap"),U.append("g").attr("class","nv-legendWrap"),U.append("g").attr("class","nv-controlsWrap"),q.attr("transform","translate("+a.left+","+a.top+")"),b&&z.select(".nv-y.nv-axis").attr("transform","translate("+C+",0)"),m&&(i.width(C/2),q.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),j=(l||parseInt(T.style("height"))||400)-a.top-a.bottom),q.select(".nv-legendWrap").attr("transform","translate("+C/2+","+ -a.top+")")),w&&(s.width(180).color(["#444"]),z.select(".nv-controlsWrap").datum(H).attr("transform","translate(0,"+ -a.top+")").call(s)),t.width(C).height(j).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),q.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),q.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+t.id()+")");var W=q.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(e){return e});W.enter().append("g").attr("class","nv-regLines");var X=W.selectAll(".nv-regLine").data(function(e){return[e]}),V=X.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0);X.transition().attr("x1",h.range()[0]).attr("x2",h.range()[1]).attr("y1",function(e,t){return p(h.domain()[0]*e.slope+e.intercept)}).attr("y2",function(e,t){return p(h.domain()[1]*e.slope+e.intercept)}).style("stroke",function(e,t,n){return c(e,n)}).style("stroke-opacity",function(e,t){return e.disabled||typeof e.slope=="undefined"||typeof e.intercept=="undefined"?0:1}),g&&(n.scale(h).ticks(n.ticks()?n.ticks():C/100).tickSize(-j,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n)),y&&(r.scale(p).ticks(r.ticks()?r.ticks():j/36).tickSize(-C,0),z.select(".nv-y.nv-axis").call(r)),d&&(o.getData(t.x()).scale(h).width(C).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),U.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),z.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),v&&(u.getData(t.y()).scale(p).width(
j).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),U.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),z.select(".nv-distributionY").attr("transform","translate("+(b?C:-u.size())+",0)").datum(e.filter(function(e){return!e.disabled})).call(u)),d3.fisheye&&(z.select(".nv-background").attr("width",C).attr("height",j),z.select(".nv-background").on("mousemove",$),z.select(".nv-background").on("click",function(){S=!S}),t.dispatch.on("elementClick.freezeFisheye",function(){S=!S})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,E=e.disabled?0:2.5,z.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),z.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(E).focus(0),p.distortion(E).focus(0),z.select(".nv-scatterWrap").call(t),z.select(".nv-x.nv-axis").call(n),z.select(".nv-y.nv-axis").call(r)):S=!1,B.update()}),i.dispatch.on("stateChange",function(e){k=e,A.stateChange(k),B.update()}),t.dispatch.on("elementMouseover.tooltip",function(e){d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",e.pos[1]-j),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],A.tooltipShow(e)}),A.on("tooltipShow",function(e){x&&P(e,N.parentNode)}),A.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),k.disabled=t.disabled),B.update()}),_=h.copy(),D=p.copy()}),B}var t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=!1,v=!1,m=!0,g=!0,y=!0,b=!1,w=!!d3.fisheye,E=0,S=!1,x=!0,T=function(e,t,n){return"<strong>"+t+"</strong>"},N=function(e,t,n){return"<strong>"+n+"</strong>"},C=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+r+"</p>"},k={},L=null,A=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),O="No Data Available.",M=250;t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient(b?"right":"left").tickPadding(10),o.axis("x"),u.axis("y"),s.updateState(!1);var _,D,P=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));T!=null&&e.tooltip.show([f,l],T(i.series.key,v,m,i,B),"n",1,s,"x-nvtooltip"),N!=null&&e.tooltip.show([c,d],N(i.series.key,v,m,i,B),"e",1,s,"y-nvtooltip"),C!=null&&e.tooltip.show([o,u],C(i.series.key,v,m,i.point.tooltip,i,B),i.value<0?"n":"s",null,s)},H=[{key:"Magnify",disabled:!0}];return t.dispatch.on("elementMouseout.tooltip",function(e){A.tooltipHide(e),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",u.size())}),A.on("tooltipHide",function(){x&&e.tooltip.cleanup()}),B.dispatch=A,B.scatter=t,B.legend=i,B.controls=s,B.xAxis=n,B.yAxis=r,B.distX=o,B.distY=u,d3.rebind(B,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),B.options=e.utils.optionsFunc.bind(B),B.margin=function(e){return arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof e.right!="undefined"?e.right:a.right,a.bottom=typeof e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof e.left!="undefined"?e.left:a.left,B):a},B.width=function(e){return arguments.length?(f=e,B):f},B.height=function(e){return arguments.length?(l=e,B):l},B.color=function(t){return arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.color(c),B):c},B.showDistX=function(e){return arguments.length?(d=e,B):d},B.showDistY=function(e){return arguments.length?(v=e,B):v},B.showControls=function(e){return arguments.length?(w=e,B):w},B.showLegend=function(e){return arguments.length?(m=e,B):m},B.showXAxis=function(e){return arguments.length?(g=e,B):g},B.showYAxis=function(e){return arguments.length?(y=e,B):y},B.rightAlignYAxis=function(e){return arguments.length?(b=e,r.orient(e?"right":"left"),B):b},B.fisheye=function(e){return arguments.length?(E=e,B):E},B.tooltips=function(e){return arguments.length?(x=e,B):x},B.tooltipContent=function(e){return arguments.length?(C=e,B):C},B.tooltipXContent=function(e){return arguments.length?(T=e,B):T},B.tooltipYContent=function(e){return arguments.length?(N=e,B):N},B.state=function(e){return arguments.length?(k=e,B):k},B.defaultState=function(e){return arguments.length?(L=e,B):L},B.noData=function(e){return arguments.length?(O=e,B):O},B.transitionDuration=function(e){return arguments.length?(M=e,B):M},B},e.models.sparkline=function(){"use strict";function d(e){return e.each(function(e){var i=n-t.left-t.right,d=r-t.top-t.bottom,v=d3.select(this);s.domain(l||d3.extent(e,u)).range(h||[0,i]),o.domain(c||d3.extent(e,a)).range(p||[d,0]);var m=v.selectAll("g.nv-wrap.nv-sparkline").data([e]),g=m.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline"),b=g.append("g"),w=m.select("g");m.attr("transform","translate("+t.left+","+t.top+")");var E=m.selectAll("path").data(function(e){return[e]});E.enter().append("path"),E.exit().remove(),E.style("stroke",function(e,t){return e.color||f(e,t)}).attr("d",d3.svg.line().x(function(e,t){return s(u(e,t))}).y(function(e,t){return o(a(e,t))}));var S=m.selectAll("circle.nv-point").data(function(e){function n(t){if(t!=-1){var n=e[t];return n.pointIndex=t,n}return null}var t=e.map(function(e,t){return a(e,t)}),r=n(t.lastIndexOf(o.domain()[1])),i=n(t.indexOf(o.domain()[0])),s=n(t.length-1);return[i,r,s].filter(function(e){return e!=null})});S.enter().append("circle"),S.exit().remove(),S.attr("cx",function(e,t){return s(u(e,e.pointIndex))}).attr("cy",function(e,t){return o(a(e,e.pointIndex))}).attr("r",2).attr("class",function(e,t){return u(e,e.pointIndex)==s.domain()[1]?"nv-point nv-currentValue":a(e,e.pointIndex)==o.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),d}var t={top:2,right:0,bottom:2,left:0},n=400,r=32,i=!0,s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=e.utils.getColor(["#000"]),l,c,h,p;return d.options=e.utils.optionsFunc.bind(d),d.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,d):t},d.width=function(e){return arguments.length?(n=e,d):n},d.height=function(e){return arguments.length?(r=e,d):r},d.x=function(e){return arguments.length?(u=d3.functor(e),d):u},d.y=function(e){return arguments.length?(a=d3.functor(e),d):a},d.xScale=function(e){return arguments.length?(s=e,d):s},d.yScale=function(e){return arguments.length?(o=e,d):o},d.xDomain=function(e){return arguments.length?(l=e,d):l},d.yDomain=function(e){return arguments.length?(c=e,d):c},d.xRange=function(e){return arguments.length?(h=e,d):h},d.yRange=function(e){return arguments.length?(p=e,d):p},d.animate=function(e){return arguments.length?(i=e,d):i},d.color=function(t){return arguments.length?(f=e.utils.getColor(t),d):f},d},e.models.sparklinePlus=function(){"use strict";function v(e){return e.each(function(c){function O(){if(a)return;var e=C.selectAll(".nv-hoverValue").data(u),r=e.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);e.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),e.attr("transform",function(e){return"translate("+s(t.x()(c[e],e))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1);if(!u.length)return;r.append("line").attr("x1",0).attr("y1",-n.top).attr("x2",0).attr("y2",b),r.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-n.top).attr("text-anchor","end").attr("dy",".9em"),C.select(".nv-hoverValue .nv-xValue").text(f(t.x()(c[u[0]],u[0]))),r.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-n.top).attr("text-anchor","start").attr("dy",".9em"),C.select(".nv-hoverValue .nv-yValue").text(l(t.y()(c[u[0]],u[0])))}function M(){function r(e,n){var r=Math.abs(t.x()(e[0],0)-n),i=0;for(var s=0;s<e.length;s++)Math.abs(t.x()(e[s],s)-n)<r&&(r=Math.abs(t.x()(e[s],s)-n),i=s);return i}if(a)return;var e=d3.mouse(this)[0]-n.left;u=[r(c,Math.round(s.invert(e)))],O()}var m=d3.select(this),g=(r||parseInt(m.style("width"))||960)-n.left-n.right,b=(i||parseInt(m.style("height"))||400)-n.top-n.bottom;v.update=function(){v(e)},v.container=this;if(!c||!c.length){var w=m.selectAll(".nv-noData").data([d]);return w.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),w.attr("x",n.left+g/2).attr("y",n.top+b/2).text(function(e){return e}),v}m.selectAll(".nv-noData").remove();var E=t.y()(c[c.length-1],c.length-1);s=t.xScale(),o=t.yScale();var S=m.selectAll("g.nv-wrap.nv-sparklineplus").data([c]),T=S.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),N=T.append("g"),C=S.select("g");N.append("g").attr("class","nv-sparklineWrap"),N.append("g").attr("class","nv-valueWrap"),N.append("g").attr("class","nv-hoverArea"),S.attr("transform","translate("+n.left+","+n.top+")");var k=C.select(".nv-sparklineWrap");t.width(g).height(b),k.call(t);var L=C.select(".nv-valueWrap"),A=L.selectAll(".nv-currentValue").data([E]);A.enter().append("text").attr("class","nv-currentValue").attr("dx",p?-8:8).attr("dy",".9em").style("text-anchor",p?"end":"start"),A.attr("x",g+(p?n.right:0)).attr("y",h?function(e){return o(e)}:0).style("fill",t.color()(c[c.length-1],c.length-1)).text(l(E)),N.select(".nv-hoverArea").append("rect").on("mousemove",M).on("click",function(){a=!a}).on("mouseout",function(){u=[],O()}),C.select(".nv-hoverArea rect").attr("transform",function(e){return"translate("+ -n.left+","+ -n.top+")"}).attr("width",g+n.left+n.right).attr("height",b+n.top)}),v}var t=e.models.sparkline(),n={top:15,right:100,bottom:10,left:50},r=null,i=null,s,o,u=[],a=!1,f=d3.format(",r"),l=d3.format(",.2f"),c=!0,h=!0,p=!1,d="No Data Available.";return v.sparkline=t,d3.rebind(v,t,"x","y","xScale","yScale","color"),v.options=e.utils.optionsFunc.bind(v),v.margin=function(e){return arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=typeof e.right!="undefined"?e.right:n.right,n.bottom=typeof e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof e.left!="undefined"?e.left:n.left,v):n},v.width=function(e){return arguments.length?(r=e,v):r},v.height=function(e){return arguments.length?(i=e,v):i},v.xTickFormat=function(e){return arguments.length?(f=e,v):f},v.yTickFormat=function(e){return arguments.length?(l=e,v):l},v.showValue=function(e){return arguments.length?(c=e,v):c},v.alignValue=function(e){return arguments.length?(h=e,v):h},v.rightAlignValue=function(e){return arguments.length?(p=e,v):p},v.noData=function(e){return arguments.length?(d=e,v):d},v},e.models.stackedArea=function(){"use strict";function g(e){return e.each(function(e){var a=n-t.left-t.right,b=r-t.top-t.bottom,w=d3.select(this);p=v.xScale(),d=v.yScale();var E=e;e.forEach(function(e,t){e.seriesIndex=t,e.values=e.values.map(function(e,n){return e.index=n,e.seriesIndex=t,e})});var S=e.filter(function(e){return!e.disabled});e=d3.layout.stack().order(l).offset(f).values(function(e){return e.values}).x(o).y(u).out(function(e,t,n){var r=u(e)===0?0:n;e.display={y:r,y0:t}})(S);var T=w.selectAll("g.nv-wrap.nv-stackedarea").data([e]),N=T.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),C=N.append("defs"),k=N.append("g"),L=T.select("g");k.append("g").attr("class","nv-areaWrap"),k.append("g").attr("class","nv-scatterWrap"),T.attr("transform","translate("+t.left+","+t.top+")"),v.width(a).height(b).x(o).y(function(e){return e.display.y+e.display.y0}).forceY([0]).color(e.map(function(e,t){return e.color||i(e,e.seriesIndex)}));var A=L.select(".nv-scatterWrap").datum(e);A.call(v),C.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),T.select("#nv-edge-clip-"+s+" rect").attr("width",a).attr("height",b),L.attr("clip-path",h?"url(#nv-edge-clip-"+s+")":"");var O=d3.svg.area().x(function(e,t){return p(o(e,t))}).y0(function(e){return d(e.display.y0)}).y1(function(e){return d(e.display.y+e.display.y0)}).interpolate(c),M=d3.svg.area().x(function(e,t){return p(o(e,t))}).y0(function(e){return d(e.display.y0)}).y1(function(e){return d(e.display.y0)}),_=L.select(".nv-areaWrap").selectAll("path.nv-area").data(function(e){return e});_.enter().append("path").attr("class",function(e,t){return"nv-area nv-area-"+t}).attr("d",function(e,t){return M(e.values,e.seriesIndex)}).on("mouseover",function(e,t){d3.select(this).classed("hover",!0),m.areaMouseover({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:e.seriesIndex})}).on("mouseout",function(e,t){d3.select(this).classed("hover",!1),m.areaMouseout({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:e.seriesIndex})}).on("click",function(e,t){d3.select(this).classed("hover",!1),m.areaClick({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:e.seriesIndex})}),_.exit().remove(),_.style("fill",function(e,t){return e.color||i(e,e.seriesIndex)}).style("stroke",function(e,t){return e.color||i(e,e.seriesIndex)}),_.transition().attr("d",function(e,t){return O(e.values,t)}),v.dispatch.on("elementMouseover.area",function(e){L.select(".nv-chart-"+s+" .nv-area-"+e.seriesIndex).classed("hover",!0)}),v.dispatch.on("elementMouseout.area",function(e){L.select(".nv-chart-"+s+" .nv-area-"+e.seriesIndex).classed("hover",!1)}),g.d3_stackedOffset_stackPercent=function(e){var t=e.length,n=e[0].length,r=1/t,i,s,o,a=[];for(s=0;s<n;++s){for(i=0,o=0;i<E.length;i++)o+=u(E[i].values[s]);if(o)for(i=0;i<t;i++)e[i][s][1]/=o;else for(i=0;i<t;i++)e[i][s][1]=r}for(s=0;s<n;++s)a[s]=0;return a}}),g}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=function(e){return e.x},u=function(e){return e.y},a="stack",f="zero",l="default",c="linear",h=!1,p,d,v=e.models.scatter(),m=d3.dispatch("tooltipShow","tooltipHide","areaClick","areaMouseover","areaMouseout");return v.size(2.2).sizeDomain([2.2,2.2]),v.dispatch.on("elementClick.area",function(e){m.areaClick(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],m.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){m.tooltipHide(e)}),g.dispatch=m,g.scatter=v,d3.rebind(g,v,"interactive","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","forceX","forceY","forceSize","clipVoronoi","useVoronoi","clipRadius","highlightPoint","clearHighlights"),g.options=e.utils.optionsFunc.bind(g),g.x=function(e){return arguments.length?(o=d3.functor(e),g):o},g.y=function(e){return arguments.length?(u=d3.functor(e),g):u},g.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,g):t},g.width=function(e){return arguments.length?(n=e,g):n},g.height=function(e){return arguments.length?(r=e,g):r},g.clipEdge=function(e){return arguments.length?(h=e,g):h},g.color=function(t){return arguments.length?(i=e.utils.getColor(t),g):i},g.offset=function(e){return arguments.length?(f=e,g):f},g.order=function(e){return arguments.length?(l=e,g):l},g.style=function(e){if(!arguments.length)return a;a=e;switch(a){case"stack":g.offset("zero"),g.order("default");break;case"stream":g.offset("wiggle"),g.order("inside-out");break;case"stream-center":g.offset("silhouette"),g.order("inside-out");break;case"expand":g.offset("expand"),g.order("default");break;case"stack_percent":g.offset(g.d3_stackedOffset_stackPercent),g.order("default")}return g},g.interpolate=function(e){return arguments.length?(c=e,g):c},g},e.models.stackedAreaChart=function(){"use strict";function M(y){return y.each(function(y){var _=d3.select(this),D=this,P=(a||parseInt(_.style("width"))||960)-u.left-u.right,H=(f||parseInt(_.style("height"))||400)-u.top-u.bottom;M.update=function(){_.transition().duration(A).call(M)},M.container=this,S.disabled=y.map(function(e){return!!e.disabled});if(!x){var B;x={};for(B in S)S[B]instanceof Array?x[B]=S[B].slice(0):x[B]=S[B]}if(!y||!y.length||!y.filter(function(e){return e.values.length}).length){var j=_.selectAll(".nv-noData").data([T]);return j.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),j.attr("x",u.left+P/2).attr("y",u.top+H/2).text(function(e){return e}),M}_.selectAll(".nv-noData").remove(),b=t.xScale(),w=t.yScale();var F=_.selectAll("g.nv-wrap.nv-stackedAreaChart").data([y]),I=F.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),q=F.select("g");I.append("rect").style("opacity",0),I.append("g").attr("class","nv-x nv-axis"),I.append("g").attr("class","nv-y nv-axis"),I.append("g").attr("class","nv-stackedWrap"),I.append("g").attr("class","nv-legendWrap"),I.append("g").attr("class","nv-controlsWrap"),I.append("g").attr("class","nv-interactive"),q.select("rect").attr("width",P).attr("height",H);if(h){var R=c?P-C:P;i.width(R),q.select(".nv-legendWrap").datum(y).call(i),u.top!=i.height()&&(u.top=i.height(),H=(f||parseInt(_.style("height"))||400)-u.top-u.bottom),q.select(".nv-legendWrap").attr("transform","translate("+(P-R)+","+ -u.top+")")}if(c){var U=[{key:L.stacked||"Stacked",metaKey:"Stacked",disabled:t.style()!="stack",style:"stack"},{key:L.stream||"Stream",metaKey:"Stream",disabled:t.style()!="stream",style:"stream"},{key:L.expanded||"Expanded",metaKey:"Expanded",disabled:t.style()!="expand",style:"expand"},{key:L.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:t.style()!="stack_percent",style:"stack_percent"}];C=k.length/3*260,U=U.filter(function(e){return k.indexOf(e.metaKey)!==-1}),s.width(C).color(["#444","#444","#444"]),q.select(".nv-controlsWrap").datum(U).call(s),u.top!=Math.max(s.height(),i.height())&&(u.top=Math.max(s.height(),i.height()),H=(f||parseInt(_.style("height"))||400)-u.top-u.bottom),q.select(".nv-controlsWrap").attr("transform","translate(0,"+ -u.top+")")}F.attr("transform","translate("+u.left+","+u.top+")"),v&&q.select(".nv-y.nv-axis").attr("transform","translate("+P+",0)"),m&&(o.width(P).height(H).margin({left:u.left,top:u.top}).svgContainer(_).xScale(b),F.select(".nv-interactive").call(o)),t.width(P).height(H);var z=q.select(".nv-stackedWrap").datum(y);z.transition().call(t),p&&(n.scale(b).ticks(P/100).tickSize(-H,0),q.select(".nv-x.nv-axis").attr("transform","translate(0,"+H+")"),q.select(".nv-x.nv-axis").transition().duration(0).call(n)),d&&(r.scale(w).ticks(t.offset()=="wiggle"?0:H/36).tickSize(-P,0).setTickFormat(t.style()=="expand"||t.style()=="stack_percent"?d3.format("%"):E),q.select(".nv-y.nv-axis").transition().duration(0).call(r)),t.dispatch.on("areaClick.toggle",function(e){y.filter(function(e){return!e.disabled}).length===1?y.forEach(function(e){e.disabled=!1}):y.forEach(function(t,n){t.disabled=n!=e.seriesIndex}),S.disabled=y.map(function(e){return!!e.disabled}),N.stateChange(S),M.update()}),i.dispatch.on("stateChange",function(e){S.disabled=e.disabled,N.stateChange(S),M.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;U=U.map(function(e){return e.disabled=!0,e}),e.disabled=!1,t.style(e.style),S.style=t.style(),N.stateChange(S),M.update()}),o.dispatch.on("elementMousemove",function(i){t.clearHighlights();var s,a,f,c=[];y.filter(function(e,t){return e.seriesIndex=t,!e.disabled}).forEach(function(n,r){a=e.interactiveBisect(n.values,i.pointXValue,M.x()),t.highlightPoint(r,a,!0);var o=n.values[a];if(typeof o=="undefined")return;typeof s=="undefined"&&(s=o),typeof f=="undefined"&&(f=M.xScale()(M.x()(o,a)));var u=t.style()=="expand"?o.display.y:M.y()(o,a);c.push({key:n.key,value:u,color:l(n,n.seriesIndex),stackedValue:o.display})}),c.reverse();if(c.length>2){var h=M.yScale().invert(i.mouseY),p=Infinity,d=null;c.forEach(function(e,t){h=Math.abs(h);var n=Math.abs(e.stackedValue.y0),r=Math.abs(e.stackedValue.y);if(h>=n&&h<=r+n){d=t;return}}),d!=null&&(c[d].highlight=!0)}var v=n.tickFormat()(M.x()(s,a)),m=t.style()=="expand"?function(e,t){return d3.format(".1%")(e)}:function(e,t){return r.tickFormat()(e)};o.tooltip.position({left:f+u.left,top:i.mouseY+u.top}).chartContainer(D.parentNode).enabled(g).valueFormatter(m).data({value:v,series:c})(),o.renderGuideLine(f)}),o.dispatch.on("elementMouseout",function(e){N.tooltipHide(),t.clearHighlights()}),N.on("tooltipShow",function(e){g&&O(e,D.parentNode)}),N.on("changeState",function(e){typeof e.disabled!="undefined"&&y.length===e.disabled.length&&(y.forEach(function(t,n){t.disabled=e.disabled[n]}),S.disabled=e.disabled),typeof e.style!="undefined"&&t.style(e.style),M.update()})}),M}var t=e.models.stackedArea(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.interactiveGuideline(),u={top:30,right:25,bottom:50,left:60},a=null,f=null,l=e.utils.defaultColor(),c=!0,h=!0,p=!0,d=!0,v=!1,m=!1,g=!0,y=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" on "+t+"</p>"},b,w,E=d3.format(",.2f"),S={style:t.style()},x=null,T="No Data Available.",N=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),C=250,k=["Stacked","Stream","Expanded"],L={},A=250;n.orient("bottom").tickPadding(7),r.orient(v?"right":"left"),s.updateState(!1);var O=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=y(i.series.key,a,f,i,M);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return t.dispatch.on("tooltipShow",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],N.tooltipShow(e)}),t.dispatch.on("tooltipHide",function(e){N.tooltipHide(e)}),N.on("tooltipHide",function(){g&&e.tooltip.cleanup()}),M.dispatch=N,M.stacked=t,M.legend=i,M.controls=s,M.xAxis=n,M.yAxis=r,M.interactiveLayer=o,d3.rebind(M,t,"x","y","size","xScale","yScale","xDomain","yDomain","xRange","yRange","sizeDomain","interactive","useVoronoi","offset","order","style","clipEdge","forceX","forceY","forceSize","interpolate"),M.options=e.utils.optionsFunc.bind(M),M.margin=function(e){return arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof e.right!="undefined"?e.right:u.right,u.bottom=typeof e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof e.left!="undefined"?e.left:u.left,M):u},M.width=function(e){return arguments.length?(a=e,M):a},M.height=function(e){return arguments.length?(f=e,M):f},M.color=function(n){return arguments.length?(l=e.utils.getColor(n),i.color(l),t.color(l),M):l},M.showControls=function(e){return arguments.length?(c=e,M):c},M.showLegend=function(e){return arguments.length?(h=e,M):h},M.showXAxis=function(e){return arguments.length?(p=e,M):p},M.showYAxis=function(e){return arguments.length?(d=e,M):d},M.rightAlignYAxis=function(e){return arguments.length?(v=e,r.orient(e?"right":"left"),M):v},M.useInteractiveGuideline=function(e){return arguments.length?(m=e,e===!0&&(M.interactive(!1),M.useVoronoi(!1)),M):m},M.tooltip=function(e){return arguments.length?(y=e,M):y},M.tooltips=function(e){return arguments.length?(g=e,M):g},M.tooltipContent=function(e){return arguments.length?(y=e,M):y},M.state=function(e){return arguments.length?(S=e,M):S},M.defaultState=function(e){return arguments.length?(x=e,M):x},M.noData=function(e){return arguments.length?(T=e,M):T},M.transitionDuration=function(e){return arguments.length?(A=e,M):A},M.controlsData=function(e){return arguments.length?(k=e,M):k},M.controlLabels=function(e){return arguments.length?typeof e!="object"?L:(L=e,M):L},r.setTickFormat=r.tickFormat,r.tickFormat=function(e){return arguments.length?(E=e,r):E},M}})();!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function z(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function T(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(Mt(u[0]),Mt(u[1]),Mt(u[2]))}return(i=Va.get(n))?t(i.r,i.g,i.b):(null!=n&&"#"===n.charAt(0)&&(4===n.length?(o=n.charAt(1),o+=o,a=n.charAt(2),a+=a,c=n.charAt(3),c+=c):7===n.length&&(o=n.substring(1,3),a=n.substring(3,5),c=n.substring(5,7)),o=parseInt(o,16),a=parseInt(a,16),c=parseInt(c,16)),t(o,a,c))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function zt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){if(m&&n%1)return"";var e=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var u=Xo.formatPrefix(n,h);n=u.scale(n),d=u.symbol}else n*=p;n=g(n,h);var c=n.lastIndexOf("."),x=0>c?n:n.substring(0,c),M=0>c?"":t+n.substring(c+1);!s&&f&&(x=i(x));var _=v.length+x.length+M.length+(y?0:e.length),b=l>_?new Array(_=l-_+1).join(r):"";return y&&(x=i(b+x)),e+=v,n=x+M,("<"===o?e+n+b:">"===o?b+e+n:"^"===o?b.substring(0,_>>=1)+e+n+b.substring(_):e+(y?n:b+n))+d}}}function qt(n){return n+""}function Tt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=Tt;var r=new Tt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=Tt;var r=new Tt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==Tt,o=new(i?Tt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=Tt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=Tt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=Math.cos(t),a=Math.sin(t),c=i*a,s=u*o+c*Math.cos(e),l=c*Math.sin(e);hc.add(Math.atan2(l,s)),r=n,u=o,i=a}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=oa(_)>Sa,w=p*x;if(hc.add(Math.atan2(w*Math.sin(_),v*M+w*Math.cos(_))),i+=b?_+(_>=0?ka:-ka):_,b^h>=e^m>=e){var S=fe(se(f),se(n));pe(S);var k=fe(u,S);pe(k);var E=(b^_>=0?-1:1)*X(k[2]);(r>E||r===E&&(S[0]||S[1]))&&(o+=b^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function ze(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Te(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),zc>t&&(zc=t),t>Tc&&(Tc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,z=N-e,q=x*L-y*z;(q*q/M>i||oa((y*L+x*z)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b
},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function zr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];zr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),zr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),zr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function Tr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),Tr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=zu(t,e),i=qu(Tu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function zu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(zu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Tu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function zi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Ti(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():Ti(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=Ti(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Ti(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Ti(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function zo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function To(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]
}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=Ti(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Ti(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.1"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=z(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=z(o);for(;f>r;++r)p[r]=z(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=T.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,za=Math.SQRT2,qa=2,Ta=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(za*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(za*t+v)]}return[r+n*s,u+n*l,i*Math.exp(za*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+Ta*f)/(2*i*qa*h),p=(c*c-i*i-Ta*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/za;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=z.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=z.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=z.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=z.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",z=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=z.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,z,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv(" ","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;Tt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:zt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h
}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,ze,Te,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,zc,qc,Tc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=Tc=-(Lc=zc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,zc],[qc,Tc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=zi,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?zi(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?zi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])
},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(zo(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=To,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),z.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),z=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?z.on("touchmove.brush",v).on("touchend.brush",y):z.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),T=+/^n/.test(k);M=[l[1-q]-L[0],f[1-T]-L[1]],L[0]=l[q],L[1]=f[T]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(+n,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();/*!
* Bootstrap v3.1.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown",h),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=" li:not(.divider):visible a",i=f.find("[role=menu]"+h+", [role=listbox]"+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j<i.length-1&&j++,~j||(j=0),i.eq(j).focus()}}}};var g=a.fn.dropdown;a.fn.dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.dropdown.Constructor=f,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=g,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu], [role=listbox]",f.prototype.keydown)}(jQuery),+function(a){"use strict";var b=function(b,c){this.options=c,this.$element=a(b),this.$backdrop=this.isShown=null,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};b.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},b.prototype.toggle=function(a){return this[this.isShown?"hide":"show"](a)},b.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d),this.isShown||d.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(document.body),c.$element.show().scrollTop(0),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one(a.support.transition.end,function(){c.$element.focus().trigger(e)}).emulateTransitionEnd(300):c.$element.focus().trigger(e)}))},b.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one(a.support.transition.end,a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal())},b.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.focus()},this))},b.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},b.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.removeBackdrop(),a.$element.trigger("hidden.bs.modal")})},b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},b.prototype.backdrop=function(b){var c=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var d=a.support.transition&&c;if(this.$backdrop=a('<div class="modal-backdrop '+c+'" />').appendTo(document.body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),d&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;d?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),"object"==typeof c&&c);f||e.data("bs.modal",f=new b(this,g)),"string"==typeof c?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());c.is("a")&&b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this,d=this.tip();this.setContent(),this.options.animation&&d.addClass("fade");var e="function"==typeof this.options.placement?this.options.placement.call(this,d[0],this.$element[0]):this.options.placement,f=/\s?auto?\s?/i,g=f.test(e);g&&(e=e.replace(f,"")||"top"),d.detach().css({top:0,left:0,display:"block"}).addClass(e),this.options.container?d.appendTo(this.options.container):d.insertAfter(this.$element);var h=this.getPosition(),i=d[0].offsetWidth,j=d[0].offsetHeight;if(g){var k=this.$element.parent(),l=e,m=document.documentElement.scrollTop||document.body.scrollTop,n="body"==this.options.container?window.innerWidth:k.outerWidth(),o="body"==this.options.container?window.innerHeight:k.outerHeight(),p="body"==this.options.container?0:k.offset().left;e="bottom"==e&&h.top+h.height+j-m>o?"top":"top"==e&&h.top-m-j<0?"bottom":"right"==e&&h.right+i>n?"left":"left"==e&&h.left-i<p?"right":e,d.removeClass(l).addClass(e)}var q=this.getCalculatedOffset(e,h,i,j);this.applyPlacement(q,e),this.hoverState=null;var r=function(){c.$element.trigger("shown.bs."+c.type)};a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,r).emulateTransitionEnd(150):r()}},b.prototype.applyPlacement=function(b,c){var d,e=this.tip(),f=e[0].offsetWidth,g=e[0].offsetHeight,h=parseInt(e.css("margin-top"),10),i=parseInt(e.css("margin-left"),10);isNaN(h)&&(h=0),isNaN(i)&&(i=0),b.top=b.top+h,b.left=b.left+i,a.offset.setOffset(e[0],a.extend({using:function(a){e.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),e.addClass("in");var j=e[0].offsetWidth,k=e[0].offsetHeight;if("top"==c&&k!=g&&(d=!0,b.top=b.top+g-k),/bottom|top/.test(c)){var l=0;b.left<0&&(l=-2*b.left,b.left=0,e.offset(b),j=e[0].offsetWidth,k=e[0].offsetHeight),this.replaceArrow(l-f+j,j,"left")}else this.replaceArrow(k-g,k,"top");d&&e.offset(b)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach(),c.$element.trigger("hidden.bs."+c.type)}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,b).emulateTransitionEnd(150):b(),this.hoverState=null,this)},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},"function"==typeof b.getBoundingClientRect?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.tooltip",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this}}(jQuery),+function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");b.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery);/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f
}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},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(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={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:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)
},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.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(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,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",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n});body {
padding-top: 10px;
}
.popover {
max-width: none;
}
.glyphicon {
margin-right:.25em;
}
.table-bordered>thead>tr>td {
border-bottom-width: 1px;
}
.table tbody>tr>td, .table thead>tr>td {
padding-top: 3px;
padding-bottom: 3px;
}
.table-condensed tbody>tr>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: 117px;
}
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;
}
#toplink {
position: fixed;
left: 5px;
bottom: 5px;
outline: 0;
}
svg text {
font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
color: #666;
fill: #666;
}
.scrollbox {
height:245px;
overflow-x:hidden;
overflow-y:scroll;
}
/********************
* HTML CSS
*/
.chartWrap {
margin: 0;
padding: 0;
overflow: hidden;
}
/********************
Box shadow and border radius styling
*/
.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip {
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
/********************
* TOOLTIP CSS
*/
.nvtooltip {
position: absolute;
background-color: rgba(255,255,255,1.0);
padding: 1px;
border: 1px solid rgba(0,0,0,.2);
z-index: 10000;
font-family: Arial;
font-size: 13px;
text-align: left;
pointer-events: none;
white-space: nowrap;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/*Give tooltips that old fade in transition by
putting a "with-transitions" class on the container div.
*/
.nvtooltip.with-transitions, .with-transitions .nvtooltip {
transition: opacity 250ms linear;
-moz-transition: opacity 250ms linear;
-webkit-transition: opacity 250ms linear;
transition-delay: 250ms;
-moz-transition-delay: 250ms;
-webkit-transition-delay: 250ms;
}
.nvtooltip.x-nvtooltip,
.nvtooltip.y-nvtooltip {
padding: 8px;
}
.nvtooltip h3 {
margin: 0;
padding: 4px 14px;
line-height: 18px;
font-weight: normal;
background-color: rgba(247,247,247,0.75);
text-align: center;
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;
}
.nvtooltip p {
margin: 0;
padding: 5px 14px;
text-align: center;
}
.nvtooltip span {
display: inline-block;
margin: 2px 0;
}
.nvtooltip table {
margin: 6px;
border-spacing:0;
}
.nvtooltip table td {
padding: 2px 9px 2px 0;
vertical-align: middle;
}
.nvtooltip table td.key {
font-weight:normal;
}
.nvtooltip table td.value {
text-align: right;
font-weight: bold;
}
.nvtooltip table tr.highlight td {
padding: 1px 9px 1px 0;
border-bottom-style: solid;
border-bottom-width: 1px;
border-top-style: solid;
border-top-width: 1px;
}
.nvtooltip table td.legend-color-guide div {
width: 8px;
height: 8px;
vertical-align: middle;
}
.nvtooltip .footer {
padding: 3px;
text-align: center;
}
.nvtooltip-pending-removal {
position: absolute;
pointer-events: none;
}
/********************
* SVG CSS
*/
svg {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* Trying to get SVG to act like a greedy block in all browsers */
display: block;
width:100%;
height:100%;
}
svg text {
font: normal 12px Arial;
}
svg .title {
font: bold 14px Arial;
}
.nvd3 .nv-background {
fill: white;
fill-opacity: 0;
/*
pointer-events: none;
*/
}
.nvd3.nv-noData {
font-size: 18px;
font-weight: bold;
}
/**********
* Brush
*/
.nv-brush .extent {
fill-opacity: .125;
shape-rendering: crispEdges;
}
/**********
* Legend
*/
.nvd3 .nv-legend .nv-series {
cursor: pointer;
}
.nvd3 .nv-legend .disabled circle {
fill-opacity: 0;
}
/**********
* Axes
*/
.nvd3 .nv-axis {
pointer-events:none;
}
.nvd3 .nv-axis path {
fill: none;
stroke: #000;
stroke-opacity: .75;
shape-rendering: crispEdges;
}
.nvd3 .nv-axis path.domain {
stroke-opacity: .75;
}
.nvd3 .nv-axis.nv-x path.domain {
stroke-opacity: 0;
}
.nvd3 .nv-axis line {
fill: none;
stroke: #e5e5e5;
shape-rendering: crispEdges;
}
.nvd3 .nv-axis .zero line,
/*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {
stroke-opacity: .75;
}
.nvd3 .nv-axis .nv-axisMaxMin text {
font-weight: bold;
}
.nvd3 .x .nv-axis .nv-axisMaxMin text,
.nvd3 .x2 .nv-axis .nv-axisMaxMin text,
.nvd3 .x3 .nv-axis .nv-axisMaxMin text {
text-anchor: middle
}
/**********
* Brush
*/
.nv-brush .resize path {
fill: #eee;
stroke: #666;
}
/**********
* Bars
*/
.nvd3 .nv-bars .negative rect {
zfill: brown;
}
.nvd3 .nv-bars rect {
zfill: steelblue;
fill-opacity: .75;
transition: fill-opacity 250ms linear;
-moz-transition: fill-opacity 250ms linear;
-webkit-transition: fill-opacity 250ms linear;
}
.nvd3 .nv-bars rect.hover {
fill-opacity: 1;
}
.nvd3 .nv-bars .hover rect {
fill: lightblue;
}
.nvd3 .nv-bars text {
fill: rgba(0,0,0,0);
}
.nvd3 .nv-bars .hover text {
fill: rgba(0,0,0,1);
}
/**********
* Bars
*/
.nvd3 .nv-multibar .nv-groups rect,
.nvd3 .nv-multibarHorizontal .nv-groups rect,
.nvd3 .nv-discretebar .nv-groups rect {
stroke-opacity: 0;
transition: fill-opacity 250ms linear;
-moz-transition: fill-opacity 250ms linear;
-webkit-transition: fill-opacity 250ms linear;
}
.nvd3 .nv-multibar .nv-groups rect:hover,
.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,
.nvd3 .nv-discretebar .nv-groups rect:hover {
fill-opacity: 1;
}
.nvd3 .nv-discretebar .nv-groups text,
.nvd3 .nv-multibarHorizontal .nv-groups text {
font-weight: bold;
fill: rgba(0,0,0,1);
stroke: rgba(0,0,0,0);
}
/***********
* Pie Chart
*/
.nvd3.nv-pie path {
stroke-opacity: 0;
transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
-moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
-webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
}
.nvd3.nv-pie .nv-slice text {
stroke: #000;
stroke-width: 0;
}
.nvd3.nv-pie path {
stroke: #fff;
stroke-width: 1px;
stroke-opacity: 1;
}
.nvd3.nv-pie .hover path {
fill-opacity: .7;
}
.nvd3.nv-pie .nv-label {
pointer-events: none;
}
.nvd3.nv-pie .nv-label rect {
fill-opacity: 0;
stroke-opacity: 0;
}
/**********
* Lines
*/
.nvd3 .nv-groups path.nv-line {
fill: none;
stroke-width: 1.5px;
/*
stroke-linecap: round;
shape-rendering: geometricPrecision;
transition: stroke-width 250ms linear;
-moz-transition: stroke-width 250ms linear;
-webkit-transition: stroke-width 250ms linear;
transition-delay: 250ms
-moz-transition-delay: 250ms;
-webkit-transition-delay: 250ms;
*/
}
.nvd3 .nv-groups path.nv-line.nv-thin-line {
stroke-width: 1px;
}
.nvd3 .nv-groups path.nv-area {
stroke: none;
/*
stroke-linecap: round;
shape-rendering: geometricPrecision;
stroke-width: 2.5px;
transition: stroke-width 250ms linear;
-moz-transition: stroke-width 250ms linear;
-webkit-transition: stroke-width 250ms linear;
transition-delay: 250ms
-moz-transition-delay: 250ms;
-webkit-transition-delay: 250ms;
*/
}
.nvd3 .nv-line.hover path {
stroke-width: 6px;
}
/*
.nvd3.scatter .groups .point {
fill-opacity: 0.1;
stroke-opacity: 0.1;
}
*/
.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point {
fill-opacity: 0;
stroke-opacity: 0;
}
.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point {
fill-opacity: .5 !important;
stroke-opacity: .5 !important;
}
.with-transitions .nvd3 .nv-groups .nv-point {
transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
-moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
-webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
}
.nvd3.nv-scatter .nv-groups .nv-point.hover,
.nvd3 .nv-groups .nv-point.hover {
stroke-width: 7px;
fill-opacity: .95 !important;
stroke-opacity: .95 !important;
}
.nvd3 .nv-point-paths path {
stroke: #aaa;
stroke-opacity: 0;
fill: #eee;
fill-opacity: 0;
}
.nvd3 .nv-indexLine {
cursor: ew-resize;
}
/**********
* Distribution
*/
.nvd3 .nv-distribution {
pointer-events: none;
}
/**********
* Scatter
*/
/* **Attempting to remove this for useVoronoi(false), need to see if it's required anywhere
.nvd3 .nv-groups .nv-point {
pointer-events: none;
}
*/
.nvd3 .nv-groups .nv-point.hover {
stroke-width: 20px;
stroke-opacity: .5;
}
.nvd3 .nv-scatter .nv-point.hover {
fill-opacity: 1;
}
/*
.nv-group.hover .nv-point {
fill-opacity: 1;
}
*/
/**********
* Stacked Area
*/
.nvd3.nv-stackedarea path.nv-area {
fill-opacity: .7;
/*
stroke-opacity: .65;
fill-opacity: 1;
*/
stroke-opacity: 0;
transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
-moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
-webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
/*
transition-delay: 500ms;
-moz-transition-delay: 500ms;
-webkit-transition-delay: 500ms;
*/
}
.nvd3.nv-stackedarea path.nv-area.hover {
fill-opacity: .9;
/*
stroke-opacity: .85;
*/
}
/*
.d3stackedarea .groups path {
stroke-opacity: 0;
}
*/
.nvd3.nv-stackedarea .nv-groups .nv-point {
stroke-opacity: 0;
fill-opacity: 0;
}
/*
.nvd3.nv-stackedarea .nv-groups .nv-point.hover {
stroke-width: 20px;
stroke-opacity: .75;
fill-opacity: 1;
}*/
/**********
* Line Plus Bar
*/
.nvd3.nv-linePlusBar .nv-bar rect {
fill-opacity: .75;
}
.nvd3.nv-linePlusBar .nv-bar rect:hover {
fill-opacity: 1;
}
/**********
* Bullet
*/
.nvd3.nv-bullet { font: 10px sans-serif; }
.nvd3.nv-bullet .nv-measure { fill-opacity: .8; }
.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; }
.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; }
.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; }
.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; }
.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; }
.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; }
.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; }
.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; }
.nvd3.nv-bullet .nv-subtitle { fill: #999; }
.nvd3.nv-bullet .nv-range {
fill: #bababa;
fill-opacity: .4;
}
.nvd3.nv-bullet .nv-range:hover {
fill-opacity: .7;
}
/**********
* Sparkline
*/
.nvd3.nv-sparkline path {
fill: none;
}
.nvd3.nv-sparklineplus g.nv-hoverValue {
pointer-events: none;
}
.nvd3.nv-sparklineplus .nv-hoverValue line {
stroke: #333;
stroke-width: 1.5px;
}
.nvd3.nv-sparklineplus,
.nvd3.nv-sparklineplus g {
pointer-events: all;
}
.nvd3 .nv-hoverArea {
fill-opacity: 0;
stroke-opacity: 0;
}
.nvd3.nv-sparklineplus .nv-xValue,
.nvd3.nv-sparklineplus .nv-yValue {
/*
stroke: #666;
*/
stroke-width: 0;
font-size: .9em;
font-weight: normal;
}
.nvd3.nv-sparklineplus .nv-yValue {
stroke: #f66;
}
.nvd3.nv-sparklineplus .nv-maxValue {
stroke: #2ca02c;
fill: #2ca02c;
}
.nvd3.nv-sparklineplus .nv-minValue {
stroke: #d62728;
fill: #d62728;
}
.nvd3.nv-sparklineplus .nv-currentValue {
/*
stroke: #444;
fill: #000;
*/
font-weight: bold;
font-size: 1.1em;
}
/**********
* historical stock
*/
.nvd3.nv-ohlcBar .nv-ticks .nv-tick {
stroke-width: 2px;
}
.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover {
stroke-width: 4px;
}
.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive {
stroke: #2ca02c;
}
.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative {
stroke: #d62728;
}
.nvd3.nv-historicalStockChart .nv-axis .nv-axislabel {
font-weight: bold;
}
.nvd3.nv-historicalStockChart .nv-dragTarget {
fill-opacity: 0;
stroke: none;
cursor: move;
}
.nvd3 .nv-brush .extent {
/*
cursor: ew-resize !important;
*/
fill-opacity: 0 !important;
}
.nvd3 .nv-brushBackground rect {
stroke: #000;
stroke-width: .4;
fill: #fff;
fill-opacity: .7;
}
/**********
* Indented Tree
*/
/**
* TODO: the following 3 selectors are based on classes used in the example. I should either make them standard and leave them here, or move to a CSS file not included in the library
*/
.nvd3.nv-indentedtree .name {
margin-left: 5px;
}
.nvd3.nv-indentedtree .clickable {
color: #08C;
cursor: pointer;
}
.nvd3.nv-indentedtree span.clickable:hover {
color: #005580;
text-decoration: underline;
}
.nvd3.nv-indentedtree .nv-childrenCount {
display: inline-block;
margin-left: 5px;
}
.nvd3.nv-indentedtree .nv-treeicon {
cursor: pointer;
/*
cursor: n-resize;
*/
}
.nvd3.nv-indentedtree .nv-treeicon.nv-folded {
cursor: pointer;
/*
cursor: s-resize;
*/
}
/**********
* Parallel Coordinates
*/
.nvd3 .background path {
fill: none;
stroke: #ccc;
stroke-opacity: .4;
shape-rendering: crispEdges;
}
.nvd3 .foreground path {
fill: none;
stroke: steelblue;
stroke-opacity: .7;
}
.nvd3 .brush .extent {
fill-opacity: .3;
stroke: #fff;
shape-rendering: crispEdges;
}
.nvd3 .axis line, .axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.nvd3 .axis text {
text-shadow: 0 1px 0 #fff;
}
/****
Interactive Layer
*/
.nvd3 .nv-interactiveGuideLine {
pointer-events:none;
}
.nvd3 line.nv-guideline {
stroke: #ccc;
}/*!
* Bootstrap v3.1.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none!important;color:#000!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) ")"}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}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.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>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.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 col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:400;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.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;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.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>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;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{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;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-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;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{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{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:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}@media print{.hidden-print{display:none!important}} <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="UTF-8">
<title>Code Coverage for {{full_path}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
<link href="{{path_to_root}}css/style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="{{path_to_root}}js/html5shiv.js"></script>
<script src="{{path_to_root}}js/respond.min.js"></script>
<![endif]-->
</head>
<body>
<header>
<div class="container">
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
{{breadcrumbs}}
</ol>
</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 id="code" class="table table-borderless table-condensed">
<tbody>
{{lines}}
</tbody>
</table>
<footer>
<hr/>
<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="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
</p>
<a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
</footer>
</div>
<script src="{{path_to_root}}js/jquery.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/holder.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var $window = $(window)
, $top_link = $('#toplink')
, $body = $('body, html')
, offset = $('#code').offset().top;
$top_link.hide().click(function(event) {
event.preventDefault();
$body.animate({scrollTop:0}, 800);
});
$window.scroll(function() {
if($window.scrollTop() > offset) {
$top_link.fadeIn();
} else {
$top_link.fadeOut();
}
}).scroll();
$('.popin').popover({trigger: 'hover'});
});
</script>
</body>
</html>
<div class="progress">
<div class="progress-bar progress-bar-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
<span class="sr-only">{{percent}}% covered ({{level}})</span>
</div>
</div>
<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>
FFTMjU<6A><55>GDEF8 OS/2g<32>K<A7>X`cmapJ<70> <09><01>rcvt (<03>,fpgmS<6D>/<2F>4egasp<06>glyf3!<06><00><headbX<62><00><>6hhea
2<00>$hmtx<74><78><11><00><<02>loca4<61>VN<00>0<01>maxp<01><00><> nameԯ<65><D4AF><00>|post<73>F<B9>i<00><><08>prep<65><70>+<00>.webfX<66>R<AF><00>8<00>=<3D><><00> <16><00> .<00><04><01> <02>Z <02><01>2<02>UKWN@ <0A><03><>| lPP@ +<00>
/ _ <20>"%<25>&' '<0F><03> <09><19>)<29>9<E0>I<E0>Y<E0>`<60>i<E0>y<E0><79><E0><89><E0> <09><19>)<29>9<E1>F<E1>I<E1>Y<E1>i<E1>y<E1><79><E1><89><E1><95><E1><00><> *<00> / _ <20>"%<25>&' '<0F><01><05><10> <20>0<E0>@<40>P<E0>`<60>b<E0>p<E0><70><E0><80><E0><01><10> <20>0<E1>@<40>H<E1>P<E1>`<60>p<E1><70><E1><80><E1><90><E1><00><><01><><FF><F5><FF><E3><FF>f<FF><07><>ߴ<E3>h<DF><03><1A><16><0F>
    <1F><1F><1F><1F><1F><1F>xrlf`_YSMGA@<1E><00>(<02><>,<2C>K<>LPX<50>JvY<76>#?<18>+X=YK<59>LPX}Y ԰.-<2D>, ڰ +-<2D>,KRXE#Y!-<2D>,i <20>@PX!<21>@Y-<2D>,<2C>+X!#!zX<7A><1B>YKRXX<58><1B>Y#!<21>+X<>FvYX<59><1B>YYY-<2D>, \Z-<2D>,<2C>"<01>PX<50> <20>\\<1B>Y-<2D>,<2C>$<01>PX<50>@<40>\\<1B>Y-<2D>, 9/-<2D> , }<7D>+X<><1B>Y <20>%I# <20>&J<>PX<50>e<8A>a <20>PX8!!Y<1B><>a <20>RX8!!YY-<2D>
,<2C>+X!!Y-<2D> , Ұ +-<2D> , /<2F>+\X G#Faj X db8!!Y!Y-<2D> , 9/ <20> G<>Fa#<23> <20>#J<>PX#<23>RX<52>@8!Y#<23>PX<50>@e8!YY-<2D>,<2C>+X=<3D>!! ֊KRX <20>#I <20>UX8!!Y!!YY-<2D>,# <20> /<2F>+\X# XKS!<21>YX<59><58>&I#<23># <20>I<8A>#a8!!!!Y!!!!!Y-<2D>, ڰ+-<2D>, Ұ+-<2D>, /<2F>+\X G#Faj<61> G#F#aj` X db8!!Y!!Y-<2D>, <20> <20><> <20>%Jd#<23><07> PX<<1B>Y-<2D>,<2C>@@BBK<>cK<>c <20> <20>UX <20> <20>RX#b <20>#Bb <20>#BY <20>@RX<52> CcB<63> CcB<63> c<>e!Y!!Y-<2D>,<2C>Cc#<23>Cc#-<01><>(h .<2E>/<<3C><02>2<ED><05><<3C><02>2<00>/<<3C><02>2<ED><03><<3C><02>23!%3#(@<40><><FE><E8> <20><>(<02>ddLL$<00>/<2F> 3<>Ͱ 2<01>/<2F>ְ2<>Ͱ2<>+015!'737!!'#'7d<03><><B7>ȷ<B7><C8B7><03><><FE><FD><B7>ȷ<B7><C8B7><01>ȷ<F4><C8B7><03><><FE><FD><B7>ȷ<B7><C8B7><8D><B7><03><><B7>LL J<00>
+<2B>/<2F>3<>Ͱ2<>
+<2B>@ +<01> /<2F>
ְ2<> Ͱ2<>
+<2B>@  +<2B>
+<2B>@
+<2B> +01!!!!!<01>,<01><>p<FE><70><01>,<01><>p<FE><70><FE>p<01>d<04><04>7v<00>2/<2F>(Ͳ(2
+<2B>@(. +<2B>/<2F>!3<>Ͱ2<>/<2F>3<>Ͱ2<>/<2F> Ͳ
+<2B>@ +<01>8/<2F>2<>22<32>"<10>-+<2B>2<>2<>9+<2B>"7<12>9<>-<11> 2999017347#7367632#4.#"!!!!32>53#"'.'ddq<05>d<DA>%Ku<4B><75>p<<06>3LJ9D?{d<><64><01>d<96><64> 09C3JL3<4C>ak<61><6B>w$B <01>d/5d<35>Z<A7><5A>gj7X0,Z>d.6dJtB+0W5<57>ju<6A>.<2E>x<00><01>L<02><00>/<2F><03><01>/<2F>+01!!<21><03><>|<01>,1<01><>,<04>A<00>/<2F>Ͱ <09><01>/<2F>+<00> <12> 99013!264&#".#"qO<02>x<EE><78>x.,,<2C>n<B5><6E>BU<01>Pr<50><72><AD>awי kd<04>L
57% <01><><90><01><>P,<2C><>XX<><58>,d<01><><90><C8>p<FE>X<><58><01><><F4>[<5B> ,<2C><><03><><FF><F3><04><04>%'7'7764/&" M<>Z<DF>f<>V<D6>c <0A>$ p<>Q<DF>f<>V<D6>\ '<0E> <04><04> 3<00>+<2B>Ͱ2<01>
/<2F>ְͲ
+<2B>@ +<2B>
+<2B>@ +<2B> +01!!!5!<04><> ,<2C><>,<04><><B0><FD><DA>dd&L<04> &7>5%&7>54&&$<24>OAXX@JOW<12>OFS
<FD>
@JO<4A>n)`*^<5E><><9B>r67)Q7q
<03>
<FD>O<17><><04><04>Y<00>+<2B>/<2F>Ͱ/<2F><03><01>/<2F>ְͰ<10>+<2B>ͱ+<2B><12>$9<><11>9<00><12> 9<><11>9<><12>$901 "'#" 6& <01>N,m<08><>w<D4>ȃ<8E><12><><C1><C1><01><01><1C><>Ȏw<C88E><77>m,Nl<><6C><FE><F0><12>dX<04>D<01>/<2F>ְͰͱ+014>>.d8Zwwy,0{xuX6Cy<43><79>>><3E><>yC@vS-IDEH-Sv@9y<39><80>UU<55><B2>y<02><>G<04><04>
!3! 7Hߒ<02><01><><D8><FE><82><91><FE><80><FE><82> <01><>p<FE><70><FE>?<13><><01><>?<03><>G<04><04>
<00> /<2F>3<>Ͱ2<01>/<2F>+01!3! 77'7#'Hߒ<02><01><><D8><FE><82><91><FE><80><FE><82>C<>I<C4><49>J<C3><4A>MN <01><>p<FE><70><FE>?<13><><01><>?t<><8E><E28C8D><E5><8C><04><04>155"&=462#<01>%?<3F><><B0>?%<01><>d<>3<95>|<7C><>|<7C>3<C8>d<95><64><FE> <04>L #'+/3<00><00>+<2B>ͱ 22<32>/<2F>"3<>Ͱ$2<> /<2F>&3<> Ͱ(2<>/<2F>*3<>Ͱ,2<>/<2F>.3<B0>Ͱ02<30>/<2F>233<33><01><01>4/<2F>ְͳ $2<><10>+<2B> $2<>Ͱ2<><10>+<2B>2<> ͳ$(,0$2<> <10>!+<2B>%)-1$2<>ͱ5+<00> <12>99<39><11>99011!%35#535#535#535#535#!!5!!35#535#535#535#535#<04><><B0>dddddddddd<64>X<><58>X<><58><02>ddddddddddL<><4C>dddddddddd<64>|<01>d<01><>|dddddddddLL/?B<00> +<2B>,3<>Ͱ$2<>/<2F><3<>Ͱ42<01>@/<2F>ְ2<> Ͱ2<> <10> +<2B>02<30>)Ͱ82<38>A+015463!2#!"&463!2#!"&463!2#!"&463!2#!"&<01><15>p<01><15>pX<01><15>p<01><15>p2<01><15>pm<01><15>p<1D><><01><15>pm<01><15>p LL/?O_o<00>v<00> +<2B><l33<33>ͱ4d22<32>/<2F>L|33<33>ͱDt22<32>-/<2F>\<5C>33<33>$ͱT<CDB1>22<01><>/<2F>ֱ 22<32> ͱ(22<32> <10>0+<2B>@P22<32>9ͱHX22<32>9<10>`+<2B>p<B1>22<32>iͱx<CDB1>22<32><32>+01=46;2+"&546;2+"&546;2+"&546;2+"&546;2+"&546;2+"&546;2+"&546;2+"&546;2+"&<15><15><15><15><15><15><01><15><15><15><15><15><15><01><15><15><15><15><15><15>2<><15><01><><15><01><><15><1D><><FC><15><01><><15><01><><15><1D><><FC><15><01><><15><01><><15><04>L/?O_V<00> +<2B><3<>Ͱ42<34>/<2F>L3<4C>ͰD2<44>-/<2F>\3<>$ͰT2<01>`/<2F>ֱ 22<32> ͱ(22<32> <10>0+<2B>@P22<32>9ͱHX22<32>a+01=46;2+"&;26=4&+"=46;2+"&5463!2#!"&5463!2#!"&5463!2#!"&<15><15><15><15><15><15><01><02><15>D<02><15>D<02><15>D2<><15><01><15><15><><15><1D><><FC><15><01><><15><01><><15>"<04>* ''<01>2<><32><D4><FD><01><>\4<><34><D4><FD>jjFF  7   j<1A><><FE><1A><><D4><1A><><D4><FE><E6>><1A><><D4><1A><><D4><FE><E6><FE><1A><><17><><04><04>'<00><00>+<2B>/<2F>Ͱ/<2F>#3<>Ͱ!2<>
+<2B>@& +<2B>
+<2B>@ +<2B>/<2F><03><01>(/<2F>ְͰ<10>&+<2B>2<>%Ͱ 2<>%&
+<2B>@%# +<2B>&%
+<2B>@& +<2B>%<10>+<2B>ͱ)+<2B>&<12>999<39>%<11>9<><12>$9<><11>9<00><12>9<><12>$9<><11>99901 "'#" 6& 53533##5<01>N,m<08><>w<D4>ȃ<8E><12><><C1><C1>Fd<46>dd<64><01><01><1C><>Ȏw<C88E><77>m,Nl<><6C><FE><F0><12><>Y<FE>dd<64>dd<17><><04><04>]<00>+<2B>/<2F>Ͱ/<2F><03><01> /<2F>ְͰ<10>+<2B>ͱ!+<2B><12>$9<><11>9<00><12> 9<><11>9<><12>$901 "'#" 6& !5!<01>N,m<08><>w<D4>ȃ<8E><12><><C1><C1>F<01><>p<01><01><1C><>ȍy<C88D><79>m,Nl<><6C><FE><F0><10><>Y<FE><04><04>+E<00>/<2F>
<CD><01>,/<2F>ְͲ
+<2B>@ +<2B><10> +<2B>Ͳ 
+<2B>@  +<2B>-+<2B> <12>#$90147 654&'5".;2654&+"ҧg|<7C>b<>|g<><67>[<5B><><9B>՛[<01>ddX<>(><3E>7<A6>x<C8><78><B1><FA>x<B1>7<C8>><3E>طv՛[[<5B><> <01>d<04><04> 0<00>+<2B> 33<01>/<2F>ְͰ<10>+<2B> Ͱ <10> +<2B>ͱ+0173#33333d<><64>,<2C>d<C8>d<C8>,<2C><><01><>  <20><><04><>P<04><04>GQb<00>/<2F>PͰK/<2F>6<B0><01>R/<2F>ְHͰH<10>M+<2B>$ͱS+<2B>H<12> =99<39>M<11>39$9<>$<12>/99<00>P<12>99<39>K<11>!'E$9<>6<12>+A9901732?6?67'76?654/&/7&''&/&#"'462"&<06>P-<<3C>-1&("/&./<05>80P<01><05>P,<<3C>-0&("/&2,<05>;.P <02>g~<7E>~~<7E>~Y!)&1,<05>;.Q <02><05> Q,=<3D>,1&("-&3*<05>:/Q<01><05>Q/:<3A>/.&0X~~XY~~d<><64><04>#'+/37<00><00>!+<2B>$Ͳ(04222<32>'/<2F>*26333<33>Ͱ/<2F>ͱ,22<32>//<2F> <09><01>8/<2F>ְ$Ͱ$<10>%+<2B>2<>(Ͱ,2<>%(
+<2B>@% +<2B>(<10>)+<2B>0Ͱ0<10>1+<2B>-2<>4Ͱ 2<>41
+<2B>@4 +<2B>4<10>5+<2B>ͱ9+015463!5463!2!2#!"&!#!"&73#3#!5!3#3#d
;),);
 <0B><> d<03>;)<29>D);ddd<64>dd,<2C><><FE>dd<64>dd2
d);;)d
2 <0E>n <20><>)<<)<02><>D<02>,d<><64><02><>D<02><04>
,<00> +<2B>3<01> /<2F> ְͰ<10>+<2B>ͱ +<2B><12>901 #!!!<02><02><><84><C8><FE><D4><FE><D4>Y<02><>|<7C><><01><>pXd<03><04>"<00> +<01>/<2F>ְͲ
+<2B>@ +<2B>+017463!!#!"&d <01><01> <0B><> X,~ <0E> <0C>] ,<2C><><04><04> <00><00>
/<2F>Ͱ/<2F>Ͳ
+<2B>@ +<2B>/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>Ͳ
+<2B>@ +<2B><10>+<2B>ͱ+<2B> <12>
$9<><12> $9<00><12> $9<><12> $901$  $ 6& 33<04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>Gd<47><01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56><F3><01><><90>d<02><><04> .<00>+<2B>3<>
/<2F> Ͱ/<2F>Ͳ
+<2B>@ +<2B>2<01>/<2F>+01#333!#3#d<01><><15><14><01><><AF>)<29>(1<><1B><04><><B0>,<2C>P<01><>p<01>,L<04> J<00> +<2B> Ͱ/<2F> Ͱ2<01>/<2F>ְͲ
+<2B>@ +<2B><10> +<2B>
ͱ+<2B><12> 99<39> <11> 99011!3!3!%35#<01><><EA><FE>,<2C><><C8><01><><01>,<01><> <0C><><FE>p<FE>d<04><04>c<00> +<2B>Ͱ/<2F><05><01>/<2F>ְͰ<10>+<2B>Ͱ<10>+<2B> ͱ +<2B><12> $9<><11>9<><12> $9<00><12> $9014>2". 6& 333_<><5F><A0>ޠ__<5F><5F><A0>ޠ\<5C>T<><54><F2><F2>P<AC>Ȗ<96><01><>ޠ__<5F><5F><A0>ޠ__<5F><02><><FE><AC>T<><54>d,<2C><><FE><D4><04><04> a<00>
/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>Ͱ<10>+<2B>ͱ+<2B> <12>
$9<><11>9<><12> $9<00><12>$901$  $ 6& ##<04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>O<AA><4F><FA><FA><01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56>b,<2C><><FE><D4>,<04><04> )<00> +<2B> Ͱ2<>/<2F><02><01>/<2F>+<00> <12>999015!#!"&3!73!<21> <20> <0B><> <0E><>2,2<>a<C8><61><01><02><>D<FD>% <01><><E6><01><04><04> F<00>
/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>ͱ+<2B> <12>
$9<00><12>$901$  $ 654& <04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3><FE>:)<01>D<12><><A0><A0><FE><EE><FE><01><><B4><AC><F2><F2><AC><AB><F3><F3><01><><04><04>S<00>/<2F> Ͱ/<2F><19><01>/<2F>ְͰ<10>
+<2B> ͱ+<2B>
<12>$9<> <11>99<00> <12> $9<><11>9012>5# &632!&#"[<5B><><9B>՛[<5B><><96><FA><FE><9E><FA><FA>n<88><01><><90><91><02><>՛[[<5B><>v<D5><76><B1>b<>Q<FA><01><>z[<5B><04><04>!z<00>+<2B>/<2F>Ͳ
+<2B>@ +<2B> /<2F>Ͳ 
+<2B>@ +<01>"/<2F>ְͰ<10>+<2B>ͱ#+<2B><12>99<39><11>
!$9<><12> 99<00><12>!9<> <11> 99<39><12>9014>327!7&#"!32653#"'[<5B><><76><C69D>p<FE>p<93><70><87>I<01><>p<93><70><87><B1>[<5B><>Xv՛[z<><7A>p<FE>P<93><50><FA><B1><01><>P<93><50>v՛[z
d<04><04> #'P<00>/<2F>3<> Ͱ2<> /<2F>3<> Ͱ2<>/<2F> 3<>Ͱ!2<>/<2F>$3<>Ͱ%2<01>(/<2F>ֲ 222<32> Ͳ222<32>)+013!!!%53'53'53'53!5!=!%5!%5!dL<><4C>d<03><><84>dddddddd<01><> <01><> <01><> <01><04><><B0><03><>|ddd<64>dd<64>dd<64>dd<64><64>dddd<64>dd<64>ddL<04>#J<00>+<2B> /<2F> <09><01>$/<2F>ְͲ
+<2B>@ +<2B><10>+<2B>Ͳ
+<2B>@ +<2B>%+<00> <12>$901546;5463!232#!"&!54&+";)dvR,Rvd);;)<29>|);<01>,<15>dX);<3B>RvvR<76>;)<29><>);;<02><>dLL<00>+<01>/<2F>ְͱ+0133>>7.ddd<<3C>x|rjd)({<7B><><84>tZL<><4C><01><0 !OQ<01>QE
((
EQ<04><04>!1Ag<00>/+<2B>>3<>&Ͱ62<36> /<2F><1D><01>B/<2F>ְͰ<10>"+<2B>+Ͱ+<10>2+<2B>;Ͱ;<10>+<2B>ͱC+<2B>2+<12> $9<00>&/<12>$9<> <11>9901;2654> ;2654."46;2+"&%46;2+"& 2 <0E><><06><> 2 c<><63><A3>ޣc<DEA3> <08> <08> X <08> <08>   ,<>rr<72><D1><7F>  ,tޣcc<63><63>t<DE><74><01> <08>4 <01> <08>4 <00>X<03>!!7'77',,<2C><><FE><D4><02><><B0>G<8D><47>G<8D><47>G<8D><47><01><> <20><><C8><FE><AB>G<8D><47>G<8D><47>G<8D><47><00>p<03><01>/<2F>ְ ͱ+01!!%7'654,,<2C><><FE><D4><02>EojCV<01><> <20>95<39><35><87><AF>6n<36><6E><00>b<03><<00>/<2F><01><01>/<2F>ְ Ͱ <10>+<2B>ͱ+<2B> <12>$9<00><12> $901!%%7'65477654/,,<2C><><01>EojCV^{wQ<06><><01><01><><90><C8><FC><01>5<C9><35><87><AF>7n<37><6E><8A><08><><97><C1>B<08><><B2><E3> <04><04>!/3?CGKO<00>+<2B>0D33<33>Ͳ)1E222<32>/<2F>'+L333<33>Ͳ%-M222<32>"/<2F>33<33>2<>/<2F>H33<33>!ͱ4I22<01>P/<2F>ֱ22<32>ͱ22<32><10>0+<2B> ,22<32>3Ͱ52<35>3<10>. +<2B>*2<>%Ͱ@2<>.%
+<2B>@." +<2B> 222<32>%<10>7+<2B>DH22<32>;ͱ&J22<32>;<10>L+<2B>B2<42>OͲ9=F222<32>Q+<2B>0<12>4?$9<>7%<12>()8999<00>"<12>89$9<>#<11>:;999<39>@ 67<=@C$9011!#5##535!535#!!!5335#5!3##5#5355333!5#53!!5!5353<01><>d<C8>d<01>dd<64> d,<2C><>,<2C>dddd,,<2C>d<C8>dddddd<64>,<2C><><C8><C8><FD>,<2C>,<2C><>ddd<01>dddddd,<2C><>,<2C><><02>,<2C><><FE><D4>dd<02>d<BC> d<><64>dddd<64><64> dd<03><><E8><FE><D4><FE>d<01><>p,<2C><><FE><D4>dd<03>dd<64>Ddd <04><04> #p<00> +<2B>333<33> ͱ22<32> +<2B><05><01>$/<2F>ְ Ͱ <10>+<2B> 2<>ͰͰ<10> +<2B>Ͱ<10> +<2B>Ͱ<10> +<2B>#ͱ%+<2B> <12>99<39><12>990153#5!'353'3535353'3ddd,<2C>d<C8>dd<64>dd<64>d<C8><64><03><>Pdd<64><03><><18>[[<5B><03><><18>[[<5B><03><><18>[[<5B><03><><04><04>)<00>+<2B>/<2F><04><01>/<2F>ְ ͱ+<00><12> 99901463! 2764'&"
<01><02><> <0C><>SS<02><01>
<0F>D<FD> <03>TT<05><04>1<00>+<2B>3<>/<2F>Ͱ2<01>/<2F>ְ ͱ+<00><12> $901463! 2764'&"%3 ' <01><02><> <0C><>TT d<02><> 2<01><02><01> <0E>D<FD> <03>TT<1E><>D<FD> 2<01>d<04><04>
?<00>+<2B>/<2F><02><01> /<2F>ְ
Ͱ
<10>+<2B>ͱ +<2B>
<12>999<00><12>9990137!!!d<><03>d<9D>d<02><01><>d<03>d<E8><00>L<04>
3 4&#!"<15><01><01><15><><01><>E~<04><04> 'Y<00>%+<2B>Ͱ
/<2F>Ͳ

+<2B>@
+<2B>2<>
+<2B>@ +<2B>2<01>(/<2F>ְ Ͱ2<> <10>+<2B>2<>ͱ)+<2B> <12> '"$90153!73#5!!7.#!"7>3!2#!"&<26>dXd<58><64><C8><C8>5(P>^
<FE>>
B&
<01>
&
<FD><A8>
d<02><><BC><C8>D<FD><44><02>||Z  <0B><><FB>

<98>
d<04>L%-1o<00>/<2F>%Ͱ)/<2F>-Ͱ!/<2F><13><01>2/<2F>ְͲ
+<2B>@/ +<2B><10>'+<2B>+ͱ3+<2B><12>9<>+'<12>!$% $9<00>-)<12>"#$9<>!<11>.199<B0><12> /0$90153!2654&+.+"#"462"264&"%53;)<03>);;)<29>37S*<2A>)R:. <0C>);d<>Ȑ<90><C890>>X>>XXd<58>);;)X);E5+);;;)<29><70>Ȑ X>>X>^dd5<04><04>"<00>+<2B> 3<>Ͳ 222<01>#/<2F>$+013!5".?!#!5&'./#5m)>$\<01>R+5<01>"(<06>]<5D>q *k<>.tB6,<2C><>-WBB*. <03><>0 <01>Ɍ<><C98C>d<03><04> )1e<00> +<2B>+<2B>Ͱ)/<2F>*Ͱ1/<2F> Ͱ <10> <0B><01>2/<2F>ְ!Ͱ*2<>!<10>.+<2B>Ͱ% <20><11>ͱ3+<2B>%.<12>9<00>)!<12>9<>*<11>9<>1<12>90135>54.'52#'32654&+532654&#d); $<01>x<D7>!" E4+v<>OȡY<C8A1>}^<5E><>Ll<4C><6C>Y3(; G<01><>7]7( 3AvFT<46>M<91>aTZ<54>d{MRa<00>o<04> <00>+<2B>Ͱ2<> /<2F>3<> <0C><01>/<2F>+0135>76&'.'5!<15>Ms<08>
(G <01>!:"<05>
0G9C/Q8$99#'% <0C><>4<9<02><><04> %~<00>+<2B>/<2F>333<33> Ͳ
+<2B>@ +<2B>
2<01>&/<2F>ְͰ<10>
+<2B>%Ͱ%<10>+<2B>Ͳ
+<2B>@ +<2B>
+<2B>@ +<2B><10>+<2B>ͱ'+<2B>
<12>99<00><12> 9<> <11>901'3#7#33!3#4.+!57#"KKK}}KK}<7D><><02><>2.!"<22>d<C8>pd<70>"!/<11> <20><><A7><A7><FC>c,<2C><>' <02><>2dd2R '!<21><><04><04> %<00><00>+<2B>Ͱ/<2F>3<> Ͳ
+<2B>@
+<2B>2<01>&/<2F>
ְ%Ͱ%<10>+<2B>Ͳ
+<2B>@ +<2B>
+<2B>@ +<2B><10>+<2B>ͱ'+<2B>%<12> $9<><12>$9<00><12>99<39><11>99901?!55!3!3#4.+!57#"!<21> <20><><A7><A7>d<E0><02><>2/!"<22>d<C8>pd<70>"!.3}KK}}KK<03>,<2C><>' <02>v2dd2<02> '<04>L/?53!26=4&#!"53!26=4&#!"53!26=4&#!"53!26=4&#!"L<15><> <15><><03><15>X<15><>2d<15>d<15>d<15>d<04>L/?53!26=4&#!"3!26=4&#!"3!26=4&#!"3!26=4&#!"L<15><>L<15><><1D><02><15>D<02><15>D2d<01>d<15>pd<01>d<04>L/?&<00> +<2B>Ͱ-/<2F>/<2F>Ͱ=/<2F>4<B0><01>@/<2F>A+01=463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&L<15><>d<03><15><1D> <15><><1D>X<15><>2ddldd<1E><>ddldd<04>L/?&<00> +<2B>Ͱ/<2F>Ͱ-/<2F>$Ͱ=/<2F>4<B0><01>@/<2F>A+01=463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&L<15><>L<15><>L<15><>L<15><>2dd@dd@dd@dd<04>L/?O_oR<00> +<2B>L3<4C>ͰD2<44>/<2F>\3<>ͰT2<54>-/<2F>l3<6C>$Ͱd2<64>=/<2F>|3<>4Ͱt2<01><>/<2F>ֲ 0222<32> Ͳ(8222<32><32>+01=46;2+"&546;2+"&546;2+"&546;2+"&5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&dddddddd, <15><> <15><> <15><> <15><>2dd@dd@dd@dd<1E><>dd@dd@dd@dd<06><><04>L
*:J <00>/<2F>&3<>Ͱ.2<01>K/<2F>L+<00><12>90153553#3!26=4&#!"53!26=4&#!"53!26=4&#!"5;26=4&+"<65><C9A6>dd<64>X<14><>,<14><><01><14> dd<01>dK}}K<> L<><4C>d<15>d<15>d<15>dL/?CJ<00>@+<01>K/<2F>@ְCͱL+0173!26=4&#!"53!26=4&#!"53!26=4&#!"5;26=4&+"3535#5X<14><>,<14><><01><14> dd d!<21><><A7>2d<15>d<15>d<15>d<15><>L<><4C>&}KdK<00><04><03>-<00> /<2F>Ͱ<04><01>/<2F>ְ ͱ+<2B> <12>9<00> <12>9901463!2#!"& ,<02>,,<1F>,<03>,<02>,,<1F>v,,d,<2C><><04>LY<00> +<2B>/<2F>Ͱ/<2F><04><01> /<2F>ְͰ<10>+<2B>Ͱ<10>+<2B> ͱ!+<2B><12>9<><11>99<00> <12>999<39><11>9015463!2#!"&?'!462"X<13><>d<>*J%<25><>lNpNNp,<03><12> <1A><><ED><B6>><3E><><01><><F4>pNNpN<00><><94><04>=<00> +<2B>/<2F><04><01>/<2F>ְͰ<10>+<2B>ͱ +<2B><12> 99<00> <12>999014>32.'&73264&"<06>y<94>z{<7B>yII<49>99
"c]s+?—jk<6A><6B>֖<02>|ׁ~<7E><><D5>r<95>BB "ko<6B>K<A0><4B>k<96><6B>֖<97><04><04>I<00> +<2B>Ͱ/<2F><05><01>/<2F>ְͰ<10>+<2B> ͱ+<2B><12> 99<39> <11> 99<00><12> $9014>2".3"_<><5F><A0>ޠ__<5F><5F><A0>ޠM<DEA0><4D><FB><01><>ޠ__<5F><5F><A0>ޠ__<5F> <09><><FE>Vu<03>%4>7.77.'&6?uDmssIOWM?%N~<7E>OrÀ~[[.
 \7<01>^<5E><><B8><A1>`G<>vwsu<73>EY<45>d;^<5E>~RlbJ(I<>43n<33><04>h!&W<00>+<2B>Ͱ/<2F><04><01>'/<2F>ְ Ͱ <10>+<2B>ͱ(+<2B> <12> $9<><11>"99<00><12>!$9<><11> "#%$901463!"3!26=7#!"&%7' 7/<01><>n<1F><><BA>);;)<01>);<3B><><C8><EB>ԥ<FE><01><><01>r<9C>k<01>qq\<01>,<2C><><08>;)<29> );;)}<7D><><C8><E1><A5>j2<01>q<9C>k<01>qqU<04>L.H<00>+<2B>Ͱ"/<2F>'Ͱ /<2F>Ͱ<10><06><01>//<2F>ְ ͱ0+<00>"<12>$999<39> <12>%9<><12>&901463!#"3!2657#!"&> "<05><><02>U<85>);;)<01>);<3B><><C8><EB>ԥ<FE><01>gg_h<><68>HCVC9<01>,<2C><>P X;)<29> );;)<29>5<99><35><A5>!&4 <01>D><3E>3Cm<04>L#R<00>+<2B>Ͱ /<2F><04><01>$/<2F>ְ Ͱ <10>+<2B>ͱ%+<2B> <12>"$9<><11>!9<00> <12>"#$9<><11> !9901463!2!"3!26=7#!"& ''<27><>,=B<><42><B2>);;)<01>);<3B><><C8><EB>ԥ<FE>V7<><37>R<FE><01>,<2C><><17>;)<29> );;)Eȩ<45><C8A9><A5><01><><8D>7<><37>Q<FE><04><04>E<00>+<2B>/<2F>3<>Ͱ 2<01>/<2F>ְ2<>Ͱ2<>+<2B><12>99<00><12> 99<39><11> 990135# #35 5#3 35#,<2C><>,'<27><>,<2C><><FE><D4><C8><C3><FE><D9><FE><D4>[(<28><>,<2C><><FE><D4><C8><C6><FE><D8><FE><D4><C6><C8>,<2C><><00><03>L<00>+<2B> 3<01>/<2F>ְ Ͱ2<>+01746;2+"&<26>d<01><> d2<03><15>K<01><><E7><01><>J<04>L<00>+<2B> 33<01>/<2F>ְͰ2<>+01546;2+"&d<01><01><> <0C> d2<03><15>K<01><><01><><E7><01><><01><>J<00><04>L<00>+<2B>3<01>/<2F>+01<11>4<01><> &&<26><01><><E7><01><><00>LL3 <01><03><>|&&<00>d<03><03>7;2654&+";2654&+"<15><15><15><01><15><15><1D> <15><> <00>dL<03>73!2654&#!"<15> <15><><1D> (L<00>+<2B>3<01>/<2F>+011 <01>4<><34>L<><01><><E7><FD><DA><01><04>L<00>+<2B>33<01>/<2F>ְ2<> ͱ+01146;2+"&5<01><01>dd<1D> L<><01><><01><15><01><><01>,<03>L<00>+<2B>3<01>/<2F>ְ2<> ͱ+01!46;2+"&5,<01>ddL<><01><15><01>d<00><04>(<00> /<2F><04><01>/<2F>+0175463!2#!"&!d<03><15>L<><4C><FD>dd4<00><03><04>7 '<27>P<><50><F0>a<>W<><57><FD>aa<><10><>Rt% 7a<><61><FE><<01><><FD>aa<><61><F0><01><><04><04> B<00>
/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>ͱ+<2B> <12>
$9<00><12>$901$  $33535#5##<03>D<13><><A0><A0><FE><ED><FE><BC><FE><ED><89><C8><C8><C8><C8><01>D<13><><A0><A0><FE><ED><FE><BC><FE><ED>Q<><51><C8><C8><C8><04><04> I<00>
/<2F> Ͱ/<2F><04><01>/<2F>ְ Ͱ <10> +<2B>ͱ+<2B> <12>
$9<00>
<12>99<39><12>9901$  $!5!<03>D<13><><A0><A0><FE><ED><FE><BC><FE>X<><58><01>D<13><><A0><A0><FE><ED><FE><BC><FE><ED>Q<><04><04> 2<00>
/<2F>Ͱ<04><01>/<2F>ְͰͱ+<2B><12> 99<00>
<12> 9901$  $77'7''<03>D<13><><A0><A0><FE><ED><FE><BC>SՍ<53>Վ<8D>Ս<8E>ԍ<01>D<13><><A0><A0><FE><ED><FE><BC><FE><ED><>Ս<8E>ԍ<8D>Ս<04><04> 2<00>
/<2F>Ͱ<04><01>/<2F>ְͰͱ+<2B><12> 99<00>
<12> 9901$  $ ''<03>D<13><><A0><A0><FE><ED><FE><BC>k<01><><9B>f<01>D<13><><A0><A0><FE><ED><FE><BC><FE><ED><01><><84><01><><9B>f<04><04> 8<l<00>
/<2F>9Ͱ</<2F>'Ͱ!/<2F>Ͱ4/<2F><04><01>=/<2F>ְͰ<10>.+<2B>ͱ>+<2B><12>!499<39>.<11> (:;$9<00>'<<12>99<39>!<11>*9<><12> .999<B0>4<11>9901$  $32264>:323>54.#"35#<03>D<13><><A0><A0><FE><ED><FE><BC>ɏ '<01>-"#1D12QE&<26><><88><01>D<13><><A0><A0><FE><ED><FE><BC><FE><ED>
 =&
)2X23L(5`<60>.d<04><04> ;<00>
/<2F> Ͱ/<2F>3<>Ͱ/<2F>Ͱ/<2F><04><01>/<2F>+<00><12>99<39><12>9901$  $7!5#!3#35#<03>D<13><><A0><A0><FE><ED><FE><BC><FE><01>d<90><64>ddd<64><64><01>D<13><><A0><A0><FE><ED><FE><BC><FE><ED><A0>d,d<><01>d<04><04>/i<00>+<2B>/<2F>Ͱ2<>/<2F>!333<33>Ͳ #-222<01>0/<2F>ֲ)222<32>Ͳ'222<32>1+<2B><12>"#./$9<00><12>9<><12>9<><11>()9990153>7533##5.'35367#53.'#53<15><1F><><87>6vk<12><><19><59>`oKȕ4<C895><34>eJ<65>Kn<18><01><>}<7D><1A><>P<>E<83>f<C8>!<21><><1B>}Im<18><>0<CE><30>Jj<18><>lH<6C><04><04> F<00>
/<2F>Ͱ/<2F><04><01> /<2F>ְ Ͱ <10>+<2B>ͱ!+<2B> <12>
$9<00><12>$901$  $ 6& 7'77'<04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>I<AA><49>m<87><6D>m<87><6D>m<87><6D><01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56>ۇ<FD>m<87><6D>m<87><6D>m<87><6D><04><04> F<00>
/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>ͱ+<2B> <12>
$9<00><12>$901$  $ 6& 77<04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>k<AA><57><CC8E><01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56>#<23><57><CD8E><04><04> F<00>
/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>ͱ+<2B> <12>
$9<00><12>$901$  $&#"32654'<04>D<12><><A0><A0><FE><EE><FE><BC>>8dt<64><74><AB>ap<61><70>;<01>D<12><><A0><A0><FE><EE><FE><01>sd7><3E><><F3>;<3B><>pac<04><03><00>/<2F><02><01>/<2F>+<00><12>901!!XX<><58>#<01><><C5><FE><D4><FE><D4>c<04><03><00>/<2F><01><01>/<2F>+<00><12>901! XX<><58><01>,,<2C>;<3B>@-<00>J<04><00>+<01>/<2F>ְͱ+<2B><12>901 !!<11><01><01><><BC><FE><D6>XX<><58><FD><A8>Xh<03><04><00>+<01>/<2F>ְͱ+<2B><12>901!!!h(,*<2A>?XX<><58><FD><A8><00><04>L 5>7 F<><46><89>X<><58>_<A8><5F><B0>Ȅխg<0F>;<3B>@-$Du<04><04> <00>+<01>/<2F>+011!<17>&<26><>ځ<FE><DA81>&<26><>p<FE><01><>&<26><>ځ <09>&<26><01><>"#<04><04> 7'!' "'<27><01><><90><81><01><>'<27><>ف<FE>'<27><>p<FE><70><82>5<01><>'<27><>ق<04><04>#O<00> /<2F> Ͱ#/<2F>Ͱ/<2F><05><01>$/<2F>ְͰ<10>+<2B> ͱ%+<2B><12> !#$9<00>#<12> 99<39><11>99014>2".;2676&+"35#[<5B><><9B>՛[[<5B><><9B>՛V:#6#:<14>0<><30><01><>՛[[<5B><><9B>՛[[<5B>F<><46>.<1D><>d<04><04>&*04;4<00>'+<2B>13<31>*Ͱ22<01></<2F>2<>2<>=+<2B>41<12> 5:$9013!3!535#64&/.#"&/&#"#!!"6?!7#d<01><><01>do" =' <1D><15>!'=
#od<01><>pd"<12><><01><><90><FE>  <20>,<2C><><FE>d <08>'0<11>  <0C>.&<26>
<01>|<01><01>`0/<2F><>|<01><>p<03><> )W9<00><><04><04>2<00>+<01>3/<2F>ͱ4+0157.>7>7.#676%>7>'&"<07> 8./ie<69><65><9A>h,Jhq<68>x{\Sc'C78Fak[)!#<23>==<3D><>Y<16><>5<<3C>b<80>;<U3-9<1E><><BD>ЛU3 7 SB<53>&?_<>T2 3s <20><>o D<04>H#<01>I/<2F>ְEͰE<10><+<2B>J+<2B><E<12>:69901>7>'>7>76''&'.7.7o FFB:8( OV
$9DkC@&<26><>'GOS3 *gJ.  &:4?<01>B8-
%>=B<>'P<>d!I,  =CnC<6E>Sm,U<>!<21>ٕfm<66>S ;4(
.MV .n<03><>}<04>3!?GC<00>/<2F>)Ͱ:/<2F> <09><01>H/<2F><ְ7ͱI+<2B>7<@
)(5>@C$9<00> :<12>$.5>BG$9017>2".'72>7.'"&5477./=FOsv<73><76><93>vsOFFOsv<73><76><93>vsOF<06>C-[Tz<54>wRY,H 7:91<><31><B0>.f<>1ii%LX(
(WT`G//G`TW(
((
(WT`G//G`TW(
(
`=^8+(3\;hI%E:JY|<7C><>|UIWs|Ci`$$<04><><04><04> )A<00><00>+<2B>3<01>B/<2F>C+<2B>6<1A>=<3D><><EF>+
<B0>.<0E> <0C><05><01><0E> <0A><><10>  +<2B> +<2B> +<2B> +<2B>$ +<2B>% +<2B> <20> <20>#9<>9<>9<>$9<>%9<> 9<00> $%........@
$%..........<2E>@017>3273#7.'77.547?./7>7&'7=FOsv<73>H=<%<25><>Ɣ%R<>ri'
<9B>ҷ%k<>.f<>1i/:(&-/"0/a+'C<>. %Ze<5A>X(
(WT`G/<11><>P<FB>egy8(<28><>6<E6><12>nUIWs|C/WR<1A><><FD>&2&?@0<7F>6<92>@(( 4kbf<03><><04> &3!26'.7 !5#5#o%%<15>~8<14>~<7E><01><01><><BD><FE>dd<64>DDG  " <20><>d<02><>-dd<01><><90>,dd<04><04>)H<00>/<2F> <09><01>*/<2F>2<>Ͱ 2<>%
+<2B>@ +<2B>%
+<2B>@%# +<2B>++<2B>%<12>99<00> <12>%99015467462'%/#&=47&dkX|Xk<11><>d^<5E>^d<><64>)1ES>XX><3E><><FE><AD>1) <0C><><F9>[@ NN @[<07> L<04> #'+/37;?CGKOSW53!265!5!54&+5#!5##"53'53'5353'53'5353'53'5353'53'5353'53'53<03><1D><>L<15>d<96> d<>dddddddddddddddddddddddddddddd2<02>d<EE>dddd<15>Jdd<64>dd<64>dd<64>pdd<64>dd<64>dd<64>pdd<64>dd<64>dd<64>pdd<64>dd<64>dd<64>pdd<64>dd<64>ddx<04>
A<00>/<2F>3<>Ͱ2<> /<2F>3<>Ͱ2<01>/<2F>+<00><12>99<39> <11> $9<><12>9901=!35 5# !7'!735 5#X<>,<2C>ԟ<FE><D49F><FD><A8>z<><7A><8D><B5><02><>z<8D>,<2C><><FE><D4><F1>X<><58><C6><FE><D9><FE><D4><C5>Xz<58><7A><8E><B4><FD>{<7B><><C6><FE><D9><FE><04>L<00>+<2B>/<2F> 3<><04><01>/<2F>+01463!2#!#"&;)<03>);;)<29><><FD><AC>d);<01>X);;)<29><>);<3B><>,;dL<04>%)-`<00>+<2B> Ͳ 
+<2B>@  +<2B>2<>&/<2F>*3<>'Ͱ+2<01>./<2F>ְ&2<>Ͱ(2<><10>+<2B>*2<>Ͱ,2<>/+<2B><12>$9<><11>99<39><12>9015!32>'4=!".!!!d,U'5%;) ,'Me<4D><65><9D>eM',<01>,X<><58>q \ #(,.<08><>*R~jqP33Pqj~RV,<2C><>,<2C><><01><><00>h<03> 7<1E>`a<><61><E2><01><>a<><61><FE>CF<00><04> ' FDB<><42><E2><FE><9F><1D><>C<><43><E3>a<02>:dv<03>(<00>/<2F><04><01>/<2F>ְͱ+<2B><12>9<00><12>901 #!!!# #<11>+,<2C><01><><81><D7><01><>}<7D>++<2B><02><1B><><FE>p<FE>X,<2C><>p<FE><70>X<04><04>2F<00>"+<2B>3<>,Ͱ,<10>22<32>//<2F>Ͱ/<2F> <09><01>3/<2F>Ͱ<10>+<2B>ͱ4+<2B><12>-901&763!7>;2++"&=!"&=#"&5463!7!"&'<03>&^6<>*<1D><>*20<><30> -<03><13>*<1D>? 2222<1D>*<04>L <00>+<2B>Ͱ/<2F>Ͱ 2<> <09><01>/<2F>+011!53463!2!<04><>P<FB>;),);<01> <20><><03>d);;)d<05>L(<00>+<2B>Ͱ/<2F> Ͱ2<> <09><01>/<2F>+<00><12>9013! 3463!2!!,<04><><B0><FE>P<FB>;),);<01><><02><>D<01>X);;)<29>.<03><04> !<00> +<01>
/<2F>ְͱ +<2B><12> 99013# #3.<2E><>**<2A><><C6><C6>,X,<2C><><FE><D4><FD><A8>/<04><03> <00>/<2F><02><01>
/<2F> +<00><12>9901!5 5!,X,<2C><><FE><D4>X*<2A><><C6><C6><FE><D6><FE><D7><04><04>!I<00> +<2B>Ͱ2<>/<2F> 3<>Ͱ/<2F><14><01>"/<2F>ְͰ<10>+<2B> Ͳ
+<2B>@ +<2B>#+<2B> <12>901=463!2#!"&>3!235#35#;)<03>);;)<29>);<1F>$<02>%<05><><AC>dd<64>dddd);;)d);;U<02>'-<17>$<24><>ddd<03><>d<04>L )7&<01>8/<2F>ְͰ<10>*+<2B>2ͱ9+<2B>*<12> 9901546?.5<>;%%##"+"&'4632#"&e2"<16><04><02><>]&/
S7<03>X22 <0A>!U<> 
<01><><FA><FC><AE><C8> Q<><51>R<15><>Jf<04>+35<00>/+<2B>3Ͱ)/<2F>3<>Ͱ2<>)
+<2B>@)% +<01>4/<2F>5+<00>)3<12>,1990146;7>7'&6;232#"&/.267"Ju?zS^Sz?vdj<64>O}<7D>::<01> 8F8 0l^<1D>GM~ $M<7F><4D><FE>( ))<29>1==1<04><04>777'7'7'7'''<15>N<E9>-<2D><>-<2D>N괴<4E>N<EA>-<2D><>-<2D>N<E0><4E><01>-<2D>N鳳<4E>N<E9>-<2D><>,<2C>N鴴<4E>N<E9>,<2C>d<04><04>".<01>//<2F>ͱ0+<2B>(<12>90153#;;276=4&#!6=4&+"?3!#'<27><>,d=|<0F>.%<25>='<27><>='20`<60>d<>d22<01><>ֈ<FA>X<><58>Kd9X+d,Qv<07>,Q(<1C><>%<25><>w<>ԯ<D5>}<7D><>d<04>L".p<00>+<2B>/<2F>3<>(Ͱ./<2F>Ͱ2<>,/<2F>
<CD><01>//<2F>ְͰ<10>+<2B>#Ͱ#<10>&+<2B>Ͱ<10>)+<2B>ͱ0+<2B>&#<12>(,999<39><11>9<>)<12>+9<00>.<12>*901374;6;2#!+"&/&735'!5##<23>dd=|<0F>.%<25>='<27><>='20`<60>d<>d22<01><>ֈd<01>X<><58>}<01>Kd9<64><39>+d,Qv<07>,Q(<1C><>%<25>կ<D4>}wddU"Ay<00> /<2F>/<2F>)Ͱ1/<2F>Ͱ2<>1
+<2B>@1 +<01>B/<2F>ְͰ<10>+<2B>#Ͱ#<10>-+<2B>Ͳ-
+<2B>@-< +<2B>C+<2B>-#<12> ?$9<00>$<12>#9<>)<11>9<>1<12><A9990173746?%632!2+#!"&7!>;2654&#!*.'&54?'<08>dj  m U.UkmTk<54><0F><><07>dd%<25><0F><10>7  
<93>V<FE><AD><C8>X<><58>K %
<09> pyL<79>N<90><4E>'<27>YS(  <0A>S<B7><03><>e<04>V8<y<00>/<2F>/<2F>Ͱ8/<2F>Ͱ:2<>8
+<2B>@89 +<01>=/<2F>ְͲ
+<2B>@, +<2B><10>&+<2B>Ͱ<10>9+<2B><ͱ>+<2B>&<12> )$9<00>$<12>&9<><11>9<>8<12>',99901463'&54?632#!"&'#"'32!7%*#!3elU.U m  m!<21><08><><06>kT
<DE><06>%k<><6B>W<A9>
  <01>$<03><>C<>Ly q <06> '<11><> <0A>(Sd)<14><>Y<01><>S<ED>  <01> X<><58>aL6:G<00>7+<2B>8<B0><01>;/<2F>ְ72<37>)Ͳ)
+<2B>@): +<2B>32<33>)<10>/+<2B>ͱ<+<2B>)<12>699<39>/<12>9013!2654&'%54&"'&77><546!5!a<> ' <0A>(<15><>N<AD>Ly%p[S<>22(SY<53> X<02><><CF><1F>V<06>jTnkU<6B><55>T  n V<>   <01><15><06><><82>d<DA>p<FE><70>
<03>48E<00>5/<2F>6<B0><01>9/<2F>
ְ52<B0>+Ͳ+
+<2B>@+8 +<2B>!2<>+<10>'+<2B>ͱ:+<2B>+
<12> 99<39>'<12> 901?26=%>54&#!"!&5<.'&5!p &yM<>NS)<29> <0A><>%
<9A><EC><01>Y<F7><59>(22<16><>XIn  U3<55>.TlnTj<54>V<07><0F><>Sd<53>ڂ<0F><01>  <12>q<><71><04><04>:<00> +<2B>Ͱ/<2F><05><01>/<2F>ְͱ+<00> <12> 99<39><11>99<39><12>99014>32 $! _<><5F>z<DD><13><><A0><A0><FE><ED><FE><BC><FE>%,<01><>nUzݠ_<DDA0><5F><A0><FE><EC><FE><BC><FE><ED>
<C9><C2>&*<2A><04><04>8<00>+<2B>Ͱ/<2F><05><01>/<2F>ְ
ͱ+<00><12>9<><11>
999<39><12>9014>32 $7'!7!5_<35><5F>yzݠ_<DDA0><5F><A0><FE><EC><FE><BC><FE><ED><01>,<02><>Uzݠ__<5F><5F>z<DD><7A><A2><FE><ED><13><><A5><FE><DA><C2><04><04>><00> +<2B><11><01>/<2F>ְͰ<10>+<2B> ͱ+<2B><12> 99<39><11>99<39> <12> 99014>32 $%333_<><5F>z<DD><13><><A0><A0><FE><ED><FE><BC><FE>'<27><><C8><C8><C8>Uzݠ_<DDA0><5F><A0><FE><EC><FE><BC><FE><ED><13><><A5>,<01><04><04>M<00> +<2B>/<2F><05><01>/<2F>ְͰ<10>+<2B> ͱ+<2B><12> 99<39><11>99<39> <12> 99<00> <12>999014>32 $% ##_<><5F>z<DD><13><><A0><A0><FE><ED><FE><BC><FE>',,<2C><>Uzݠ_<DDA0><5F><A0><FE><EC><FE><BC><FE><ED><13><>p<01>,<2C><><04><04><00><00><00>|<00>+<2B>*ͰO/<2F><>/<01><>/<2F>ְͰ<10>X+<2B>
ͱ<9C>+<2B><12>9<>X@!#$<JUx<55><78><84><85>$9<>
@
"&0;Zgv<67><76>$9<00>O*<12>06<FHUW$9<><39>@
Xl<58><6C><85><8D>$9014>32 $277>7.'.'"'&65.'6.'&76746'&67>7&72267.'6'?6.''&%>72>7.73_<><5F>zyݠ_<DDA0><5F><A0><FE><ED><FE><BC><FE><EC>" T>9.*-hu"#. F = .2) ( (%

)#? 6 /R+>=>1
 " ,$<24>Uzݠ__<5F><5F>z<DD><7A><A2><FE><ED>Y!w F  /JG 
s$>   #/ &
% I+
*  ' ' $#  
' "qq $
U _<04><04><7&6767'"/X!N`<60><><A4><8E><FE><FD> <0A>{<7B><><82>+o<>+We<57>6\e<><65>~<7E>\F/<2F><>n`<04><04>/37;P<00> /<2F>4Ͱ7/<2F>Ͱ/<2F>0Ͱ3/<2F>Ͱ,/<2F>8Ͱ;/<2F>%<25><01></<2F>5ֱ1922<32> ͱ(22<32>5
+<2B>@5 +<2B> 22<32>=+01=463!2#!"&5463!2#!"&5463!2#!"&!5!!5!35#;)<03>);;)<29>);;)<03>);;)<29>);;)<03>);;)<29>);X<01><> <0C>,<2C><>d<D4><64><C8>d);;)d);;<01>d);;)d);;<01>d);;)d);;<3B><>d<99> d<02>ddL<04> %<00>+<2B>/<2F><01><01>
/<2F>ְͱ +<00><12>9015!!d<03><>J<03><><84><FE>Lddd<64> <0C><><FE><01>d<04><04> !%`<00>/<2F>Ͱ
/<2F>3<>ͱ"22<32>%/<2F><13><01>&/<2F>ְ"Ͱ 2<>"
+<2B>@ +<2B>2<>"<10>#+<2B>2<>Ͳ#
+<2B>@ +<2B>2<>'+<00>
<12>901=!#!"&463!546;2!2!5#35#<04>;)<29>);;),;)<29>);,);<3B> <0C><><C8><C8><C8><C8>);;U<01>);d);;)d;)<29>pdd<01>d<04><04> <00>+<2B>3<01>/<2F>+011777'7!77!77'!'<07>Ȏȁ<C88E>p<FE>Ȏȁ<C88E>pَȁ<D98E>p<FE><70>ȁ<01><><90><01><>Ȏȁ <20>Ȏȁ<C88E><C881><FC>ȁ<8E>p<FE><02>ȁ<E6>p<FE><70><04><04> )BL<00><00>
+<2B>Ͱ/<2F>J3<4A>ͰE2<45>(/<2F>93<39>#Ͱ42<34>(#
+<2B>@(A +<2B>/<2F><04><01>M/<2F>ְ Ͱ <10>+<2B>Ͱ<10>! +<2B>&Ͱ&<10>*+<2B>>Ͱ><10>C+<2B>Hͳ7HC+<2B>1Ͱ1/<2F>7ͰH<10>+<2B>ͱN+<2B>&<12>
$9<>>*<12>-<99<39>71<12> /;$9<00><12> $9<><11>*-<>$9<>(<12>99<39>#<11>/;9901$  $ 654& 462#"64632#"46?&54632#"'"&%462#"&<26>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3><FE>m. M  R)z  73H3 .  <01>D<12><><A0><A0><FE><EE><FE><01><><B4><AC><F2><F2><AC><AB><F3>.  <20>,! . <20> 1~! .
<91>$33R . <01><>;<04><04>O:<00>/<2F>'Ͱ /<2F>Ͱ6/<2F>J<B0><01>P/<2F>Q+<00>'<12>?9<> <11> 1$9<><12>239901327>767>'&'&#"67632#"&'&>767>32>'.'&#"0#vF?8!@)'(<01>#Z .A#<23>{Ey&$<24><>4I7Z 0$&\4=k6_v[<5B><>EC8fOESkZ(G<>־N9@1*+,<01>#b/W!#<23>tCu$'$<24><>4B?#>@$$\475<11>be[<5B><><<01>C<FF>]W<>$!7G<>P6<04>X5=<00>3/<2F>-3<>Ͱ2<01>6/<2F>ְͰ<10>*+<2B>
ͱ7+<2B>*<12>$9<00>3<12>9014632632'.'.76?>54&#"'&#"<50>bg<62><67><8F>#WCG<43>`+rFBGCW#<23>=>@]aRq @C>`9J:vr3H<c<10>Ł<83>Ń.ZlGF<47><46>:<3A>FAFGlZ.VA>Zo\o >FXGaS<61><53>Pc9<><39>w<04>332764/&''7'&'7'7>54/&#"9B<39>D[]BBB<42> i<><69>{<7B>_.7B<37>B<D4> i<><01><>_/#7B<37>B]_@<40><>Ba_@<40>BBB<>B<BA> i<><69>{<7B>_-87B]B<>
i<D4><01><>`13#j+]B<>BB<42><42>@<00><03><04>E<00>+<2B>Ͱ/<2F>Ͱ/<2F><06><01>/<2F>ְͰ<10>+<2B> Ͱ <10>Ͱ/<2F>+<2B><12>9990174>2#!"&7!!264&"<22><f<><66><9C>d:;)<29><>);dX<><58><FD>=V==Vd<03>2..2<15>G);;<3B><02><><BC>V==V=<04><04><00>+<01>/<2F>+0117'!'&4762"/'/<2F><>, #**$<24><><FE><E9>|<7C><>$*<0F><>*#<23><><FE><F5><FE><D4>' <04>1=C<00><00>-/<2F>*3<>Ͱ>2<>-
+<2B>@-, +<2B>;/<2F>3<>Ͳ;
+<2B>@ +<01>D/<2F>ְ2<>Ͱ2<10>,+<2B>:222<32>>222<32>+<10>@+<2B> <20><11>ͱE+<2B>2<12>9<>,<11> 9<00>-<12>)9<>;<11>':@C$9<><12>9013.#.54>753#.'#5&'.654&''<27>WJ.BN/!X<>Od&ER<+<03>6J@"<P7(<28><>d<9B>U(<19>*=I<><49>XR<01>McO/9X7\<5C>CNO,?iBHK <0A><>,<e><3E><> MNW(k,;<3B>+<12>@Gdf<03><04>C<00><00>1/<2F>/<2F>3<>Ͱ2<>/<2F> Ͳ
+<2B>@ +<01>D/<2F>ְ92<39>Ͱ$2<>
+<2B>@ +<2B>
+<2B>@ +<2B><10>+<2B>ͱE+<2B><12>8BC$9<><11>  *13$9<><12>,9<00>*1<12>-999<39><11>,<990153&'.>7632#4.#"3#>36327#"&'>7>'d<>
/-a<><61>ʙDP$%T)!<1E><>):#b!<21>!L<2)O'*<17>2'V7
  0 $Xd17;V^(X<>w4K,9S*3d2<64>;6 "<1E>B <0B> 
7<8F>G<04><04> <00> +<01>/<2F> ְ ͱ+<2B> <12>901 ## ##**<2A><><01>**<2A><>,<2C><>,<03><>|X,<2C><><FE>|<03><03><04> "<00><00>+<2B>3<>
Ͳ+<2B>Ͱ/<2F>ͱ22<32> /<2F>Ͱ/<2F>Ͳ
+<2B>@ +<2B>2<>"/<2F>Ͱ2<01>#/<2F>ְͰ<10>+<2B> 22<32>
ͱ22<32>
<10>+<2B> 22<32>ͱ 22<32>+<2B>Ͱ/<2F>ͱ$+<2B><12>9<><11>9<00><12>9<> <11>901333!5335!##535!#5#735#<02><><C6><C8><C6><01>d<90><64><C8>,cdc<64>,dddd,<03><>|<7C><><FE>dd<01>d<90>ddd,<01><> dd<64><64><03><04>"<00><00>+<2B>
33<B0> /<2F>Ͱ"/<2F>Ͱ/<2F>ͰͰ/<2F>Ͱ/<2F>Ͱ2<01>#/<2F>ְͰ<10>+<2B>22<32>ͱ22<32><10> +<2B> 22<32>
ͱ22<32>
+<2B>Ͱ/<2F>ͱ$+<2B><12>9<><11>9<00>"<12>$9<><12>9<><11>901333!!#5#5335!##53535#<02><><C6><C8><C6><01>,dddd<64><64><C8>,cdccdd,<03><>|<7C><><01><> dd<02><>dd<01>d<90>ddd<64>|<7C>L<04> k<00> +<2B> /<2F>Ͱ/<2F>Ͱ /<2F>Ͳ 
+<2B>@  +<01>/<2F>ְͳ+<2B>Ͱ/<2F> 3<>Ͱ<10> +<2B> 2<>
ͱ+<00> <12>$9<> <12>9901 ##!#553#35#**<2A><>X,d<><64>ddd,<2C><>,<03><>|<7C><01><> d<03>d<E8> <01><>|<7C>L<04> k<00> +<2B>/<2F>Ͱ/<2F>Ͳ
+<2B>@ +<2B>/<2F><0E><01>/<2F> ְ
ͳ
+<2B> Ͱ /<2F>3<>Ͱ
<10> +<2B>2<>ͱ+<00> <12>$9<><12>9901 ##%53#!#5'35#**<2A><>X<>dd,dcdd,<2C><>,<03><>|dd<64> <01><01><01><> dd<64><04><04>
R<00>/<2F>Ͱ /<2F> Ͱ/<2F>Ͱ/<2F><14><01>/<2F>ֲ 222<32>ͰͲ
+<2B>@
+<2B>@ +<2B>+<00> <12>$901 ##5!5!5!53**<2A><><01><01><> <01><>p,<2C><><FE>,<2C><>,<03><>|<7C><><C8>,<2C><>,<2C><>,<2C><><04><04>
R<00>/<2F>Ͱ /<2F> Ͱ/<2F>Ͱ/<2F><14><01>/<2F> ֲ222<32>Ͱ
Ͳ
+<2B>@
 +<2B>@
 +<2B>+<00> <12>$901 ##535!5!5!**<2A><><01><><F4>,<2C><><01><>p<01>,<2C><>,<03><>|<7C><><C8>,<2C><>,<2C><>,<2C><>LL*<00> +<2B>Ͱ/<2F><04><01> /<2F>ְͰ<10>+<2B> ͱ!+01463!2#!"&73!2654&#!"<15><>,<2C><><A2><EE><ED>ԥ<FE><D4A5>;)<01>);;)<29> );<01>,<2C><><A5><EB><ED>ԥ<FE><D4A5>A);;)<01>);;)LL"><00> +<2B>Ͱ/<2F><04><01>#/<2F>ְͰ<10>+<2B> ͱ$+<2B><12> !99<00><12> "9901463!2#!"&73!2654&#!"-<01><>,<2C><><A5><EB><EB>ԣ<FE><D4A3>;)<01>);;)<29> );<3B>M<><4D><01>,<2C><><A3><ED><EB>ԥ<FE><D4A5>A);;)<01>);;)<29> <0C><>LL"><00> +<2B>Ͱ/<2F><04><01>#/<2F>ְͰ<10>+<2B> ͱ$+<2B><12> "99<00><12> !9901463!2#!"&73!2654&#!"<01><>,<2C><><A3><ED><EB>ԥ<FE><D4A5>;)<01>);;)<29> );d<><64><01>,<2C><><A3><ED><EE>ԥ<FE><D4A5>A);;)<01>);;)d<><64>MLL"><00> +<2B>Ͱ/<2F><04><01>#/<2F>ְͰ<10>+<2B> ͱ$+<2B><12> !99<00><12> "9901463!2#!"&73!2654&#!"!<03><>,<2C><><A5><EB><ED>ԥ<FE><D4A5>;)<01>);;)<29> );d<01><><01>,<2C><><A5><EB><EB>Ԣ<FE><D4A2>?);;)<01>);;)<29>pML<<00>+<2B>Ͱ/<2F>Ͱ/<2F><12><01>/<2F> ְͱ+<00><12>9<><12>9<><11>901!5 55!2654&#!5!2#,<01><>p<FE><01>);;)<29> <01><><90><A5><EB><01>,<2C><><C8><FE><A2><FE><A2>p<FE>;)<01>);<3B><><C8><EB>ԥ<FE><00><03><04>!(<00>/<2F><13><01>"/<2F>ְͱ#+<2B><12>9<00><12>9013!327636'&#676/#"<06>.<2E>   <17><><01> 
<04><><BC>K<13>J  i<01>  <06><><D3>VL?<00>+<2B>Ͱ<10>Ͱ/<2F>Ͱ/<2F>Ͱ<14><01> /<2F>ְ ͱ!+<00><12>99<39><11>9013!275!"&5463!5./"!5 5<><35>,/5<> );;)<01><0E>]]<5D><>X,<01><>p<01><><90><0F>;)<01>);<3B><02><><EB><A5>,<2C><><C8><FE><A2><FE><04><04>$T<00>+<2B>Ͱ/<2F><1A><01>%/<2F>ְͰ<10> +<2B>ͱ&+<2B> <12> $$9<><11>#9<00><12> "#$$9<><11>9013!26='#!"&546;7'#"%'!'<01><>,<2C><>Nz;)<29> );;)<29>vJd<4A><64><01>a<><01><><F4><95><01><><90><A5><EB>bI{<7B>);;)<01>);zN<7A><4E> V<><56> <0C><><95><04><04> Z<00>
/<2F>Ͱ/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>Ͱ<10>+<2B>ͱ+<2B><12>
$9<00><12> $901$  $ 6& 462"<04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>r<>rr<72><01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56><12>rr<72>rL<04> .<00> +<2B>Ͱ/<2F>Ͱ 2<01>/<2F>ְͲ
+<2B>@ +<2B>+011463!2 !!35#  <10><01><01><><C2><FE><D9><01>dd 
<FE><ED> <20> <01><01><>p<FE>v2L<04> +<00> +<2B>Ͱ/<2F><05><01>/<2F>ְͲ
+<2B>@ +<2B>+011463!2!!! 35#  <10>,,'<27>C^dd 
<FE><ED><02><><BC>,<01><><F4>2L .<00> +<2B>Ͱ/<2F><05><01>/<2F>ְ 2<>Ͳ
+<2B>@ +<2B>+011463!2 ''35#  <10>1T<><54>F<FE><02>dd 
<FE><ED><02><><C1>T<><54>F<FE><46>:2L<04> +<00> +<2B>Ͱ/<2F><05><01>/<2F>ְͲ
+<2B>@ +<2B>+011463!27'%'35#  <10>a<>ap<02><03><>ԕ<01>dd 
<FE><ED><03>b<DC>a<D5><61><02><><BB>ԕ<95> 2L<04> .<00> +<2B>Ͱ/<2F><05><01>/<2F>ְ2<>Ͳ
+<2B>@ +<2B>+011463!27'7 35#  <10>|<7C>b<D4><03><>ԕ<95>cdd 
<FE><ED>d<>a<D4><01><><EB>Ԕ<95><02><><B9>2<17><><04><04><00>+<01> /<2F>ְͱ
+01  <04><>%<25><>O<02><>`<01><10><><10>w<01><><03><>8dL<04>M<00>/<2F>Ͳ
+<2B>@ +<2B>2<>
+<2B>@ +<2B>2<01>/<2F>ְͰͰ<10>+<2B> ͱ+<2B><12> 99901546;!3+!#"&35#<15><01>d<F4><14><>D<FD>Xdd<64><03><1E><>,<2C><><C8><01><>pg<>><04>@<00>/<2F>Ͳ
+<2B>@ +<2B>
+<2B>@ +<2B>2<01>/<2F>ְͰͱ+<00><12> 99901546;!3'!#"&%735#<15><01>d<F4><64><C8>x~<7E><><FE>E{xa{<7B>%<25>dd<64><03><1E><>,<2C><><C8><DA>x<78>p<1D>{x`{<7B>$<03><><04>#<01>$/<2F>ְͰͱ%+01546;!3'!#"&35#7'77'<15><01>d<F4>g<C8><67><AA><FE><D6><FE>Xddd<64><64><AA><7F><AA><7F><AA><7F><AA><03><1E><>,<2C><><C8>g<F3><67><AA><FE>pg<><67>ժ<FB><AA><7F><AA><AA><80><AA><7F><04><04>l<00>/<2F>Ͳ
+<2B>@ +<2B><10> Ͱ/<2F>ͱ22<01>/<2F>ְͲ
+<2B>@ +<2B><10>Ͱ<10>+<2B>Ͱ 2<>+<2B><12>9<00> <12>99<39><12>
901546;!3!!#"&% ##53<15><01>d<F4><64>p<FE> <0C>X,,<2C><><C8>d<C8><03><1E><>,<2C><><C8><FE><D4>p<1D><><AB>,,<2C><><02><><BC><04><04>[<00>/<2F>Ͳ
+<2B>@ +<2B>/<2F>ͱ22<01>/<2F>ְͰͰ<10>+<2B>ͱ+<2B><12>9<><11> 9<00><12> 999<39><11>
901546;!3'!#"&%333 53<15><01>d<F4><64><C8><C8><FE>n<FE>X<><58><C8><C8><C8><FE><D4>d<D4><03><1E><>,<2C><>n<FE><6E><C8><FE>p<1D><><AB>,,<01><><90><00><04>L 53!265!5!54&#!"5!L<1D>P<04><15><>d<01><>&d<><15><12><>f<04><04>
<00><00>/<2F>33<33>ͱ22<32>/<2F> 33<33>ͱ 22<01>/<2F>ְ
Ͱ
<10> +<2B>Ͱ<10>+<2B>ͱ+<2B>
<12>$9<><12>$9<><11>$9<00><12>9<><11>99<39><12>901!!5335335!5 553;5#,<01><>p<FE>dddd<01>,<2C><>ddddd<01>*<2A><><C6><02><><BA><C8><C8><C8><C8><C8><C6><FE><D6><FE><D6> <0C><><C8>d<04><04>/:<00>+<01>0/<2F>ְͰ<10> +<2B>ͳ +<2B>Ͱ/<2F> Ͱ<10>
+<2B>ͱ1+0173737+"&5%;2654&d22d22d22d<15>X
<15>$<1A><>%<02><01>dd<64><64>,dd<64><64>,dd<64>p<FE><70>A<01>d5!<05>sRtEd<04>L38<00>+<2B> 3<> 222<32>(/<2F>%333<33>2<01>4/<2F>5+<00>(3<12> 99013!5"&5!#!5".546?5!2!4635!2d<01>K<01>K<01>"2<19>pK<19> K<>p"28 &<01><>v& 88 x88 &<26>v<01>& 88 <0E><>LL *.2<00>+<2B>Ͱ/<2F>Ͳ
+<2B>@ +<01>//<2F>0+<00><12>$9013!2654&#!"!73%!!5!5!!%35!'!5%;),);;)<29><>);d<01><>i'<27>Wd<57><64>d,<2C><>,<2C><><01><>'i<>Wd<57><64><01><01>,);;)<01>);;)<29>D<FD>b<C8><62>d,<2C><>,<2C><><01><>bb<62>d<C8>F<FD><46><A3><04><04> 3?6&/&.'7>/.><3E>fgї{<1F><13>4v<><76>ev<0E>-<12><03>+<2B><><89>fg<66>=!<01>.<0E>ve<76><65>v1<14><11><04>L@/<00>+<2B> Ͱ(/<2F>8<B0><01>A/<2F>B+<00> <12> /99<39>(<11>&)2@$901=46754>2#!"&?>=6 6=.#"m&RpR&m<15><><14><1D>><3E><14>d|<7C>~\<5C>ud?, 2<>3/2 
2<FE><D1>3<14><02>!"<15><18>"!<15>A1)!((!
d<04>L<00>+<2B><01><01>/<2F>+0135!%!'57##5##5##5#dL<><4C><03>}ddd<64>d<C8>dddddȖ<64>d<01><><90><C8><C8><C8><C8><C8>pd<70>d<04>L $<00>
+<2B>3<01>/<2F>
ְͰ<10>+<2B>ͱ+013!4&+"46;2346;2d,;)d);<01>;)d);d;)d);<01>);;)<29>p<03>);;)<29><02>);;)<29>D<05><><04>L'+H<00> +<2B>Ͱ/<2F><04><01>,/<2F>ְͰ<10>+<2B> ͱ-+<2B><12> #(*$9<00><12> &()$901463!2#!"&7!!!#535!3#353#5#3d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d,<2C><><C8><C8><FE><D4><01><>dd<64>dd,<01>|<7C><>|<7C> |<7C><><02><><BC>,dd<64><64>ddd,d<>p,<2C><><05><><04>L'+H<00> +<2B>Ͱ/<2F><04><01>,/<2F>ְͰ<10>+<2B> ͱ-+<2B><12> #(*$9<00><12> &()$901463!2#!"&7!!3533##5#353#5#3d<>|<02>|<7C><>|<7C>D|<7C><><03><>|ddddddd<01><>dd<64>dd,<01>|<7C><>|<7C> |<7C><><02><><BC><FD><A8><01><><F4><C8> d,d<>p,<2C><><04><><04>L#D<00> +<2B>Ͱ/<2F><04><01>$/<2F>ְͰ<10>+<2B> ͱ%+<2B><12>$9<00><12>"$901463!2#!"&7!!!5#35!!5#35!d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d,<2C><><C8><C8><01>,<2C><><C8><C8>,<01>|<7C><>|<7C> |<7C><><02><><BC>d,d<> d,d<04><><04>LD<00> +<2B>Ͱ/<2F><04><01>/<2F>ְͰ<10>+<2B> ͱ+<2B><12>$9<00><12>$901463!2#!"&7!!-d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d,d,<2C><>,<01>|<7C><>|<7C> |<7C><><02><><BC><FE>,<2C>Ԗ<FE><05><><04>L'Z<00> +<2B>Ͱ/<2F>Ͱ#2<>/<2F>%3<>Ͱ/<2F><04><01>(/<2F>ְͰ<10>+<2B>Ͱ<10>+<2B>!Ͱ!<10>$+<2B>Ͱ<10>+<2B> ͱ)+01463!2#!"&7!!!%3264&+;#"d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d<02><><BC><FD>)69&<26>6)<29><>&,<01>|<7C><>|<7C> |<7C><><02><><BC><01><> dT<64>VV<56>T,<05><><04>L#)H<00> +<2B>Ͱ/<2F><04><01>*/<2F>ְͰ<10>+<2B> ͱ++<2B><12> !$'$9<00><12> "&($901463!2#!"&7!!!#535!3#35#33#d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d,<2C><><C8><C8><FE><D4><01>ddcdd<64>,<01>|<7C><>|<7C> |<7C><><02><><BC>,dd<64><64>ddd,<2C>p<01><06><><04>L!'L<00> +<2B>Ͱ/<2F><04><01>(/<2F>ְͰ<10>+<2B> ͱ)+<2B><12>"%$9<00><12> $&$901463!2#!"&7!!!#5#5335#33#d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d,<2C>ded<65>ddcdd<64>,<01>|<7C><>|<7C> |<7C><><02><><BC><01>d<90>p<FE><70>dd,<2C>p<01><06><><04>L!%+<00><00> +<2B>Ͱ/<2F>")33<33>Ͱ#2<>/<2F>Ͱ/<2F>&3<>Ͱ'2<>/<2F><04><01>,/<2F>ְͰ<10>+<2B>2<>!Ͱ!<10>+<2B>ͳ+<2B>Ͱ/<2F>Ͱ<10>"+<2B>%Ͱ%<10>*+<2B>)Ͱ)<10>&Ͱ&/<2F>)<10>+<2B> ͱ-+<00><12>9<><11>901463!2#!"&7!!5!##53553!5353#d<>|<02>|<7C><>|<7C>D|<7C><><03><>|d,cdc<64>d,d<01>d,<01>|<7C><>|<7C> |<7C><><02><>d<C8><64>dd<64><64>pdddd<01>d<90> <01><04><04> y<00>
/<2F>Ͱ/<2F>Ͱ/<2F>Ͱ/<2F><04><01>/<2F>ְ Ͱ <10>+<2B>Ͱ<10>+<2B>ͱ+<2B><12>
$9<><11> $9<00><12> $9<><11>9<><12> $901$  $ 6& 57!!!!<04>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>d,<2C><>,<2C><><01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56><F3><FD>dd<64>d<04><04>  $<00><00>
/<2F>Ͱ!/<2F>3<>/<2F>Ͱ/<2F><04><01>%/<2F>ְ Ͱ <10>+<2B> Ͱ2<> 
+<2B>@  +<2B> <10>!+<2B>2<>2<>$<10>+<2B>ͱ&+<2B> <12>
$9<>!<11>9<>$<12> $9<00>"!<12> $9<><11>999<39><12> $901$  $ 6& !#5#3#353<15>D<12><><A0><A0><FE><EE><FE><BC><16>V<><56><F3><F3>,dd<64><64><C8><C8>d<01>D<12><><A0><A0><FE><EE><FE>_<><5F><FE><AA>V<><56><F3><01>dddddddd<02><><FF><F2><04>A r<00>/<2F>Ͱ<10> <20><11>Ͱ2<01>!/<2F>ְͰ<10>+<2B>Ͱ<10>+<2B> ͱ"+<2B><12>999<39><12> 99<39> <12>99<00><12>
$9<> <11> $901;!3264&#".#"333qO<71><01><>x<80><78>x.,,<2C>n<B5><6E>BU:<3A><><C8><C8><C8><01>Pr,<2C>ԭ<FE><D4AD>awי k<><6B>,<2C><><FE><D4><02><><FF><F2><04>A<01> /<2F>ְͱ!+<2B><12>99901; >54&#".#" ##qO<01><01>^y<>x.,,<2C>n<B5><6E>BU:,,<2C><><01>Pr<01><>m<1A>dx<64>awי k<><6B>,<2C><><FE><D4>,dLm7!!'5!33 33d<01>K^K<01><><90><FE><F2><AA><FE><F2><AA><FE>Ԫ<FE><D4AA><FE>ț--<2D>,,M<><4D><FE><B3>y7<04>)327!'32654'>54&'.#"&#"y9/iJ8,K^K.6Ji 2;{Y<1A>^t<> Ji<02>5XJi<1E><>--2iJ f=Z<>Yq<59>tiA<><41><A5><FF>_<<3C><04><00> .<00> .<2E>:<3A><><05><18><><18>:<3A><><05><00><01>(<04><04><04><04>d<04><04><02><02><01>F<00><00><00>HF<04>d<04><00><01><04><><B0><04><04><><B0><04><04><04><04>d<04><><B0><04><><B0><04><04><04><04><04><04><04>j<04><04><04><04>d<04><04>d<04><04>d<04><04><><B0><04><04><04><04><04><04><04><04>d<04><04>d<04><04><04><04><04><04><04><04><04>d<04><00><04><04><04>5<04>d<04><00><04><><B0><04>!<04><04><04><04><04><04><><B0><04><04><04><04><00><04><04>u<04><04><04><04><04><00><04><04><00><04><00><04><00><04><00><04><04><04>,<04>d<04><00><04><04><04><04><04><04><04><04><04><04><04><04><04><04><00><04>h<04><04><04>"<04><04><04><04>o<04><><B0><04><><B0><04><><B0><04>d<04><04><04><04>d<04><><B0><04>F<04><>:<04><04><04><04>.<04><04><04><><B0><04>J<04><04><04><04><04><><B0><04>a<04><04><04><04><04><04><04><04><04>d<00><>P9<00>'d<00>dddd<><64><FF><9C><FF><9C><FF><9C><FF><9C><FF><9C><FF><9C><FF><9C><00><><FF><F2>dy****f<00><00><00><00><00><00><00><00><00><00><00><00><00><00><00>0HP<01><01><01><01>6<02><02><02>,L<03>rd"D<06>L<07><07><08> 0 ` <09>
D
<88>
<EE> V <0B> <0B> > <0C>  v <0A>:`<0E><0E><0F>L<10><10>&<11>`<12><13> b<14>&<15>b<16>L<17><17>8<18><18>,<19><19>J|<1A><1A><1A>0N<1B><1B><1B><1B>Z<1C><1C>2<1D><1E><1E>F<1F><1F><1F>  * F n <20> <20>!j!<21>"B"<22>#~#<23>$$<24>$<24>%%<25>%<25>%<25>%<25>&Z&<26>&<26>&<26>''j'<27>(8(d(<28>)6)<29>*n*<2A>+h+<2B>+<2B>,D,<2C>-<2D>-<2D>.f.<2E>.<2E>/:00<>1&1~1<>22<>3`3<>44<>55f5<66>66\6<>7
7`7<>7<AC>8P8<50>99X9<58>9<96>::^:<3A>:<3A>;,;t;<3B><@<h<<3C>=D=<3D>>>H><3E>><3E>?0?<3F>@@`@<40>A"A<>A<88>B<F0>B<82>C<F8>C<88>D<D`D<><00><00><00> j (| <00> L<00> 8<00> x6 6<01> <01> <01> $ $4 $X <00>| <00>0<02>www.glyphicons.comCopyright <00> 2013 by Jan Kovarik. All rights reserved.GLYPHICONS HalflingsRegular1.001;UKWN;GLYPHICONSHalflings-RegularGLYPHICONS Halflings RegularVersion 1.001;PS 001.001;hotconv 1.0.70;makeotf.lib2.5.58329GLYPHICONSHalflings-RegularJan KovarikJan Kovarikwww.glyphicons.comwww.glyphicons.comwww.glyphicons.comWebfont 1.0Mon Jan 27 08:01:34 2014<00><>2<00>  
   <00> !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~<01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>glyph1uni000Duni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni25FCuni2601uni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200<30><01><><FF><01>K<>PX<50><01>Y<8E>F+X!<21>YK<59>RX!<21><>Y<1D>+\XY<58>+R<>X<E6><?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
<font-face units-per-em="1200" ascent="960" descent="-240" />
<missing-glyph horiz-adv-x="500" />
<glyph />
<glyph />
<glyph unicode="&#xd;" />
<glyph unicode=" " />
<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
<glyph unicode="&#xa0;" />
<glyph unicode="&#x2000;" horiz-adv-x="652" />
<glyph unicode="&#x2001;" horiz-adv-x="1304" />
<glyph unicode="&#x2002;" horiz-adv-x="652" />
<glyph unicode="&#x2003;" horiz-adv-x="1304" />
<glyph unicode="&#x2004;" horiz-adv-x="434" />
<glyph unicode="&#x2005;" horiz-adv-x="326" />
<glyph unicode="&#x2006;" horiz-adv-x="217" />
<glyph unicode="&#x2007;" horiz-adv-x="217" />
<glyph unicode="&#x2008;" horiz-adv-x="163" />
<glyph unicode="&#x2009;" horiz-adv-x="260" />
<glyph unicode="&#x200a;" horiz-adv-x="72" />
<glyph unicode="&#x202f;" horiz-adv-x="260" />
<glyph unicode="&#x205f;" horiz-adv-x="326" />
<glyph unicode="&#x20ac;" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
<glyph unicode="&#x2212;" d="M200 400h900v300h-900v-300z" />
<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
<glyph unicode="&#x2601;" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
<glyph unicode="&#x2709;" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
<glyph unicode="&#x270f;" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
<glyph unicode="&#xe001;" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
<glyph unicode="&#xe002;" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
<glyph unicode="&#xe003;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
<glyph unicode="&#xe005;" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
<glyph unicode="&#xe006;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
<glyph unicode="&#xe007;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
<glyph unicode="&#xe008;" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
<glyph unicode="&#xe009;" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
<glyph unicode="&#xe010;" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
<glyph unicode="&#xe011;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
<glyph unicode="&#xe012;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
<glyph unicode="&#xe013;" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
<glyph unicode="&#xe014;" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
<glyph unicode="&#xe015;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
<glyph unicode="&#xe016;" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
<glyph unicode="&#xe017;" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
<glyph unicode="&#xe018;" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
<glyph unicode="&#xe019;" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
<glyph unicode="&#xe020;" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
<glyph unicode="&#xe021;" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
<glyph unicode="&#xe022;" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
<glyph unicode="&#xe023;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
<glyph unicode="&#xe024;" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
<glyph unicode="&#xe025;" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
<glyph unicode="&#xe026;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
<glyph unicode="&#xe027;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
<glyph unicode="&#xe028;" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
<glyph unicode="&#xe029;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
<glyph unicode="&#xe030;" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
<glyph unicode="&#xe031;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
<glyph unicode="&#xe032;" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
<glyph unicode="&#xe033;" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
<glyph unicode="&#xe034;" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
<glyph unicode="&#xe035;" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
<glyph unicode="&#xe036;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
<glyph unicode="&#xe037;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
<glyph unicode="&#xe038;" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
<glyph unicode="&#xe039;" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
<glyph unicode="&#xe040;" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
<glyph unicode="&#xe041;" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
<glyph unicode="&#xe042;" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
<glyph unicode="&#xe043;" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
<glyph unicode="&#xe044;" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
<glyph unicode="&#xe045;" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
<glyph unicode="&#xe046;" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
<glyph unicode="&#xe047;" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
<glyph unicode="&#xe048;" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
<glyph unicode="&#xe049;" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
<glyph unicode="&#xe050;" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
<glyph unicode="&#xe051;" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
<glyph unicode="&#xe052;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
<glyph unicode="&#xe053;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
<glyph unicode="&#xe054;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
<glyph unicode="&#xe055;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
<glyph unicode="&#xe056;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
<glyph unicode="&#xe057;" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
<glyph unicode="&#xe058;" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
<glyph unicode="&#xe059;" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
<glyph unicode="&#xe060;" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
<glyph unicode="&#xe062;" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
<glyph unicode="&#xe063;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
<glyph unicode="&#xe064;" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
<glyph unicode="&#xe065;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
<glyph unicode="&#xe066;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
<glyph unicode="&#xe067;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" />
<glyph unicode="&#xe068;" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
<glyph unicode="&#xe069;" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
<glyph unicode="&#xe070;" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
<glyph unicode="&#xe071;" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
<glyph unicode="&#xe072;" d="M200 0l900 550l-900 550v-1100z" />
<glyph unicode="&#xe073;" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
<glyph unicode="&#xe074;" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
<glyph unicode="&#xe075;" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
<glyph unicode="&#xe076;" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
<glyph unicode="&#xe077;" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
<glyph unicode="&#xe078;" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
<glyph unicode="&#xe079;" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
<glyph unicode="&#xe080;" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
<glyph unicode="&#xe081;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
<glyph unicode="&#xe082;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" />
<glyph unicode="&#xe083;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" />
<glyph unicode="&#xe084;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
<glyph unicode="&#xe085;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" />
<glyph unicode="&#xe086;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
<glyph unicode="&#xe087;" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" />
<glyph unicode="&#xe088;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
<glyph unicode="&#xe089;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
<glyph unicode="&#xe090;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
<glyph unicode="&#xe091;" d="M0 547l600 453v-300h600v-300h-600v-301z" />
<glyph unicode="&#xe092;" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
<glyph unicode="&#xe093;" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
<glyph unicode="&#xe094;" d="M104 600h296v600h300v-600h298l-449 -600z" />
<glyph unicode="&#xe095;" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
<glyph unicode="&#xe096;" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
<glyph unicode="&#xe097;" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
<glyph unicode="&#xe101;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
<glyph unicode="&#xe102;" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
<glyph unicode="&#xe103;" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
<glyph unicode="&#xe104;" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
<glyph unicode="&#xe105;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
<glyph unicode="&#xe106;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
<glyph unicode="&#xe107;" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
<glyph unicode="&#xe108;" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
<glyph unicode="&#xe109;" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
<glyph unicode="&#xe110;" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
<glyph unicode="&#xe111;" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
<glyph unicode="&#xe112;" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
<glyph unicode="&#xe113;" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
<glyph unicode="&#xe114;" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
<glyph unicode="&#xe115;" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
<glyph unicode="&#xe116;" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
<glyph unicode="&#xe117;" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
<glyph unicode="&#xe118;" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
<glyph unicode="&#xe119;" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
<glyph unicode="&#xe120;" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
<glyph unicode="&#xe121;" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
<glyph unicode="&#xe122;" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
<glyph unicode="&#xe123;" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
<glyph unicode="&#xe124;" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
<glyph unicode="&#xe125;" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
<glyph unicode="&#xe126;" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
<glyph unicode="&#xe127;" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
<glyph unicode="&#xe128;" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" />
<glyph unicode="&#xe129;" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
<glyph unicode="&#xe130;" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
<glyph unicode="&#xe131;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" />
<glyph unicode="&#xe132;" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" />
<glyph unicode="&#xe133;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
<glyph unicode="&#xe134;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
<glyph unicode="&#xe135;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" />
<glyph unicode="&#xe136;" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
<glyph unicode="&#xe138;" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
<glyph unicode="&#xe139;" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
<glyph unicode="&#xe140;" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
<glyph unicode="&#xe141;" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
<glyph unicode="&#xe142;" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
<glyph unicode="&#xe143;" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" />
<glyph unicode="&#xe144;" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
<glyph unicode="&#xe145;" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
<glyph unicode="&#xe146;" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
<glyph unicode="&#xe148;" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
<glyph unicode="&#xe149;" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" />
<glyph unicode="&#xe150;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
<glyph unicode="&#xe151;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
<glyph unicode="&#xe152;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
<glyph unicode="&#xe153;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
<glyph unicode="&#xe154;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
<glyph unicode="&#xe155;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
<glyph unicode="&#xe156;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
<glyph unicode="&#xe157;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
<glyph unicode="&#xe158;" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
<glyph unicode="&#xe159;" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
<glyph unicode="&#xe160;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
<glyph unicode="&#xe161;" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
<glyph unicode="&#xe162;" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" />
<glyph unicode="&#xe163;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
<glyph unicode="&#xe164;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
<glyph unicode="&#xe165;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
<glyph unicode="&#xe166;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
<glyph unicode="&#xe167;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
<glyph unicode="&#xe168;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
<glyph unicode="&#xe169;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
<glyph unicode="&#xe170;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" />
<glyph unicode="&#xe171;" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
<glyph unicode="&#xe172;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
<glyph unicode="&#xe173;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
<glyph unicode="&#xe174;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
<glyph unicode="&#xe175;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
<glyph unicode="&#xe176;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
<glyph unicode="&#xe177;" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
<glyph unicode="&#xe178;" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
<glyph unicode="&#xe179;" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" />
<glyph unicode="&#xe180;" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
<glyph unicode="&#xe181;" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
<glyph unicode="&#xe182;" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
<glyph unicode="&#xe183;" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
<glyph unicode="&#xe184;" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
<glyph unicode="&#xe185;" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
<glyph unicode="&#xe186;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
<glyph unicode="&#xe187;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
<glyph unicode="&#xe188;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
<glyph unicode="&#xe189;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
<glyph unicode="&#xe190;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
<glyph unicode="&#xe191;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
<glyph unicode="&#xe192;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
<glyph unicode="&#xe193;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
<glyph unicode="&#xe194;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
<glyph unicode="&#xe195;" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
<glyph unicode="&#xe197;" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" />
<glyph unicode="&#xe198;" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
</font>
</defs></svg> oON<00>LP<00><><8C><F2>(GLYPHICONS HalflingsRegularxVersion 1.001;PS 001.001;hotconv 1.0.70;makeotf.lib2.5.583298GLYPHICONS Halflings RegularBSGPv<>5v5|-\<12><><CD><E9>`<60>W<D8>hKqJx"U:r,/<2F>4\<5C><> li<6C><69><D2><DB><D3>ʚ<06>E<9D>LFM<46>ƀ<14>V(g<>W\<5C><>+rK0
Q<C1><AF><C8>3-O><3E>C<82>d<7F>g<8A>e}\<5C>4<F8><34>[Dd<1B><>p<>WQ<57><51>@<40><><DA>J[<0E>M<A8><4D><1F><><86>UA<55>Н<83>j<><6A>.p<><70>`k<>*C<>I4ث<14><>o\<5C> <09><>w<C0><77><9B>fv<66><76>XD<58><44>lB<1A><>g1<67>[/a<11><1D> 2<>l<C0><6C>E<96><45><9D><FF><B1>2<><32><E4>g2<67>9<B5><05> <0A><1E>zGDUB<55><06><>A<E6>$L<><4C>}Xʕf<CA95>z;N2<4E><32>_<DE><5F><BF><9E>;(<28>k<8E><6B>@B[<5B>!<21>6P<36>3<A7>G
<10>E]{<7B><><C8>JW/s<><73>4<AB>%<25><><EA>ߙ<1B><><A3><E8>_<1D>}}c<>O-4lP<6C>aDX<19>[<5B><>q<>v<00>*<2A>X,<2C>u *
<86><D6><C0><B7><EE>z<A0>3JL<DA>}<7D>
0<E5><19><><83>VjUyjn<6A>)<29><16><><86>O0;<3B>0!<21>-!r"&bbl,-`<60>Q<E3><51><90>|/^<5E>L<><4C><B8><FE>V<08>R<DF>uz<75>Ԫ<FC>I<07><><B0>Ъ<F7><D0AA>!<19><>k<EC>&)J{.t<>S?<3F><><99>iS<69><53><BD><80>diVD<56>1w b<><62>]<06><>D<AD>*<2A>%qs<71>PD<50><44><BF><A2>ẍ<00>p
EG`<60><><98>+<2B>w:<3A>V<A0><56>*X<[<5B>l<><6C><F1>M<><19>
<12>.<2E><>ΡSh<><68><A2>qk<71><6B>"<22>
<C2>J <20><>MT6<54> c<><63>k<FD>a<89><7A>nq<><71>m0<6D><30>pDJ<44><4A>v<CC><FA><EFA69E><CE><C1><FF>F<D8>v<E7>(<28>S<82><53>(<02><>MI<4D>ӶF<D3B6><10><>K<><4B>m<H<13> <0B><><C5>q~|M<>X`~Is<49> "<22><><92>;<3B>#<23>8<82><14>xƘ<>+<2B><><86><DA><CA><DE><06>m` <0C><>-I`<60>><3E>"<22><18>=<0E>-<2D><>B(><3E>Qe<51>Yeg<65>䜊7 <0B>.<03>_<FB>j<AA>&LK<> 9zR<7A>u<BC>C<81><43>
<E9><94>&B<>0 <0A><01><><E8><87><E2><94>_<DD>C_<43><5F><11><><88>{4<>W?<3F><>N<84><4E><E8>"$<19>#<23><>D<FD><93> :J4<06>/<2F><><A8><9B>횶G<1B>J;]<5D>w<C4><77><E8>d<DB>:<3A>H9<48><13>®<B4><C2AE>[Ԩ* K<C2A0>
<99>#<23>8A$a`]ڞ-TE7 $ :<3A>sp†f L$}Z<><5A><96><96>b]<5D>b<E3>6<1A><><D4>H<BE><48><FD>rx-t <0A><><83>jViMj<4D>N^[<5B><11>8<03>>Cn7L <0A><><90>&+3W6<57>G<<3C>B<15>O<><4F><AB><82>2A:<3A><AA>K<92><4B>='<27>=<3D>J<F9><4A><BF>Bƃh<C683>2<90><32>"d<><64><19><><D7> <09> <09> <20>O<i܊ۢ<DC8A><DBA2><C5><E0>Kpi,<2C><01>V<AC><56>N<FD>^<5E>4Rhx-<06><>BSْ<53><D992><94>[9U<39> "An<41> <09><>oh+<00>F<86><46><AB><F9>1<16><><12><>r<~{N<><4E>9 <0A><>4rI<72><49><96>ېU<DB90>`p<1F>zt<12><><C9><08>m<D9><6D>gu<><75>;<3B><>Z<8C><5A><B2>|8D <0B>S M<>K;<3B>ȩ<03><>˫@~%
<FA><9D>xv@A<> iI<13>&<26><13>ûڊ<C3BB>4<88><34><82><B6>c<8F>Q2}0<>.<2E>G<97>~<7E><><9E>y<E3><79><A0>#<23> <20><08>Z-<2D><><BF><97>-<2D><00>ʞ<AB><CA9E>%j<>)u/<2F><16>v<>a<86><61>I,g҂<05><><05><><1E><00>"<22>l&<03>8<E2>@<40>Q'<27> ?<3F><><1D><>qO8lG<6C>OeƔ<65>jjKj &<26><><A8><D1><D6><FB><FF>
<89><10><><ED><A3>c<0E> <11>F<18><>G[x<><78>H<8D><48>M} Ȑ]8<>y<A2><79>e<A2><65><F1>6<11>[=3[<5B><>ҚF<D29A><18>V<D1>H]<5D>p<EA>&Y<>\W<><57>V<AF>Y _<>P<CA>tP[<5B> <20><>Pu<50>>8<><38>6<D7><1D><><17>X<C0>nf<6E><66><A6><06>i<EE>?<3F>4 <09><><F5>}<1D><><<18>4 <20>ζfV<66><56><E1>Geb}<7D><> <0B><><A3><F3>s i<><01><>{OE<4F><45>n#<23>&QP6D*BLB<00><1F>1<>SRk<52>D<F7><44><F7><B5>XX<58>><|0;<3B><><95>ڈ<EB>5<80>5<>C~<7E><>4<D4><34><A4><FA><F3><BA>?<3F><>:P<>}"<22><>%<25><>ut5<74><35><97>I<8A>!<21><><B4>9<9C>l<BE><6C>$!<21><><A0>yM<79>T<C5>><3E><>'<27> O<>tqa?^<5E><><E2>Em<45> ߲<>C<B2><0F>s<94>S|-nH <0C><1F><>q<F8><71>#Yt<59> <0A><><E4>k <09><>¹<16><><F0><8E>Ǯ<DC>s<9F>%<>bCW/|<7C>`F<>\<5C>b,<2C><>ɏ2H<32><48>2<F5>/<2F>94# ~<7E>e<DD><65><10><><87><FD>c<CA><63>ĩ"<22>Q<><51><E3><E2><C0>7<89>:<3A>Z<D2>I֋]%<25><><A2>Y<E0>*<2A>B;8aFx<46>ʩb<CAA9><5F><CD9F>- *<2A><06>)<29>4<0F>?<3F>j<>@<40><10>5Q'<27><>P8<><38><F4>Gr<02><><B4>)<29><><G<>F<05>4<94><34>G{<7B><>6<B5><36><8B><F2>;<3B><><E3>ԉs<D489><73>$z%<25>q<F6><71><8F>[<5B>
B<9F><89>ONDM#<23><><0*0<>.3.<2E><>N<F9><4E>6FQg,<2C>4V<34><56> <0B><10><><DF><C0>'<1F>,<2C>ʲ<CD><CAB2>G<00>U X<><58><FC>BiU<69><55>=M <09>K<C9><4B>@<40><><16><>boB<<3C><><F4><92><94><83><1D>@<40>]<5D>̈<10><00><><AC>a<BD><61><E9><D0>7<E8>`<<3C><>T<C7>&r1=<3D><><08><><EE><03>V<84><56><A4>4DaD<>2<1F><1C>x<C3><15>u<BC><02>)<08><>ڎ<1A><>i<9A><10>Ov<4F><76>
dbH<F6>i<E9><97><C5>Γ"<22> F]@<0F><12><><D9><C0>Ą<BA><C484>!6&<26>
G-<17><><0F><><92>踃/t<><74>C<><43><B0>x<C7>4;<3B>D<9C><44> <20>ۧSU<53>S<1C>[<5B><>O/<2F><><A8><B2>'<27>uKR-l<>k<FB>Ư'<27><>^[<5B>BV<42><56><BD>,<2C>R<88>JKذT^Eg<><67>\<00>2ژ,<17>U&љ+u <20><><F7>w<B6><77><ED><ED><F5>b<84><62><17><>rK<>H<8B><48><F1>r<><72> }F<><46>*<2A><>w<><77><8F><11>" <0B><><E6><08><>R9<52>D<81>A<B5><41>Y
<A8>=7G<37><47>P*<2A>=+<2B>;N+P
<06><>x<B2><6C>("<05>c{<7B><><47>_<FB>xۢƴHE-Bᔡ`\_<16>`<60><>T<90><54>X<91>i<8B>C<DF>O<F5><4F><0F><>!;<3B><><8E><CA><FD><1B><><E4>#<23><><9B>$<24>QC<51>U<>(<28><>75D<35>
Ѥ<><02>d<E2><11>=<3D> <0B>>dZ<64>0t<><74>j<E0><6A>g<A1><67>v2<76>-ēx<C493>U <1D> <0C>3,7t<><74><C2><CE>a<A1>,(<28>5<E2><F2><C2B6><88><84><00>Y<><59><D0>E<C0><45><C1>$<24>6<97>s<D6><73><CC><E2>B܉O<DC89><4F><B0> c<>:
<B8><88><F5>:<3A> <20><><D2>R.yaHX<48>%<25>1yL7<>A<D0><41><D1>z5<7A><35><8C>o<A0>*<00><>n5<6E>e<F3><65><AF>)oF<6F><18><>aDe`hp"Q<1F><><9B><B7><02>Yo<59><6F>O<><03> <20>4o<34><6F><A1>p<94>s0<><30>OE
Y)b<08>8x<38>.<00>k<AF>+8U)+<2B>6-]K9<4B><39>pQt<51>&<26><07><>}<7D><>Snmb<6D>t<><74><BA><08>LM<4C><4D>w<><77><F5>XsSIj<49>><3E>I<F5>Sj 2`%<25><><1D><02><>9<DE>4<EC><34><81><91>}<7D><>=J<>A<BD>v<85>D j<><6A><8A><D2>ؓ<82><D893><D5><E0>T<E0>[<00>P<>#<23><>a<1D>W<AC>0Tt-~z<><7A>I<AF>,<2C>6<91><36>U2<55>)<29>'<27>\<5C><><82>v<94><76>
<F0><FC>S<95><91>R<8A><EF>P<1B> Znq<><71>"abE<62><45>rwL1<4C><31><81>U[<5B>n @G[9y3s<33><73>;! r퐽"04{<7B><>2 faJ <0A><10>)<29>"P:<3A> <0B>6<BF><36>3'Z7\<5C>H5<>9<E0><39>NT<4E>t
<F9><AE>}<7D><>;wL<>.<2E><>td<><64>q<02><17>w<><01><>o
<8A>Ή<B5>)<29><>"f.d<>x<FA>Cz
KFNǢh<1A>F<9C><46>@<00>ᡰ)1V<31><56>a<EC><61>P<E3> JV<01><>,<2C>B{&<26><><8E><1D><1B><1D>f<05> p<17><08>ph<70><68>x<C6>O2<4F>%8<><38><9D> Q<><51>PL:e<><65><13><><8D>ϨiN<69><4E><><DF9F><F1><A7>Ғ<D4>]<5D>Q$<24>{3<><33>qN<><4E><CA>%<25><><82> Ot<><74>=j<>xgP<67><50><13>ΰ<8D>FK<46><4B><FC>^{<7B><>f<A5><66><85>?^<5E>/<2F> O<>\<5C><>:<3A>JD;<3B><>Q`c<><0E>^!<21><>dv<64>k<E8><6B><80> <09>e<E5>3<>a<92>IC<0E> <20>d6 <20><07><><90>IȚ#\},<2C>?H<><48>f3<10>c<D8>U<><55>w<E1><77>+<2B><>$<24>U[":<3A><><A8>}<7D>]j<><01>b(Es)<29>`<60>%\¥<><C2A5>U<CD>.#]v/)<29><15><><08>K:I<02><>c<F0>4<>ó.c$<12>C<FE><43>?f<> `+<2B>6<C8>cx$#[ߺ<> f& h,<2C>A4<41>-<2D>g<C1>`<60>?<3F>$<24><>1 1<>bB5<42><35> <0C>
X`h<><1E>^<5E><><CF>2<F8>*<2A><><95><02>"<22><>`<60>P<A7><50><B0>R<F9>o<><6F>o<9E><6F><8D>פ)jk<6A>7<>L"<22>3<B6>|{y@<40>պi<17><><15>w@&<26>}g$<24>s<>u<92><75><D9>"򩄕_<F2A98495><5F><86><F5><9B>[n
7(<0E><><AF>)<29>D`<60><>Q<E6><51><B8><E9>Ŕ<B4>m><3E>@<40><>cgDD~xp<02><><90><99> <20>}`<13>t<89><74>o<82>H<D6>T<14>u<AB><75><BC>ҁ)<29><><D4><CF>m7$'<10>,h<> XN<>rl<04><07>u<92>5_<<3C>g<83><67><DF>L<AA><><D4A2>+<2B>^<5E><><06><><F0>ā-,<17>,<2C><>ii΃Ċ<CE83><03><><B0>B<D9>2<><32><8A><B4>.<2E><><BC><A0>D<E9><44>!^<5E> <09>B*<2A>&h<><68><93><02><>z<B6><7A>[s<><73>בrIXe<13>>@>[ƍ<><C68D><h<>Bܧp<DCA7>n<B6>[*<2A><><B2><16>d<08><><83>p,֋<><D68B><E8>¾<E7>@K\<5C> <0A>D$SL<53><4C>)<29><>B<><42>D<D6><44><81><AE>/<2F>oW T<>f<BB><66>ᓄ"@<08> FT<46><54>P<>QA*<2A>/<05>Ր<><D590><91>ZK<5A>3A_<41><5F>^<5E>+<0E><><B6>[9 <09>װ<><D7B0><CA>Cf<43><66><13><14><><0F><>͏<A1>B<D5>PxT<01><><B4>="0<><30>j<D2><6A>U<EC>a<A3><61>J<D1><4A><BD><E9>SU<53><55><9E><A7><69><DC86>m<B0>ҿD<D2BF><44><D9><1D>{-<2D> s<>i
<0C><><93> K<><4B>s<><73><F8>eD<65><78>z<83>D<80><44> D<> ̶<>B<D1><42><C1> <0C> <03>A=%a<>,<2C> <09>T<C5>$<24>l9<6C>"<22><><BA>Œ~3<>m<9D><6D>P<F2><17><>h<9B>m6<6D>ʈR:<3A><><88><D6><1B>ak<61>: <20>m<><6D>0<94><30><1B><>Q,<2C><><65>Պy <0A><>FR<<3C>b<><62><88><02>i<12><>?<3F>i<E1><69><90><10><><12><><83>Dz%i8<02><>}<19><><C1><17><>.<2E>s<04>ƙ<B7><C699>3L]<5D>Gv<><76>4c<19>q<AC><71>u<($)<29>`U<><55><1B>x<D9>ۿ&<26><>߮<07>1 &<26><>p<><3E>Ĭ]6<><36>ݏ<1F><>S@<40>&<26>ƛ2<C69B><32>@<40><>4<><34><D9>w|{<7B><> ߤ9<DFA4>.<18>F<CE><46>d<B6><64><B0><85><E9><CF>q<9C>r<>(<28>A<85><41><1D>#ADp#6<><36><18><><D5>=rR<72>
{<00>x<FA>P<EA><50>(<28><>Q@"<03><><9C><D5>ޥ&Ϡ]<<3C><>p3{<7B>><3E>a <0B>y[<5B><>J(<28><>%;MA<4D><41> ~NdR;<3B><>>4h<34>Y<13>j<F4>Q<E7>=<3D>yæ[<5B>`\<5C>h :L]<5D><><B2>}<7D>~0M<30><14><><94><BA>l<<3C>T<BB><54>+ L(XBE<42><45>WrK<72><4B><FC>K<E4><19>ۦ@<40>m<DF><6D>HSJ&<26>9<>)1_zD<7A><44> O<>MK<4D><1A>GC <20>&N!<21>ֶe|ɹl^<5E><><0E><> <0C>8$5<>,<0E><>,<2C>k<A2><6B><<3C>0<C1><30><89> <09>
<91>n<CB>+<2B>Yx<59>2<>Oc<4F>Z#VƖ<56><14><16><>*<2A><1D><><97><F6>Ϧ<B0>0<C2><30>lY<12><>a<><61><C8>CB<43>~P<><50>8L<>5a6Ĵ<36>Y<FB><59><F9>*<2A><>\ <0B>z<1D>lq<16>z<81><8C><7F><BE><FD>hR<68>o<84><6F><B3><A0>)(]<5D>t<F0>h<CD><68>F<B1>(<28>Y<>T<BC><54>/h<>b<A5>5<E2><11>/O]<5D>`ОV<0E>Z5<5A><1D>Fs
b<AA><C5><11><><BA>K<FE>a<C8>i<81>ie<69><65><FA><D0><F9><E5>J̀O/L<>sWP<57>yC<79><43><B7><80><A2><EC><D1><07>XX<18>n<8E> $<24>N<>C<06><>mF*wgF<67><1C><><BF><01>;<3B>u<86>iy<69>(<07><><8A>?<3F>N<>_<AB>Zh13 <0B><><C1><1C><>ĞyX`]#<23><08><><1E>+<2B>X<E0><58><95><86>H<01>#zn<7A><1D><><C5>P)z<>u<DA>n<81><6E><84>Z<D8><5A>L%4<>n<BA><6E>Az<07><><00><>3y<33><79>V<90>a <0B>}<7D>/V'<27><><B6><F0>2<CF>GE<47>̩t'<27><<19><><C6><E8>K:<3A>i`8<>M<90> ȇ>0F<30>#<23><><92><B5><97>S<07><>2<D3>zB!<21><><1D>TC<54> l-<2D>c:Tl占b<E58DA0><04>P<02><15><>I<F0>S;<3B><><A5>K<04>Μ<D7><CE9C>NW<4E>pw}<7D><>R#<23><>;<3B>~<7E> <0B>-b;<15><1E><>} <0B>3@<40>=6<>]<5D>Ӧ<AF>ؒAy<41>0<E0>h<A6>)<29>?<3F><>(o^<5E>2<><32>Ri}l[<5B>=<3D><71>P41<05><><94><A8>8󅷞<38><F385B79E>8<E9>@B<>B<89>8<C2>Rjp><3E>ފ<D0>v<CE><76>P<>-'<27>KU<4B><55><1B>L<12><>R<B4><52><9D>C<80>a=<3D><><A4><FA><AC>r'}ݨk<DDA8><6B><9C><A7><B7>Fp<><70>6<>H<94>bI,F<>o<C8>1<A6><18><>r<C6>'"<22>չ<AC>&<26>&lI{&Qf<51><01><>2a<32>\L<08>)A<>Rہ<52>Q<02>DX<44><58><91>:<1C><>v<F5><76>aiGGw޶
<08><>/<2F><11><>0$<24>O0&<1C>#<23>H9<48><39>o(<28><><D0><EF>sQƬ<51>"<19><><9A><13>M<><4D><F0>Lj<FE><19>L<><1D><><FA>7<C7>L5
<1B>y<9E><79><97><><C99A> <09>Y<C1><59><1A>%<25>w<>t+55Z<35>(<28>)<29>͊<D8><CD8A>BvM<><4D>K<F5><4B>0:$<24><>»<CB>8!0<1D>Ab<41><62><F1>J<9A>#9pB́<42><CC81><B2><BD>@E(<28>C<>u<A2>O<85>P<|h<13> <0A> <09>s<99>R<EF>y<F9>n<E9>x@<40><1D><><8A>fr:„<>i<90>1<1A>Z<97><14>BLnѫ<6E><04><>rtI-1<>x<11>,<2C>Fޠ1S<31>b'<15><>1C<31><43><FE><F2>I <0B> Y<07><>^<10>\<5C>U<0E><><C8>F;<01><><FC><14><><F2><C2><CE>=<3D><>6-T<>-<2D>H<BD>2G'<27>8<CD><38><99>H<95>9<>&$+<2B>d k?K<>(<28>J'<1E>q<CA>j <09>s`<60><><E2><B8><D4>*L9y<39>2@ <0C><><04>a<1A><>-<02><>*P<>k<><6B><1A>vW<12><>2<FA>F<16><><1E><><B7><AA><A7><0F><>0(<28><><0E><03><06><13><><E8><99><D8><E5><F6><97>tT<74>lh<6C>ш%q<19><0E><11>A.<2E>[<5B><><8F><0F>_g>9d<><64><E0>M<EA>x<F5>,mw<1B><>첌-{
<C1><A3><D8>3t<33>w<FB><77>61}<7D><>L<><4C><18>w<BC>f<A1><B1><E9A6B5><08><06>G<10><0F><><07><07>,h <19><?<3F><>"@9<>?<3F><>(><3E><>jZ<6A>Z8<>H<87>5<>t<A8><74><0F><17><><E3><C7><C1><94><D9>É<91><C389>@w<><77><8D>i<BA><69><08><><F4> Ku|<7C>A<94>I<D4>g<CD>n<B5><6E><FB>)<29><><01><><04>.}88<38>F@<40>*<08><>ʠ<FF>txV<>~J<><4A><EA><C6>Uw6A.<02><><84><89><8C>0n*<10>"<17>1-<2D><1F><>5<AD>9<92>dq<64><71><05>?<00>5<EF><35>L<15><><90><9E><F4>8<CE>v<>&
<E3><80>|<7C><><A4>֓I4<49><34>$H<><48><E3>]<5D><><8E>Z<EB>MUj/R-l\w׭O<D7AD><4F><00>U LQ<19>*<2A>`<60>r }krmVӛ<56>k^v<>J<D5><4A><C3><F8>S <0B>''<27>x<C3><78>Qi_<69>᭒d<E1AD92><64>4(Qn<51> <15><>\T<><54>-<2D><><9C><0F>VB<56>+ u<1C>xd<78>FȘW<C898><57><87>`<60>q<BE><71> <09>NB
\<5C><>5<E4>#3v<33><76>$<24>O#<23>ȧ,<2C><><02>*(<28>w\<5C><><A9><BF>h;^ʻ<07><>ƪ<A9> <0C>'<27>NYmLʿ<4C><CABF><EC>"<22><><C3>T<07>R<FA> <0A><>Cy<><79>.<2E><> <20><>>f <0A>D<1B><> <0B>k<AA><12>D<B2><44><D9>o<><6F><97>9<D6><39><F0><B6>/<2F><><E3>މ׮<DE89><D7AE><8F>=4fQ<66>؀<95><D880>'k5B$rL<1A><11>줁t<ECA481><74><D0><EF><E4>I<E9>L<><12><><E9>?P<>!>Mf0<><30>+<2B>^˪!Ѡ<>>5Ĩ&y<><79><98>_<ED>d<92>A<1E>+<14><><DA>1<C2><31>f+<2B>#<23>X@<40>ח<D6><D797><89>č<D6><13><><17>S.r;0~RP72ř|$<24><><98>o<F8><6F><AA>V<14>X<B3>Ba<42>?<3F><>^ b~<7E><><9A><FE>*<<3C><>L~<7E>0<BB><30><14>$<24>)<29><19><> <09><13><>y<84> J<>U_<55><5F>$DE<44><45><CB>2<CB>c<90>{A!;<3B><>ZO 5e<35><65>6<02><><AC> <09><>Ze<5A>U<E9>C<FF>-Z<>͢<><CDA2> <0B>֘k<D698>\f3\<5C>e<FC>%J<><4A>3<03>+ KE<4B><45> V<><56><00>Ɠ<E4>A<C9>p4bsŜwI<77>=?<3F><>"<22>x<>Ӡ<B8><D3A0><D7>ф-E<><45><EB><C9><C6><E7><FF>
<E3>
8Yb<59>$<24><><1A>:<3A><><E5><89><EA>e) yYP<><50>;<3B>̰<A1>b<><62>d<E9>O)<29>w<F3>BAe777|<7C><>*<2A>b<62><A<><41>[<1B><><F9>ߘ% O<><4F>Wk^<5E>T+<2B><><B5><05><0E> M,!<21>ܪ<E7><DCAA><85> <20><><F5><10><>)<29><><D4><C1>5<F1><35>9<89>E<B6><45><FF>Ҋ$1]<5D><><01><>Ė<B1><50>jc3yC<79>F<A1>Q?es<65><73><EE>ft<>:<19>, a<>lG<6C>l<D8>:͟k<12><><C6><D7>`<60><><BC><F5><97><98>f<BA><66><DE><D5><DA><EE><C1>6c<36> ~<7E><>Ze<5A><19>a<08><>q_<71><5F><06><>A4<>a5<61><35><F5><18>1<>3Ue<55><65><91><A7><BE><A6><1E>6<AB><05><><9E><92><A3><87>jo<6A>V<DF><56>s<FA>Xo΃<6F>{<7B> <0B><><BD>7y<37><79><92><F7>0ζ_2f<32>JNN<4E>]<5D>Ƕ<D0>b<12>V<F4>@<40>ǚ<FD>5lCAM*<00>V<9A>v<C2><76>S<88><06>s<D8><73>5<FF>Ug<55>VȺM<02>w<F5><77>D<D6><44><8A><FC>`<60>{<7B><><BC><86><1A><10>ˆ<7A><DE86>Zs<5A><73>96<39>ô*<2A>><3E>FT@<40><>J<><4A><89><95>ƪ3<C6AA><33><A1><84><E6>}/<2F><1D>S<CB>a<AE><61><82><1B><13>U<90>Ȫ<D5>j1SaB7~<7E>& FMs<4D><73>Ϝ<AF><CF9C>[<5B>><3E>+<2B> {<7B>1<06>Ys<59><73><04><><C2><EA>Ƞ@<11><10><>z(<03><16>=!؆<>73<37>މ<16>f<C7>z<8B><1F>e<8D>(<28><;oe<6F>3_'D<><44>Z<F8><5A><90><8F><DE><13>s5"b4g<34>dHC<48><43><84>oL<6F>5.<2E>6<FE>:<13>5<AA>}9$M<>Q<15><1A>'$<24>¥9D<0E>scM <09>|<7C><>)lI<05>E9<18><17><1A><>#C<><43>5L<35>J<>`<60><>fK<10><><AF>%<25><<3C>G<01>'<27><><B9><9A><85>PO<50>y<00>`<60>5<1D>5:<3A><>k<D7><6B><A8><BC>'<27><><89><E4>qg<71>uuq<75><71><98>[,<2C><>)<29><>Zb <0C>q|+ <13><<3C><>o[<5B><>!<21>'<27><><B4><99>NҨK<15>HX<48><58><85><B8><C1><AE>ɜ"r<01><><1D><14><> f<05><>l<8E>eh<65>)(<28><><E0>>{P,e& <0A>'<27><><90>S7<53>a<90><61><90><02>:<3A>n<>p<9C>-ąKz<4B><7A>Hhw%ɹm<C9B9>|lߝʍȝt<C89D><74><90><BB>e<><65><A3>0q9S_z/L[<5B> P{)<29><04>x<><00><>.<2E><><C6>{h<><68><B4>L<7F>ٷV)k<>ٮ<17><>q<CA><71><80><99><CA><F3><91><81>;jz<6A>@b<>2<D2>Q<88>`<60> 9~'3<><33>2<C8>j<A2><6A>F<89><46>
v<93>Q<D3><D1><E8>TdM<F1>@<><DCB9>P<A0>N<C4>q<FC><71><89>޺<08><><A5>Hі<18><><EF>J<D6>M<89><4D>rN2<4E>Q9}l̀
<92>(6<>,<2C>A<><41>; +<15>"<22><>:<3A>(<28>-$V<><56>3x6<78>AT<41>\<5C><15>"<22><>z<E3><7A>n <20><>%<25>*bo<62><05><>@o<17><04>JLB<4C><42>q<B3>Izi<7A>T<9C>N<1E><><1B><0E>9X<39><58>j<19><1F><<3C>39<33><39><89>'<27><00><>L<9B>R<08><>B$eY<65><59>Ğa<C49E><61>+<2B><>(<28><><F5>n2u<16>Cc<b<>Ml<4D><6C>!K<><0F><>瑽I<E791BD>z<96><7A>V<CA>v JJ;,'t3<><33>F<D0>It$KY<4B><59>^VG<56>.<2E><><ˬA<CBAC>Θ<E0>S'_<><5F>؞<F6><D89E> <0C>T<98><10><10>U<C5>R<C5><52><BD><EB8697>S<A8><53><E5>]<5D>o<A6>sy5;m*2<>D.L<>#-T<>eX<65><58>bL<01>a<B1><61><08> <0C><><0F><>z<>9^<5E><><C8>
V<>ȆP<C886><50>.V<><56>G<EE><47><C0>iV$:ͭ<>m5<6D><35><B0><A3><E6> <1E><>f<D9>S'mm<6D><6D> "<13><><EC>!<21>F{p7x<37>9<CD>{<7B>jf<6A><66>Bl<19><><B5><B8>2<9F>k<9B>3<CA><1E><>)<29>.<00>΍q<CE8D>Iԑ|<7C>\O<><4F><92>@<40>I<D9>_<03>q <0B>xH\<5C><><A7>( 2<>*4<><34>$$ <0C><><DE>4_O<5F>GJ<47><4A><E0>f<EF><66>*6<>?ipf(<28>l[`\rs<72><73><C5> <0B><>!<21><>܉l<DC89><6C><BF>{1<><1E>`<60>,<2C>)<29><>_ϒ<04>*f<> l(<19><><E0> ^<5E>}<7D><><E1><FB>%"<22><>n<AA>M<E7>O2<4F>'<27>U<B0><55>){<7B>9<B3><39><B0>N[<5B>לM<D79C>ɟ<AE><C99F><B4>IR`<60><>1<E4><31><F0><0E>T&<26>+<2B>:<3A><><A5><FF>o<C1><6F><FF> <05><>E <0A><01>o<F2><00><>0<>2<D7>'!;<3B>%<25><><17><>t& <0A><>ZL<5A><4C>R_i<19>2<CD>#n/K<><4B><97>"X<><58>K/^<5E><>(h<><68>~+<2B><>,q<><71> <09>kk<6B>r<CE><72>$<24><>W<CB><57>׆%ѶP<D1B6><50><BE>6<96>A]Y<><59>\<15>,<2C>=<3D>o<AA>/<2F><><90><11><>A<>B\<5C>/*<2A>d$)'<27><><AD><A1>Q<>~ <20>9<14>6<F2>F<D7><46>t<C5>ܙPT<50>
Ĺ2<90><15>{Ј%y<><79><F2>GV<47>P-<2D>m<C7> i<><69>ޚ<EC>SieDـ<>h#5<>y<EB>V<D6><56><89><12><>r<F6>*/
iE脩<45><E884A9>&<26>A<85><41><D3>v<AD><76>%<NT<18>@Vr<56>i<A9><69><ED>YU<59>p+AH{<7B><><05><_<><5F><1D>t#ziX<69>#r<><72>R<F5>ɣM<C9A3><4D>
<D5>8th<80><10>aZ<61><5A><CA>A>a<>%˂<><CB82><BE>*w<><77> `<60>‹<02>B<F5>=<3D>U<F3>f{<7B>(<28>I<85>Nq_ zh.3fKH<4B><08> f]<5D>N<A7><4E> <4C><58><10>=<3D>zR<7A>g}퇍<00>Z<14>U<E9><55><10>J<9F>"y<>x<88>q<C1>E<8A>SZD<5A><44>X<C3><58><B4><E5><FA>J<A6>N4<4E>H<17>O<D6>V_<>X/<2F>b<F3><62><F1><E3><D2>YmOt)<29><>r<>!)<29><><CC>mFL.<2E>P@<40>0<90>c<AA><63><E0>grT<72><54>xg<78><67><00>=<3D><>]
<B0>3A?)z<> Ua<55>0<B5>@<40> z<><7A>d0<><02>w"<22>jZpL_<4C>T_C<5F><43> e )~<7E>o<00><><0F>Q<13>R<A2><52>N<D3><10><>x3Î<33><C38E><A7>|<7C>T"b, <20><>2&
<DF>cT<9A>6<B2><F9>@1# <20>,@<40>-<14><><8A><0F>#<23><><BC><8D>z<E7>|<7C>VcX<63><58><9C><93>k5<10>8<9E>W<13><><15>YP!<21><><84><9E><13><><06>\-<2D>`<60><><14> <03>|<7C>)<SN<53><05><><06>d8,<11>N <0B>)<29><>K<B2>,<2C>^n<>Ht<48><74><0F>N4<4E>E$ <09><><F1<46><1B><>~<7E><>\<5C><>Y/<2F>Uqb<71><1E>:I$p<>dI{*p<><70><AD>6r<1A><>*<><7F><AE><98><07>?<3F><>1<80>}Ć:<3A>̒P<> <0B>o䇍<6F><0F><>o$6_<1A>
"<22><><92><E1>"F<>"<22><03><><AD>z<D2> <20>AA<41><41>,DX<><58> <09>7<A4>+T<>1<B9>%+<2B>1<94><17><>R<E2><52>+#<23><15><>2iQ<69><51>
<FA>p<F0>L<FB>Y<BD><B4><95><F2>r<><72><AF>aH<61> <20>;M,<18> <09><><A0><1D>dM[<5B><98>XZ<58><5A><33>~<7E>3)o<><6F> $Ii<49><69> <0B>h<AA><68>L<05><><FB>p&<07>>2oo<6F><17><><AE>D<00>4}<7D>ئ<84><D8A6>=Lg}<7D><><98><87><9A><F7><E3>Pi<50>9І<0E>.<2E><13><>x<8D><15><><D7>pT<>sq<73><1A><><F5><FA><D5>2<D6><32>yǿa-GuN<75><4E>hXH<58>8u<38><75>O<13><>i%<25> (Ck<43>%<25><03><>b9<62><39><CF><EE>|<7C><>B<EC><42>(#<23><>U<BD> <20>Yt=<15><>'`҃ <20><><81>><3E><>N<BB>-<2D><>'<27>׿ <0B> ]<5D>69A<39>0&!Ge!<21> mܥ#<*L<>£U.<2E><>1<81><31>=RI<0F><>2'<27>)<W1O<31><4F><<3C><>mt;<3B>ߛ<C7><DF9B>ȸ<CC> I
<B5>T<AA>Vmd{ԣ<><D4A3>Z9.<2E><><D8><F5><8A>y]<5D><>(<28><><A1>P<A6>1<DB>><3E>`<60>><3E><>
l<EE><F5><A9>٦hh%<00><><98>H<E2>^Y<>Y-aA<61><41> <0B>x<F8><78><8B>q<9D><71><16>[<5B> '<27>@L^ q=B<>Q<02><>Gͱ2<CDB1><32><95><D0><EF>\<18><08>K<99><4B> <0B>o<F5><17>D<9F>9x<39>x۳I <0A><>8, <0C>O<D0><4F>ȉ<BA>C<B9><43>;<3B>'<27><0F><0E><>2o<32><11>u<C1>P<E9>p <0B><>CR<><52><D4><CC><D4>
<15><><C9> <06><>{<7B>|<7C><>p<>`<60>4<1D><>t<9A>v<><76><83>X<96><58> @X<>+<2B><><8A><8E><AC>6zP?,<2C><><E3>J<9C><4A><FA>*<2A><>lKh:<1C>MѰ<><14>dC<64>^<5E>fh<0F><>D<B7> <0C><><90>]w<>J<><01><07><><B4>ү<><D2AF><83>!<21><><90>}7?fY<05>ƉA<C689><41><BA>"S<>E<FB><45><8D><EE><15>i<B4><69><E8>D2#ե<>$=<3D><><B9><03><><1C><>4<E4>:{<7B>pۿs<DBBF><73><9A><15>><3E>
<CE><1A><00>irr<72><54> ;<3B> <00>q<15>!<21>u_<0F><><F0>n&5ҁW<D281>%<25><>7
<17><13><>_<07> c<>5<C4><D1><7F><E2><F0>9<F7>f5<><35>r<A3>~J<07><>D<B0>R<A5>5<06><14><><15>e<BF><65>?[<5B>T6<54><36><8D><9F>mf8O<38>r<AA><72><9E>*<2A>~$Qc<><63><1C>ڏƁ;B<><42><BF>=<3D>E_<45>M<9D><4D><8A><10>hhR<68>` >~<7E><@34<33>TG<54><47><90>a<>8<EC><38><14>vf<><66><D4>&<26>G[<5B><>U<AE><55>%H<14>-XP@ <20> K<><02>/<2F>қ<D3><D29B>@^0<><30>ݩ<1A>'<27><>f<1D>܍kl<><6C>ش<CA>\<5C><>B<8E><42><E7>G]<5D><>W?s<><73><B4>X<>(V<01><18>z<><7A>$F<>;<3B><>]<5D>HP<48>{*6<>D<CB>cb-7|<7C>X<8A>|<7C>o~m<><6D><8A><8D><F4><D0>s<BC><73>siB<69><03>J[0{V<><56><B5> <0B><>\=T%<25><07>CJ͵m9<<1E>?<3F>fK<66>]<04>ɒCy<43><79><89>{<><7F><18> P<05><><FC><88><B1>Ə뇰G<EB87B0>^JH<18><>@
\쓚c<EC939A>~R<><62>@mh<><68>VS<56><53>#4<><02>xSk<53>ȗ<D0><C897>~<7E>y<94>*<2A><>q<83>6<1F><>&g<><67>Y<97><13>?<3F><> g<><67>b<8B> Xn<1C>!<21>$<24>8[<5B>E'(<28>)<29><10><>C7"<22>ONh<4E>C3<1B>V<>,<2C><>%<25><><E2><C7>(eR39I<0F><>H<86>_YDb<44>;s~<7E>L<93><4C>\<5C><>ed<11>5<EA> i<12><>3<CE><33><FE><83><C0><94>s<A5><73><A7>ђ9I<39><49>t<92><03>r<1C><><D2>ô<CF><C3B4><8B>ikX<06><><18><>J<AE><4A>B<C1><42>5F<35><46>޾<93>U<81><06><13>u\<5C>-<2D><>*/Usw<73><77><D7>
<04><><A5>b OĿ<4F>m<A5>O<19><><D9><E9><FF>n<V<><56><F8><FD> l<>~<7E><>=<3D><>#<1E><00>0~<7E><>=<3D>&<26><><95><B2>'<14>_<80><1A><05><><88>ec<65><63>yO<79>4wc<>2<82>-Y<><59>o<F2>,<2C><><D7>#<23><><B3>w<88><77><85><A9>ã<C5><1C> <0C><>ŀq#֤<>;+U3<55><33>ř<0F><><B3><93><85>vE<76>
Ѱ<B4>~<10>i<><69>l_<18> b<00><>L-<2D>1<96> Q\<5C>E=$P<><50><F3>R<AD><52>H<CF><48>DO<44><0F><>p<>X<10>ԣ<F2>F<><46>ܲS<DCB2><53>h<E7>sS<73>I$<07><>E!<21>T<CD><13><> e <0A>|<02>X<><58><A0><8C><01><><E4><E9><F0><01>L&qT <20>q<D4>!c`gp$=c<>@3<>%<08>K<9D>5<07>!<21><><96>%<25><><0F>#<23>fS<66>N<CB> 8<>yY )<29><><9C>I<93><49><C4>њX<1E>p (<28>|HA<07><><FB>+<2B>zN"/<2F>3O3Z<33><5A>^
X_<CC>5
o<8A><96>I<E0><A6>_ȯ<>%<25><>pףc0?<3F><><A4><82><D7><DC><F2><04>7n<37><6E><E5><FA>:8<>
y]K<>8<A7>a<C0>h<D0>v<87><76><F4>$.><3E><>,1G<31>G[ՁxeX<65><58><8E>uj<75><6A>z z<>ҳݘ-6<>`<60>9<A6>e<11><><84><8D><B9>$<04><>v<01>:<3A><>]]@<40><12><>/ yB(z<><7A>Î
<F4><ED><06><>/ oZ<6F>m'N;=3<>%)y<><79> <0C>19<31><39>F<F0>L(<1E><>g<9D>R<D4>K@ ; <20>\'<27>'<27>]<5D>̱<>2i<11>e<AC>vu<76><75># q<><1C><>Z<17>~<7E>1<81><31><E0>5I]9,<2C><><B6><B0> 7J<>i)<29>H)j<11><>-j<><6A>u<96><75>՘ <09>O<EB>O<05><><F5><BE>/<2F> p<><70>:<3A><>/<2F><19><>(<28>;<3B>RBU<42>7<9A>e<9D>d<99>I<C2><49>N<D4><4E>RH<52>?>X0y8P<><50>r#<23>b _<><5F><13>8i؍Cf`ȑ<>ai<61>2U<32>y<BA>d=<3D><14>2<C3>_<15>Db<44>9<85><39>@<40><>:q<><71>"ڌSp<53>F<85>~<7E><><AB>"6TDg<44>tӆ<>
<B4><B8>+t<><74><87><F2><1A>Hh7 ><3E>T<D2><54><09>$<24>A<FD>Q+<2B> <20>@;;<14><><A2>M<F7><15><><07>~o<><0E>S<:.<2E>g<A5><67>&<26><>`$<24>"C<>PbQ,`<60>$<24>`<60><><99><><03><>W<B7>18<31><38><<1A><19>~<7E>$<24><>+<2B>t<F2>
<83>>N<19><><F8>]-m<><6D><00><>e <09>B5<42><35>P<C9><50><FC><BF><C7>Ncx<63>q<D1>E}n<> <0B><><9B><FD><F1>B68<36><38>5 <09><>}<7D><>Uf<55><<3C>)<0E>Sb<>Q<E3><51><B0><A6>R<><52><A2>Uk<55>)LGS*<2A><>F:<3A>Hp<48>%xسR<D8B3>)<29><><DD>s<><73><A8><>Rq<52><71>Wj<57><6A>G<D0><47><93><E9><E3>i<FD><69><D5><<3C>5)<29>
/򈈳2`<60>޲<><DEB2><16><><E6><14>h<EC><68><91><08>6<BF>`눯L<EB88AF>T <15><><08><><F5>ɖ<C5>n <18>Q<00><>Y<D0>\<5C><02>;uth<74><68>2<12>6WZa<5A>fQ<0F><><A5>r`<60>1t<12><>-<2D>1<81><31><8E>a<><61><16><><D2B0><18> g0<67><30>C<DB><43><FC><C6>i<0E>[[<5B><>^;<3B>`FOpb^ū<><05>^n<><6E><CC><C3>P mJSr4K*X<><58>˓ .c<1A>n<F6>nm<12><>E<E2><15><>P<F1><50><0F><><FC>h<02><>J<9A><4A><AD>l<FC>|<7C><><03><>c<98><63>! !<21>Z<E1><02><>I>Nb<4E><62>T<BA><54>p<A1><19><>P<08><>u$k[C<>%<25>- <19><>QL<0F><><16>&<11><><03><><F4>B88<38><38>J<F6>t<14><><A8><E7>q<A6>i<><18><>c<16>2H<32>šE/'W<>^<5E>y<9F><79><F1>Rrnզ*p<>aK<61>#51<1A>=<3D>̺6<CCBA> <0B>j<F5>C<91><43>#<07><<3C> /I͑2 ;ċ `SX<53><58>ԙ<><D499><94>$j<><6A><0F><>j<02>g<DB>I\d<><64><AF>O<A5><4F><1A><><18><><g<><67>HEƪ<>(1HHx<48><78>u1<75><31> <0C>-<1B><><DB>!<21><>1<04>L<B4>/<J<><4A>/<2F><><C4><C4>?<3F><>p{@<40>e<D4>h<88><68>CnVrc<> <0C><0F>S<>`<60>_O>X<><58><B0>%<25><>=<3D>gr<00>j<BD><6A><9E>{yV<79><56><A8> <0C>P<BE>sJIf<49>M<0F>!<21><a<><61>~4v,<2C><06><>}h<><68><BF>
L<EB><C2>D(<28>xR<16>E<BD>l<E8><6C>Ʊ儡F<E584A1><46><84><E8><B0><D6>R#L<><4C><80><DD><E4>5<DA><35>D<F5>ߙZcS<63>_K<5F><17><>q
<BD><A2><94><F0><D1><04>h<><62>v~<7E><><E1><07><><AE>G<A3>T<E2>iT<><54><07><>1-HL.=<3D><16>@<40><>s<FC>)<29>2<10><>B<>5<D2><35>'<27><18>!<03><12><><D2><FA><B8>L<C8><4C><94><D6>}<7D><>X&<26><>9<><39><90><89> <09><>J<0F><>iO<69><4F>#<23>o<10>B<91><42><B8>y:<00>d<E5>!$A<> <09><>[u<>E{D<>PcgC<>{L<>_E<<01><>q<19>u<9D><75>}<7D><>Fſ<46><C5BF>v<98><76><96><C7>R*eU<65><55>Y[l]<5D><>jH<6A>*ow<><77>a$<24>D-<2D><15><><94>-
<87>S<8D><DE><F9>cǀI p<><70><B5>(r$[<5B><15><>LS<4C>q1<71>l<C3>l nP<03>Ԙ<EE>p3<70> 9t]t<>:;<1B>4 <09> <0A>J<84><4A><95><C1>\zֿ-#<23>ɇ]<08>8Y<1B>=<3D>)<29><>Đg<><67>3"
5x<19>/<2F>+/<16>\
?8Q<38>9<A4>1-<02>ެ<<3C>Z<CA>mF~<7E><><02><06>.<05>Ьh<D0AC>46<34><1C><02>JG<4A><47><AA>>]I<>N<88>F<05><><A8>n <0A>1D<31>a<93>6-4<><34>KX<>8)<29><04><><16>>8<> <12><>)<29>q<90>@<40><><15><><1B><><E7>PȒR<C892>2<97>G<B8><15><>I8C@<40><>hW <09><>T<D2>Q];K<E<><45>v<92><76><1E><15><>rž#<23>N<98>*<2A><>ٵeR<65> :<3A>@<40><><CE>8<B2><38><A2>]1:<3A><03>85G<35>"<22><>~<7E><>U8_<38>4#<23><><B4><B8><F7>j<A1>j<8E><6A>q<D5>A% ,<2C>}!¦8<C2A6>?,5'\2<>a<D2>S<F1><1C>MdK)<15><>\\<5C>2.<2E><>:G<><47><02><><91>A<D0><41>a<A8>tI<74>#<23><00>E<D1>|<7C><07>И+<2B>h\<5C><><FE>1Q<31><51><86><E1><02><><<3C>D|vL<1B><>%n۟<6E><DB9F><B4><90>L<>Z"<22>R_ D <20>0<E28493>sC@<1D><>_<B5>7<01>y<CD><79>P:<3A>Yd<59>%<25><>Lj%E<><45><E2><E9><<3C>[s<><1A><>RN<52><4E>94<39><1C><><16><06><><C4> <0A> <20>/<2F>co<[)<29><>$<24>*<2A>~<7E><><A3><AA>JQj<51>"Ɯ&><3E><>=_<>1a<><10><><C0><BE><C5><F0><95><> <09><>ȱ@<40><>x<CE>Z<7F><5A><E7> u<>rd<>`_1<1A>T<B1>*<1F>K<86>b<EA><62><03><>{
<96>p-n<><6E>+<2B><><EA>W9?<3F><><1A><>.<2E>W*m<>*n<1F><><84>Ԥ'<27><1B><>.CA<06><>Cd<43><64>ýD<C3BD>C1<>n*<2A>k]F<> <13> ܴOl7i<37><19>%<25>cXkԺ%i(<28>ε<AF>=<3D>r$Dy<44>U6<>ʉ<F2>;<3B>c<D1>a<86><11> k|<7C>Gr:<15><>9<9E>mm<6D><6D>W<D2><57><9A><><C39E>X<D9><58>e<C6><05>UA<55><41>D<8E>Q<9E>_«<04>t<E8><74>j<FD><6A>$Uh<55><68><BD><A2><91><94>4<9B><12>a<E8><61><F1>| <>a <0A>eB<65><10><><84><BE><F3><EA> <20>CUMҵ<4D>h<F1>ރ8<><38><97>w<AD>Ƥii<69><69>p<><70>`<1D><><05>g<04><>6ρ<36>#<16>M<74>?<<3C>8W<05><><80><DC>^<5E>%xpf1<12>Sq iX<08>Y<A5>Z<C8>KT6 /5Qt<51><74><87>Φ<9A><CEA6>hEzp)H<>J<E7><4A><E8>XC<19> <0C>ΐR[S} q<16>T/<2F>E<F9><45>:E,<2C>2P<08>!<21>Z<E4>N<D3>Ă<80>T<96><13><>s<><73>=4<>阃RN<52><4E><9D><F0><C1>S<C8><53>w<04><>y#d<><64>8G6<`<60> 3<><07>YˤM<00><>=9fts4<73> q<><71>9<CE>x<A0><78><EC><30>aE<61>g<D0>E7<45><37><88> [<5B><>3<01><>n(<28>)* <20>l<9C><<3C><><96>`<60>T<02>&v<08><>}<7D><><12><>Ou<4F><75>(<28><>! `<60>4<14>HA<04>XO<58><4F><C1><FE>е<><D0B5><0E>>!<21> <09>+<2B>҆<90>5!<21>
<B4>0`<60>!WB4<0F><><00>`1@<0E> <00>X<16><><05>@<40>( <20>8 <09>L@M@<03><>9z<39><7A>Ok<4F>U<BF><55><F0><AF>;<<3C>?<3F>^<5E><>LJ<F1><C787>ï<03><><9C><1E><><F3><F2><DD><03>r<><72><E3><81>s_<73><5F>J<FC><4A>B<D7><<3C><>΍I<CE8D>͵}<7D><>s<E8><1D><>4y<34>WMmQjݯ6<DDAF><19><><AE>%<25>Ì<>Ό<02>Ј<7F><D088>c<FD><63>F<B9>(6n<36><6E>]:<3A><01>?w<> r4'}p$<24><><A6>j.<2E>cb%<25><17> ,<2C><><B7><B6><FC>[P!C<>δ<87>LD<4C>$<24>W<A8><57>rbG|TX!<21>bFT#<23>VL.4<83>Cp <$<24>*Y<>& <20>"<22>Ę<A5>Ј<AA>T<AA><54><80><A9><A4>@<40><>H<AA>S<D1><53><B1>"<22>JE<4A><45>#*F Tl8<6C><38>aQ ¡` <><C2A0><C0>az<><7A><C1><8A><15>+fV<><56>Zo<5A>f<C5><15>x*<2A><>U<EC>ت<8F><D8AA>T<B1>B<E7><42>EJ|
<92>7<19>*%<25>T<D4><54><89><A8>Q6<02><>EA<45><41><B6><8A><15><>W<B0><57><B2>պ<><D5BA>ʪ<A8>z<A2><7A>j<87><12><><06><>4}<7D><><E3>L<EE>nf<6E>:<3A><><97>?<3F>x괢<78><EAB4A2><AA><B6>><1A>Xj<58>!<21>I<AA><49><82>
<AC>X*<2A>^<5E><>v<9E><76>ڥWj<57><6A><92>:v<><76>ڡ<A5>j<E7>ܪ<83>n<EC>5<AB><35><BA><AB><86>Z<A6>gj<67>Y<A9><59><9A>j<B6><6A> <0B>V-><3E>"^<5E><16><><A1>ĵ<D6>+J<>!:<3A><><T4<54><34><BB>Ek<45><0F>T"<22>P<1A>|֫Ե\<5C>*<2A>)TAJ<41>
U N<>Ju@Ҫ<04>_hU<68><55>_<07><>uX<75>j<93>U<>گUr2<72>I<AB>XK<58><4B>]URꨗT ]PAu~
<AB><CE>U\<5C><>ݕVЪ<56><D0AA><B5><A4>'<27>Yj<08>$G<><47><D8><FE><C28F><E8>#<23>o<1F>`<60>X<D5><58>X5ZQ<5A>ɋV,Z<><02>{<16>е]<05><>%V1*<2A><04>*<12>`J<>q*<2A><>W<89>:<3A><><B9><C1><0E><>uk<75><6B><83>^<5E><><90><AA>W<1A><>կ<06>5g<01> Xpj<70><6A><8C>+<2B>P<FD>ꄿT<05><><FA><BE><9F><AB><C1><1F>o<FB><6F><F1>l<D5><6C><92><12><><E0>p<C4><70><BE><FD>+<2B>M* 2$<24>;<3B>p<82><70>@&<26><>8<AC>A2$J "0$N`<17>-3<><33><16>a<8A><61><85><DD>p8̂<38><CC82><A1>Y<><59><FA><82><A2>#U<10>@X'`<10>l<B0><6C>P)<29><><FB><A5>o‘<6F><C291><FC><F9>n<BB>+<00>l<B8>x<F1>ЇP;<3B>Xxtm?49 @<40>R;<3B>S<F0>p<9B><70><E8><8E>x<><78>B<EA>kq’<71>L<AF>^s;<3B>$<<3C><><E6>7<CB>1^ӷ%<25><><16><><8F>'U7<55>ZH<5A><48><06>b<><62><BB><AC><18><>̚<F5><13>-`mu<6D> ǯȜ<C7AF>}<7D><><85><CB>F,
<0E><><8E>\<5C>W<06><>G<D7>GveFoB^qez<13><><F1>.<2E>J<16><>-?7<><37><F8>g<>.<2E>g<F4>2<D1><32><E1>3V<1B><><E3>.<2E><><87><1A><><84> L<>گ<AE><DAAF>J<98><4A>*<00><><CA><F1><03>K<><15>JAD !<21>$<<3C><>b<16>ft<66><74>!<21>ϔ&<26><> <0A><><1D>%^<03>> ʯ<00> <09><00>dId<49><64><87>r<>RZZ<5A>$=<3D> <09>b<E8>t<8F><74><D2>Ȩ<C5>΋\rCA<43>t_X<5F><07>'.<2E>z<>bf0^<5E>f<FB><0E><> <04><><10>D V<><56>7<>6<82>7f/<2F>>/<2F>I<><49><1B>W+<2B> A<><1A> '6<>N<>‚<DAB9>g"<22> <1C> t<><74>T<EA><54>ҹDL<1A><><EA>d@C[1<><31><C9>M<CE>.y<><79>X<9E>-'G<><47><<3C>c<AD><63><F4>G<D8>ʶ<EC>٠a<D9A0><61>e+<2B><><BA><80><BF><82><03><>GGN{^lY<6C><59><B3>35;!kv0<03><>j=<3D><><D3>f<98><66><B1>B<F0><42><E6>w<EF>f$<24><><EE>AM<41>B=>L<>B_<42>|־E<15><>g\<5C><4D>M<FC><4D><F9>!P<>S<D7><04><>=*<2A>y<F7><55><<3C>f<FA><66>)<29><>kuTf
W,<2C>PG<50><47>y<94>fS<66>Օ?wYV<59><56>k^<14>ݚ<E6><DD9A>j<86><1E><><1B><><D2><E1>k<AE>x<A5><78><08><><B7><88><FC>A<BC><41><8A>=<3D>pT<70><54><8D>R{(<28><><CC>&<26>{A<7F><41><10><>K<84><4B><9A>n<C7><6E><9B><C1><AF> <20><>Ѣ<07>LDz30<33><30><A0>X<B9><E8><7F>G<DF><47><C1>|<7C><>M<B3>c<><63><F2><F9>L<01>_K<> <0A>VMe2j<32><6A>$<05>n$$y<1C>=<12>F<99><46> <09>?<3F> !e!<21>t<95>t(<28><>@<0F>C[Ra<13>l<A3><6C>n<A1><6E><9E>O\؁ <0B>BxnЙK<D099>h<DC><68><85>:<3A><><A4><C1>0I<30><49>b<84>=<3D><><D9><E4><D4><CC>gt1cr&<26>B<94> <0A><><83><AB><AA><DD>tUX<><06>UW<55>xKk<>zc<7A><63>[ <09>Bi<42><69>f<>Bʟa<CA9F><61>4<FD><34><90><F1><E9><C9><D0>ҹ<1D><>HF<48><46><E3><D2><FE>7F<37><46><80><02><0E>2@<40><>W<1E>HұWX<> <14>޸<EA>P<BC><50>͵z<CDB5> <18>Q<85>P<>$p+A)+<2B>K>\<5C> <0A>;<02>9B<39>G<E2>Dx<44>j<95>*<2A><1F><><96><65><CB99><C2><13>N-<2D>b<C8> <0A>^<5E>I<80><49><90><0F><><EA>gW`<60><><C0><AE><93>)<29>N
\<5C>$<24>x+<2B>.<16><><A5>0ћ<><D19B><A4>2<AB><32>Q[<5B>S<CC>C<19>[gX %<25><><8C>|<7C>;›dDs<08><><90>j<AD>|[!<21>8d <0C><> <0C><>&<26><>y~<7E>:<3A><<3C><><F0><CE>9<C4><08>\H<><48><00>@0w<30>AT)C|%33<33>H>0r<30><72>=<3D>161<36>P.*<2A>y<BF><79><8D>4[Ŧk<C5A6><6B>D<BF>4><3E><30><D898>B<F9>l<91><07>ab <0A><>"8><3E>O<DA><05><>'<27>'FdA<64><41>7<AD>b<C5><62><C1>mInv><3E><1D><><C3><E4>)F<>ZS2y<>b<91><62>2j/3<>(<28><><F9><E6>7<D1>FĬ$G<>52 <09>f<BC><0E>(<28><>Ύ9<1A>4<90>I<CA>%*2<><05>"v<>X-B<06>xp:<3A><>kԝ<6B><D49D><F2><99>\<5C><><17> <20><>%<25>(<28><><11><>"@x<>/g<>F <09><><BB><14>T<8E><54>3
<F1><B3><A4>)<29>|;oX<6F><58>9R(o<><6F>g<E1><1A>P<9C><50>Q*:<3A><AC><EE99A0>p<A9><70>JfuvXص<17>!<21>Rz<52><02><>Q#A<><41>C<99>q<95>i<89><69>!P<>aY<61>2]b3<62><33><9D>E<y ؕBP<42>3&Q<>6Fꓵ<46><EA93B5>B':q<><71>b8*^`<60>J<9A> <0C><>bZ+<00>E4ґ<><D291>ޏnə4<C999>`<60><>{<7B><>V" $<24><>4<BD><34>°N"<22>AP<41><50>O*D<>5VͰ<56><CDB0><88>ɩ<88>
<98>><3E><><17><>6<EA>P<07>Hu~<7E><><81>sFxR<78><52><81><C8><F4><F7><04>$<24>H<DC>T<><54><B6><1C>`w,<2C>^[4<>:)6l~s<><73>9_<16><>2<84><32><BF><A4>!<21><><8C>.<2E><><AF><A8> g ?i)eh<65>|<7C>Ga #<23>i<8B>ejD<6A><44><F1>dAo`<60><> 9$<24>S<F7><53>)LE<4C>v<00><1D><>B<93><42><89><B2><FA>,/<01><><B5>e<CF><65>P<B7>a
<CC>窀J<E7AA80><4A><82>I<1C><19>??Qg*<2A>[9<><39>9<C4><39><02><><FF>{ <13><><A2>Ӧ3<D3A6>{<7B>C<83>K<>%:<3A><>G<E0>J<ED><4A><D9><F5>xI|ѳ`<60><>N<04>e<01>L輺<4C>t<9C>r<BD><36>-<2D><18>\<5C><>jp<6A><70><FE><B9>-<2D>Q <20><>¬S<C2AC>l|<7C>ȃ<C0>6<B7><36><9D>2<>ʫ<98><CAAB>y<D6><05>8<A2><00>_$*(<1B>#<23><><80><9D>+[<5B><>6<A3><36> V#<23>i<08>S7<53><37><8C>u><3E>z&<26>Κq<CE9A><71><B6>%]<08>Pр6<D180>`<12> <0C>F<D8><1D>b"2<>'<27>-<2D>H<48><7F><87>Q{
<A8><81><BF><81>/<2F>Wk<57><18>c<EE>$<19><><EB><FA>/sت<>y<>n <0A><><88><8A><C8><FA>[@<40><>7 w<><77> 0<>a<B5><61>V<13>GΙ<47> <20><><B7><83>}<7D>' <09>C)<29><> -<14>x<>U"!9<><39>[<5B>ϳ<14><><EB>P(p<><10><><97><06><05>CZ,*<2A>BFς<>!ns#P<><00><>#Ȣި>|E<05>+<2B><18>Z<EB>Sn<53><6E>dMOH2<48><32><C0><83> L<> <0C><>7<FA>ZCC<43><43>S_#<23>N<AC><4E>K<89>2<08><><9D><DB> <20>D<1A><<3C>sT)Ĩ
xy+<2B>YD<59><44>ի<>K<D4><4B>jzo<7A><6F>Z<91>Q<DD>$<24><>:<3A><><B0><X:de<64>A"<22>c<><1E>&<26><><B8><E4><E6><FF>#<23> <0C>A9F<39>U<>zn<7A>i#|<7C>F $?<3F><>la_<61>X.-<1E>H-<2D><><EF><8B>h<><68>dwqVbG<62>JA<4A>:<3A><>]<5D><>O%<<3C>x<E5>Œ[<5B><><9C><B4><E7>x2<><32><1A><0E>O<D5><4F><B3>Wf<57>h<A5>3<D6><33><92><F8><F6><F5>Hv<48><76>tB<><42>x<E4><78>%
%d"<22><>)i;o<1B><03><>!<21><>`]1<>#E,"<22><><A4><A2><98><07><><AD><82><B0>Yx<59><78><C1><FA>)f<> <0C><><BE>'<27>4R2|<7C><>#*6<><36><84>.i<>TGh<47>Z<05>У<80>×<86>g+vr<76>*<2A>zS<7A><53>=<3D>^f<>5XNv<4E>8
*<2A>8<EF>d3<<15><>8<9C>(m'&<26><> pw<70><15>R<00>
<96>
<BC><00>;<3B>y<><79><04><>a#y<><79><97>H<>rY;f<><08>,<2C><> e<>G<9C>y<E2><14><14>D<83><44><AC>;I<><49><C7><CD>G<98>q*<2A>D<87>FII<49>"HX<01>W<F0><57><84><BD>@<40>#<23>ΞB<CE9E>Z<06>I<EF>)M<06>9<>Rb5G<35>33,<2C>1<A1><31><81>,<06>;<3B><><1C><>z
\פ+@<40>1<BD><31><B8><98><11><>s`K<>*}?t<17><><00>ٚ<C0>7QJ<51><4A><BE><B6><00><><84><B0>-&<26>[T<><54>wzD޵ 7<><10>+i<>
<DE><C1>S+{\=<3D><><ED><E99DBB>p&<26><>|o<>V&<26><>/<2F>ʉ<91>'<0F><>*<2A>ĸ<DC>g<FA>u~B<><42>M<12>B<E4><42>O<F3>y<18>@<40>Gߧ`n<><>
<DF><06><>J s5<73><42><DC9B><F4>87J<37><4A>i@v<><12><><88>}u<>\<5C>&<26><>r<\XX<19><><8D><86><82><86>2׮o<D7AE>'<27><><B1>
7X<E4><E8><8C>v<90>/.Y@~<7E><><B4><1A><>u<88>aK<61>5<C9><35><A4>m<12><>= <20>=<3D><>{<04><><A2><CE><F1><DC><CE><F1>h|/#<M<><4D><96>X<><58><86>Em<45><6D>-1<><31>S&<26><><8E>A<93>G<12>k*<2A><><50><CC85><AC><D0><C7>ϗd<CF97><04>B<B2>Xg7P<37><50><DE>c<D6>X,K7<4B><1B><>'<27><>q<E8>7<A5>l<E5>d<03>%<25>,<2C><>d<B5>P<F4><50><C6>C<A8><43>c!<21>l2<><32>X<CB><58>F*K<><4B><B1><18><37>t<8A><74>#<23>{<7B><><DA>C<99>u <0B><><A5><98><E2>t<E7>BDI4E<34><06><>:<3A>9&<26><>@<40><><A7><E7><FA>g<D1>۴55}<7D>P<>Y
<82>]<5D><10>.<2E><><FC>
w<A2>ˍ<B4> V<>Q<E2><51><A6>IM<>I<E3>Xr^<5E><>A<98><41>B<D4>+ <20><><B1>D<80><44><D4>RJ&^<5E><>@<40><17>Nd<4E><64>0<>3U<33><55>! <12>Z<AC>7<81>J<D8><10>g9<67><39>f<> <20><><99>5<1C>s<F9><73>?<3F>!<><0F><><C9>"X<><58>l1<6C><31><AF>f<D4><18>[V<>]"^<5E><1F>" <0B><>g{<7B>=e<><65>9<95><39><E6>h*Xpd' <20><>"<22><>1<8E><31><AE>!~<7E>3~<7E>@<40>ׇ<C3>/<2F><><ox!V<00>, 'B<>.뚢<04> 2lzp#/C<><43><D0>O<BD><4F>f<18>N<97><4E>^V<><56><08><>u<11><><18><10><>L<EB>f_<66><5F>kSd<53>W>^<5E>H1<48><15><1A><>d)<29><13><>&II]<5D>u<A3>2<DB>0<E6><30>.<2E>PU<1A>V<1A>Y<1D>zs<7A><73>F;<18>&np*Z<><5A><97>8PN`D <0B><>@<10>?#x<02><>"pL<70>B^<5E>{<7B><><A8><1D>Z-<1B>ED]<5D>v<><1D><><A2>(М<d<>՜ %X% Vy<;r\<5C>a<B9><61><BD>D<>Z<BA><5A><BD>*<2A><>@<40><><1D>O<1B><>H<16>7,C<>Hx0<78>oם<><D79D>tJv<4A><76>ġ<D1><C4A1> v,<2C>af<61>x<CF><78>Df,p_YZ4<5A>ue\s<>H<>nu<n}<7D>U<C1><55>tE<>Q<84>l<9C><6C><BC>9<A2>H&N<>R<>`<13>'在<><E59CA8>[<1E><AD><7F><9C><8D>d(<28><>9J<39>p<84>2<FE>`<60>LR<17> +<2B><11>K<C1>fo$<24>X<>ﳉ-n@focދ<63><DE8B>N-<2D>AWK<57>]<5D>,Ȃ]<5D><>e*#<23>d<BA><64>=<3D>3<93><33>Kg/<2F><><89>4-<2D>2<99>P|@G<17><><91>bbL5<4C>`<60><>)<29>߷<AC><DFB7> <0B><>5<F0> iQ<18>G<DE><v6H\<5C>ʢ<1A>K<A2><4B><9F><96>1<1A>&<11>k<E4>'<27><><E1><B5>p<8F>h<DD><68>AF<02><>
t<8F><C6>Q<><04>Ď,<2C>a<D8>Rg*eD<65><44><B7>S{ϛ1<>q<85><0E><>U<1B><><84>i<C8>sQ<73><1A><00><>z<A1>^<5E><>#<23><>)ă<61><03>j<><6A><AD>t242X<16>̙<80><CC99>H<AA>0Ƅ@<03>]<5D>^,[cE<63>p<9C><70>h<<3C><HgJ(=@<40>$r<>.!<0E>zGT<47>@s<><73><B6><11>/F3j{<7B>-<2D>l<EB>@br<62><72><F6><C8><C1><E5>"=<3D><><FF><CA><FD>?<3F>3<92><33>Mk<>'~<7E>ڷ˳<>J<FA><4A><F5>+<2B>$<24>o<AB>j<><6A>s#F<>N<B5><4E><96>; ؠ<>R+<2B><>h#<23>Ob<4F><02><>.<08><><A8>4xT<78><54><EC><E1>ِ <20><><B3><96> <09><>0<FC>w<96>@ -<2D> <09>b<B8>aGe<47>C<><43>D=<02><>{<7B><>&ģz<>Dž<95><03>@Jh~<7E><>#f4<66>v!D<>|Y
D<D9><F4>pKҊ<8E><9E><93><B3><86><EC>e<>[<5B>6^<5E>H&;
{<7B><><B6>B"2<><32>i<B1><<3C>qQ<71>C?<3F>Qg
<87><1E><>ʈ(<28><>"֎ѥ`7^<5E>0,O<><4F><FC><AD>J<E6>n<A0> <0A><><FF>O<CC>
d<FC><FC>|<7C>R<F7><52>٧s<D9A7>k<86><6B><F0><F8><C2><C1> N<>ϕ<D3><CF95>vN<76><4E>
<1E>X<A0><58>}$&<26><><F9>)r`<60>2<BA><1F> <0A><><C1><C8>k<><6B><BD><85><88>ȉ<87><C889>!8r\<5C><>;n <0C>E6ejO/,uq<>4-I<><49><B6><7F> F<>d<9D><11>g<1C>8E
<80><8A>Z<E8>/c<>j<10> cG<63>8<><11><>
<18><><A1>Cb=B<><42>(tD1<44>;<3B>So<53><0E>r><3E>` <20><>1<D2> <20>Cm+KJ<4B>]<5D> <0C>5<CD><35><ED><AB>]<5D><><1A>M<06>i<FD> <0A><>h<D3>0jxy<78>ۛHy<48><79>:<3A>T<C2><54><85>A<11><><E5><E3><DF><EF>uac<61>)y<><79><B4><8E><91>s<EC><73><6F>a<BC>SG)$<24><><D9> ux<16><><F9><B7><F7>" <0C><1C>mTqv<><76><92><B3><CF>N@[U<>j4<1F>3<E8><33>Y
n1i
{N/<2F>Tj5<6A>f<08><><01><>c絋X<E7B58B><58>̽<>99@06<><36><8C><A1>| <0F><>=<3D> R<><52><E2><88><F9> <09><><<3C> v<>lb<19>2<D2>8<E4>o<><6F> <0A><><DF>Q<90><51>@<40>F;D<>:l<><6C><F8><05><>,ecd<63>-<2D><>B<>l<>
<F2><89><FC><CC><F4>m<E5><F1><97><E7><88>X<08>LL=#<23><><B9><85><9E>+<2B>Y<DE>$<24>}<03>n£<>{<7B><><E9><F1>)p<>BS<42> <0B><>4<E5><06><>Jw.d<>D<AB><44>P<D4><50>#<23>|<7C>%<25><>J<0F>p+<2B>T<04><><F8>UY<03><>4<EF>6?<14><><9F>qj,<2C><>s<B9><73><1C>JT`<60>Jb L(7<><37> q<><71>y<A0>K<F9><4B>&M<><4D><B3><B9>~
<E9>]g7<67><37>W<><57><A7><0F><<3C>U<84>y3<>KC m<><6D>'*<2A><> <09><><D0>Q<16>ƌd kF<6B><46><D9>Dv<02><>Jt<4A><11>S<06><1E>0L<30><4C><85>di<64>S<02>B:<3A>Ag<41><67><A3><C7><EF>R<87>XY<58><59>¢<BB>^<5E><><83>@<40>K
S$j<>-<2D>W'<27>9<BF>#Z<>K<B9><4B><A2><BC><CC><D4>I <20>eh6<68>Gt<47><1F>Aq<41>~<7E>3<DE><33>9<11><>/BH!<21><><D3><01>I[ňc<>$q<><71><B7><86><E0>gF<12>d<8D><85><E8A093>uMc<4D><1F><03><>H<E2><48><11>ɴ<E6>0<BB> <0C>T2Fm<46><6D><84><8C><AC><9E><08>`<60>6k{<7B><><F9>:<<3C>n<><6E>k<AF>dD<64><44>d<CD>F<E2> qKMCO<43>dF߅><3E><>E8E<38><45>r<12><>t<DD>y.<2E>G<BC><47>x<><78><A1>B5Cf<43><66><12><><A6>r!<21><>h{<07><>b#<23>zpZ<70>ِzNd<4E>,<2C>gMY<14><><FD><8A><95><95>}<7D>)<29>$<24>O;<3B><><FA>-<1B> <20>yq}fq7<71><37><A1>ֵ HS<48><53><AC><84>1<CD><31>R<99>&<04>~Z<><5A>O(<0F><><0E><>]4<>f<9E>FN<16><><A2>HPg6<>y<B5><79><BA><00><31><17><><96>K<92><4B>*<2A><>R[A<03>1<95><31><12><1C><><93>APȔ<50><18>S<F1><1E>$<24><>, A'<27>bCp<43><70><B4> <09>P<02>4<E6>>Y!Ov<4F>^\s(r<><72>Њ<C2>ۨn<DBA8> p)
pi<70>5<94>U<80><55>Y<81><59>Z<8D>D<CD>tY<74>:<3A>1<1D><><E8>Q<EC><51><AB><15>q7/Rk
<E6>@"B<>?А<><D090><1E><>o<D3><6F>x4 <09>s(J<>(qoc^EcѢ4,<2C><><14>ГmXh<13><1B><06><>(<14>b<17><> <12>i<C9>m<E5>E <0A>e&<26>5C<35><08>1<96><31>y<C2><79>v<99>I Z<>&<26>ye<><65>Q`o<>vY<76><59>IH޸X<DEB8>B<04>{Π 0<>\<5C>#A<>4$<24><><E6><8F>8ЃΨ<D083> <0C><><06><>Zh<>N}hة<68>%P<>}@<40> <0A>
<A5>?<3F>5d<35><64>1<89>9<1C>.PŠjco<63><6F><EC><C0><04>WH<57>W G<><47><91><B0>!N<>4K<00><><0E><><81><E8>)f<>><18>-<2D>t<16>n<EC>Y<F4>4<1C>*<2A><>c<E3>N<A8> <09>a<D8>ևD'<27><1E> &_0<5F>M& ^ژ<>b-<2D>9<C2><39>?e<1D><><B1>n<BD>ב޷ <18><>򂇥E<F28287A5>,<2C>d!<21>E|KOP<4F> <20><>:<3A><>Y<>j٭O{<7B> Cfm!X<><58> w<><77>2\~<7E><><95>h&<26>;ꍝgPҲx<D2B2>z<A1>_<BB>9<99>uDy<44>"<06><><C4>H<CC><48>
ey|ʠ'<27><>[q<>r|#<23><>R<9A>r<8D>_<B2><5F><9A><FC><8A><95><B6><AA>k<>R=y8<14><>X]<5D>8w<38><15><><8E>=Q-<2D><><D3>^f<>6,J<>E<94>C<92>0 G<>/I<00>т0<D182>4<08><>Ā<D8><C480>c9]<00><>"<22><>9ÄP<C384>*<2A><>R#<23>L<88>ɻXz<05><>43<34>8<84>/<17>߹zeF$1<>_<AA><5F>IV<49><56>F<FF>2Q<32>X).<2E>T<98>cfgW<67><57><D2>U<F9><55><01><>v!<21><>!<21><> <0A><>6<ED>B"&<26>Şgt<><74>9<9D> <08>h<9C><68><A3><A0>dEpj-ہʁ+<2B>~<7E>^F<><46>sR%a4<61>/}0<00><><15><><9B> <15>Q'<03>`<60>E<E1><05><><6E>ٕtձ<74><D5B1>W}9 <0A>_<>2PS0<53>Ԟ<9D><02><><10>!%Rp<52>B<FD><05> <09>q <<14>$ <20><15><><13><14>"<22>ъm|<07><>BpZ*d<><64>ğ_~<7E>/<2F><><E0>`
<1F><><E4>%<25>7y<37>+M"<22><><FA><F2><10><>f<8E>fl<66>n<DD><06><0E><>Y<93>l<BD> Sya<>U乒<55>+NP<4E>Z<8F>@<40>_ہ<5F><13><>;<3B><><A8><EA>DT<08><><14>YG:I<><49><95>D"i<> <09><12>+<2B>9<D8><39>IL{Ћ><3E><><81>A<93><01>D<B0>4E<34><45>E<C7>q W<>J<10>e<93>E|<7C>9<A4>6p<36><70><BF>X"H<>MI'$<24>|<7C>K'<<3C><>t<AE>N{I7i`<60><><85><J<>o<F8>-<2D> <20> 1"nH<6E><48><E0>=Ca<43>i<F9><69>/ <09>h<83><68>2m<06><07><>šP<C29A>8<90><38>S-'<27><06><>l<BB><6C><FD>p{<7B>v<E1>u<E0>63H<33>:}{rN<72><4E> 2,3/<2F><>}?<00>_x<5F><78><87><16><15>qKx?<3F>ONr##<23><>l@۵`><3E><><AF><CD>Fq<46>B?<3F><>Y<C0>f<89>"%0q?F=<3D><>O*<01><>æ:Cx*<2A><><19><><8C>hXԠ<58><D4A0>~U<><1F><19>Č><3E><><9E>wOFF[<00>@FFTM<01>jU<6A><55>GDEF<01> OS/2<01>C`g<>K<A7>cmaprJ<72> <09>cvt (<03>fpgm$<01>eS<65>/<2F>gasp<04>glyf<04>N <00><3!headR<>46bX<62>hheaS $
2hmtxS<<02><><F4><11>locaTP<01><01>4<B8>VNmaxpU<> <01>nameV<01><><D4AF>postW<>@<08><>F<B9>iprepZ<>..<2E><>+webf[X<>R<AF><00>=<3D><><00> <16><00> .x<>c`d``<60>b `b`<04>[@<40><02>1 <0A> x<>c`fid<69><64><9C><C0><C0><CA><C0><C2>t<C3><74><81>!
B3.a0b<30><01><03><><A5>P<83>p?<06>G <0C><07> <00>I0<49><00><19><>(00 a <09>x<>͑?K<>`<10><>m<EF>H<DA><48>PD<50><44>wZ<><5A>]<5D><>E<C5> <04>:<3A>8 <1D><>ݺv<DDBA>"<22><><0F><><E0>is<><1D><><9C>E<D4><45><84><F8>C]|<7C><><E0><FE><BD><0E>%"<22>2<87>$c=<3D><><99>LZ<4C>MhcHȷ<>
<09>ӭ<14>@<40>r<DA>]<5D><><DE>5U<35>ZRG=<3D>hM<1B>Ԗv<D496><76>C<1D>*<2A><><A8>#4<>BC<>q<8C><71>GJ<47><4A>])q<><12><07>hA}<15>k<AD><6B>%<25><>@G:<3A><>AN<10><>F<>`<60>M<><4D>̓(<28><>R<<3C><><8F><EF><>f<D6>YQ*<2A>.eYW<><57><88><DF>_<95><5F><F8><><C597>.w<><77>-><3E>S><3E>C<0E><><B6>+<2B><>7<D2><37><D6><E4>-6d_<64>)_<>-w<>a<F1>7S<37><53><9F>h<83><00>(<02>x<F8>]Q<>N[A<10> <03><><81> 9<><14><><B3><99>{<7B> <09>Սbd;<3B><>i7r<37><72>q@<40>D گ<19><><A0>H<A4>!H|B>!3k<33><6B>4;;<3B>sΙ3Kʑ<4B>w<AA>k<E9>S<CF>$<24><><90><06>6<CD>NH<4E><48><00><><F7><EB><EB8D8C>Zlf<6C><66>u<CA><75> <06>є;j<00>=o)M;<3B>Z<81><5A><B4><A7><FE>
<86><FB><FC><1F>;<18>4<B4><34><D3>: <09>!<04><>qK<71><4B>ͺ<><0F><><FA><82>b00<30><30><A4><98>.?<3F>R<A6><52>4<B7><6A><CBB0>Ѽ<91>3<11><>4@Skm<04><><9A>!<21><>qK<>˦<90>6<B1><36><98><98>$<13><><C1>tUS<55><53><B5><CC><F8>]<5D><><B2>`<60><07><>Vy &ҷ$<24>, <11>b<F6><62><11>
9<E5><DC><C9><FE><A4>@<40>HƼIJ;ㆵƑ<><C691><D7>6O<36><4F><<3C>Mmo<1D><>Y<1C>w<C1>K:<3A>Ȇ<F8>b;b)<29> DBFU<46><55>Ͻ,<06>R<E4><52>@<40><><94><80><E5><8F><08><><B4>D<<3C><>u1Vz~<7E><><DB>ˊ<F2>V<BB>΋Bwo<77>j<AA><6A>)<29><><><03> <0B>Ac<41><63><C1><9B><CF>J<FE><4A><,<2C>4hCz7z<37><7A><FF><B5>><3E>'ӿ<>Z<01><><78> `<1B><><<3C><>H<CC>[I<><49>dK<64>$K<>)Œe<C592><65><C5><F1><91>w<DC>͝<C8><CD9D>B8<42><15> <20>r<85> <09>B( -),<2C>r<90><72>P<94>n<DA>m<D8>Š<E9><C28A><19>B<D2>,<2C>XZ<58>m!<21><>&<26><><F1><F0><BF>H<CD><48><04><><CA><EE>q$<24>%<25>{<7B>{<7B><><DF>= ˴1 <0C> <0C><>p<C2><70><8C>K<A4><4B> <0C><05>}/[2<1A>m<FE>̱<B0>ɔ8<l<><6C>e<C3><65>,<<3C><13>b"'<27><><C6>,<2C><>?<3F><>k9<6B>f<1B><13>0E<30><45>/<2F><>02<30><32>(LF<4C><46>RU<52>Y<AC><59>3<F8><33><8A>b<90>*<2A><>"dK<01><>L<C9><4C><F1>,<2C>Ă,D<><44>,<2C>ĸ(<28>
E<C2>=<3D><><BF>
<BC><08><><A7>6O:<3A><><A0><8E> <06><><FE>Z<FB>EL<45><4C>0<C2>xs<78><73>ܐ-<13>ҹo<16>̝D<CC9D>e<14>!<21><>*<2A><><E6>g<C2>f <0B>2 <0B>βŌ<CEB2><16><>Y<DC>S<B2>$*<2A><><D6>(<28>"<22><>f<EA><66><F5><E0><F8><96><BA>R<8C> <0A><17>g<F8><02><>Q<85><19><>Zn<5A><6E>O<E2><4F><B5><14>(<28>#<23>U <19>9<A5><18>J0<4A>H<19>Z-KV<4B>Pr!d<>3J<33>B<16><>B<96>,|<7C>JݤSqe<71>tUqfK<66><4B><FD>+<2B>nE<6E>W<E8>Ų<BA>%<25><>ߏT,<2C>z <0B>B<F1><42>З<AF><D097>>9ޛf<DE9B>1+D<><44>Q<A8><51>0<B7><30><0E><><B3>Q0<51>c<C6>4I<15><>^/ޖX|<7C><>6<1A><>-Y<14><>ϙ<F7>!<21>ՃF<D583> <0B><><DE><CD>g<FA><67>Т%<25>g"7=^<5E><>u<BA>F3<><33><F9><E2><E3>x<EE><78> <0B><><05>]<5D><17>}<7D>EW<45>t:<3A><><83>基𪯦<E59FBA><F0AAAFA6><9F><BC>1<C1><31>Q~ {<00><>My<4D><79><12>ϔ <0C><>Q+<2B>-Ƕ"9F<1F>ڿ<1E><><D8><03>ſȟ<C5BF>HL<48>Q<84><51><B8><8C>˜ŗ)<29><>%3'<27>KV<4B><56>Z<0F><><E7><F5>پ<A2>d<&<26>I<f<><66><94><BC>8.[ξ<CEBE>O\<5C><><93>z<EA><7A>/<2F><>YC<59>_q<5F><71><<3C><>x<D8>/<08><1C><>m<90>U<E0><15><>3L<33><4C><05><10><18>
`qt<05>R<0F><><B2><EB>0<F5>]E<<3C>n<A8>н<AE>c<C3><63><8F><B2>6<A9>5<D2>~<7E><><87>Ï><3E>_<E4>_`X<>ȸFH{x<15>z3$<13>d鿟z<E9BF9F>=<3D><><EF>C<DA><43><E7>8[<5B><><9D><F6>~<7E>v<B2>t{<7B><><CA><F1>^<5E><05><>0f&ǔ<><C794><8D>BU<42>`Y2<59><32><10><>̙<B2>s80<><30><AE>M<C3><18>J<D7>+F<><08>)y<05>;<3B>&<26>R{}<7D><>b<F5>M<91><4D>;̗g<CC97><16>I<86>Ia<49><61>ń<E4>D<><44>z<F7><7A><93>A$8f<38>[o_~ ?k<><6B>un<75><6E><F7><ED><CB>rX<72>\<07><EC><7F><FE><92><F6><A0><B4>=s<><73>_]r<><72><F0>B{@><3E><>]f<>r<B1><72><<3C><><96><B1>?<3F>5<><35><E4><8F><DE><E5><85><7F>0M<30>)Lف<18>3<B9>\U<>4<9A>h<C6>(<28><>"UɅ<>A1<41>vH<>{Ǻܭr<DCAD>b<10><><81><F3><99>S<>ܯȢ<DCAF><C8A2>W<EA><57><9A>#<18><><E0><1E> <10><><02>y<F1><79>K`w<><77>k<E5>s%[d<> <0C>ּ<AC>t <09><>&<26>I=x<><78><F5>g_$<24><>~W}<7D><><9F><BC><87><E7>Wv^<5E><1E><> <02>Z<E9>^<5E><><A4><FE><F9><C5><16><><99><F5><FC>&I<>`Fa!O:<3A><>&<26><>{<7B><>0<D9><91>NH<4E><48><F3><C5>^}<7D><><><D3AE><BF><E6>}<7D><><B3>e<BD><65><EF><F0><F0>\;<3B>s<9B>ڲ<CD><DAB2>_8g<38><02>{ՖY<D596><59><FD>tcy͚<79><CD9A>7] <0B><><B4><FA><E8>|<7C>>{ c<03><>zr<7A>(񘉇+, <20>~{<0F><><F9><A5>n<FD>&u<>=<3D><>\ ERg<12><><1E>g<F9><67>|<7C><>><3E><>(v<10>T <0C><>Dr<44><72><A6> O<>u<F8>,<14>T!<21><12><>g<DE><67>,<2C><><FC>}<7D><><F7>ˎsG<73>ʝ<F6><CA9D>Ž?|<7C><>?<3F><><9F><1E><>y<C7><79>%<25>Ho_<6F>"^c\"M<>T<CC>G<FE><47> <20>wR<>/W٪([+<2B><><B9><FB>Gw18<31><38><FF><E8><F7>u<D0><75>8<CA>wd<77><64>gRL'<27><><19>0e9<><39><88><AF>- (<28><><12>)<29><>ҚU<D29A>%<25>SlU<6C>-<2D>83JGNqU<71><55><95><AE><AC>(<28><><E9><9C><>8<7F>Cr<10><><A5>#_<>g<DD><67><B2><B9>rV<72>](<28><><A2><F6><99><ED><A2><84><BB><FE> <0C>W<><57>JKu_k[<5B>4<<3C><>*E<><45>D{w<0F>r<EE>R<05><>
<82>)<29><>߯8<DFAF>RsT]/<2F><><F3><F1>JA<4A><41>Qr<51>s<9C>rt<74><7F><0F><><C4>^<5E>:0~<7E>_<90>x <09>RNǶ֏0<D68F>|<7C><>F'<27>0<D0><30>dF<64><46><1D>ו<03><>d<91><64>2HI<48> <0B>1<BC><31><8B>E<C3>G?<3F><>J-<2D>8<10><><AD>LϖN<CF96>|<03><>$<24>OaL<61><4C>d<B1>L<80>'<27>p>\ <20>B<85><42><19>Ƿ<DF><C7B7>':<3A>m8<6D>^ܰ3<DCB0>‰<F6>0 ='㾜9<E3BE9C><39><8B><B9><94><B9> <0B>jJ<6A><4A><85>E9<45>C<A4><43><A9>EJ<45><4A>l<96>!-Js<4A><73><AE><84>L<EE><4C>/<2F>~k<><6B><B5><B4>,Pg<14>Sr!ә<><D399>ڲ<F9>B<94>@R<>Z<01><><DB>҂<D5><D282><F5>*m<>c<80>o<9B><6F> <0B><>kn<6B>fKwS<77><53>\ <20>l<DA>$<24><><B1><A4><98>}<7D><><92><FF><FF><F6>TA<54><41><82><9D><E0><8D><8C><FE>g<CE>{<7B><><E4>m<1E><><FB><AF><05><><B0><CE>E<E4><18><>y|<7C><>x/<2F><>KrJsU<73><55><99><83><A3><AA>c<8E><63><AA><11>0aD<61><13>hi<68><69>G<F1><47><CF><EB>>8<><38>]<5D>4<A3><<3C><06>=<3D>}Q<><51><1F><><B7><FF>f<0F><><E0>|?<3F>v#<23>ǿ<CD>)(<28>2<<3C><><C4><0F><0E><>0<C0>8<B0>H*D<1E><>Ǿ<>#<23><>z:<3A> [?<3F><>.d.<2E><><E4><E7>@N<>u3<><33>D0<44> IP}<7D> <09><>A<E0>-<2D><1F><13><0F>5<E2>VM<56> R<><52><13>P <0B>9%TU<54><55>rs՜<>$h<<3C>f<A1> E@<40><><BF><D6><F5><06>! +<2B>UU<>%[N$<24><>D<1C><>L<95>f<E0><19><><BE>k<19>0<ED>I<D2>Dv<44><76>w<><00>Cv<1B><0E> Z<><5A><87><02>cc<><63>x<FC>I,{<03><><A4>t<0E>yN<79>Iq)<29><>X=d^<5E><02><><13><11><14><08>{<7B>v_<76><5F><A6>0gO<>j<B3><6A>YEu<45><75><39>C<1F>[=<3D><>Us<55><13>+<0E><><96><B1> <0C><06><><F2>؎k<D88E>W\e<>!<21>"q<><08>Q]<5D><><91>@h<7F><68>~.<2E><><83><05><><D0><E8><A2>P- Ԙ<13><>SW<>y<>e<AA><0F><><DA>B<8E><42>d`<60>ds<00><><A7><9A> <20>6<81>`<60><><F3>T<C9><54> <0A><><8D>Y<A5>M`<60>w<D4><04><96><7F><F6>[<5B><><8F><90>l=<3D>񟝶<FF><F19F9DB6>w_<77>}<1A>uH*<2A><>(<28><02><i~<7E>P<AC><50>t<A6>H<E4><48>J<9A><4A>a<B1><61><F5>o<CF><6F><81>bb_<>`<60>-2<04>R<E4><52><A9>Lc<4C><<3C>8&[.GWF<57>D<>HX<48>L<C1><4C>qVK"<22>6<05><> ǵ<>"#]<18>
A<83><84>Vmhy<68><79><83><02>d<><64>]<5D>.f>s2s6<73>L<83><4C><B0>,<2C>(}@<40><><BD>z <0B><>Wi)<29><16>U@<40> <0C>PC<50><43>K<F6>}N)׏<><D78F><AC>.2`X<>V˗P`<60><><94>>.<2E><><9A>g<8B>ܥΓ<DCA5><CE93>=<3D><08><><10>'dl<><6C><33>D<99>+<2B>
}<7D><><B0>Ͱ<EF> )$SB* <09><><9B><F1>5:I<>6 <0A>J^c,4<><34>:<3A>܊<FC><DC8A>[ <0A>=<3D>d[<5B>)<29>4<93>3<A6><33>M<CF><4D><9F><B6> <0C>/<11>̭<97><1A><><FC>{<7B>Q<9A><BB>2<ED>:<3A>^<5E><05><><EC>Fr<46><72><FE>6<F2>ϞmO{<7B> <0C>H<><48><05><><E1>p?kr'w }<7D><>Ճ_n<5F>Ns<1D><><86>Ȝ<CD><1C><>;<02>ə<19>3d<33><64><D2><C6><E4><B4>m<FA>֟<DB>m<1B>B<C8>)~<7E><11><18><><BC><A0>k<8F><05><0E>Ź<>
<D6><FE><B4><DE>,,<15>L<A9>u<><75>
*&*<15>.8<9E><C9>P<BB><15><><CC>!\uZ]<5D><04>ì҆<C3AC>i9<69>F% <0C><>By<42>L-<2D>Uꁭ<55><EA81AD><EE>[U<><55>ro^<5E>끋z]<5D>g<A8>PD<50>u<><75>"R_I<1A><0F><><A8><16><>^<5E>nz<6E><7A><F4><ED>B<<03><><ED>}<7D>x,N<><4E><87>[VG<56><47>e<BB>}lN<6C>@<40><><18>3M<33><4D>$kq<16><06><>{Y<><59>q<C3>d<><64><BE><F6>v<C1><76><F6><1C>X<>G<C6>k<F7><6B><9B><06><>5<FF> ]L<>L<D9>u<F5>{<7B><>͇PW7Q=<1B>L_2<5F>@<40>:Y<>$^s<><73><BA><B0>-<15> <20><><FE><B1><A7><B0>mۋr<DB8B>]<5D><><8F><02>m<F0>FdbL<19><>N<A5>\<0F><>X- <12>h<02><><89>f<13>I<D5>!"):<3A><>Wd<57>a=<3D><><F6><8C><D5>']~<7E>ա<9B><D5A1><DA><00>87<38><37>2<8E>gx<67>)<29>)<29><><1E><><E0> <0C><>Ϊ<E0>E![<5B><>xY<>q<82><71><F1>S<90> <20>è<B0>J^@p<><70>\$<24>prüG<C3BC><47><B1><E4B583>p̬<><>w<99><77>˔<AD>N<BC><18> Oy𔑈6]<10>[[x<><78><B7>[Zݺ<00><><F6><A0><84>=<3D>M<C4><10><>=<3D><><EA><01>}߇d<DF87><64><1F>O<AA><07><><91><F1>{<7B><>g<B0>O|<7C><><88>T <20>Aj+<2B>=<3D>0/<2F><14>UZ<55><5A><B7>b <16>3CN<>x fda<64>c<94><63><BA><B4>$<24><>9O<39><4F>ɳ?<3F><1E><><F6><;<3B>V<F6>m=o6=<3D>+<2B>@9<><39><BA><05>5<87><0F><><AB><EB>=1e+<2B>S<DE><1B> $;.*˼<><CBBC><80>M<>ہ<F4>*+K<0F><>5<8A><35><83><A4> _<>W <0C> <20><><04><><88>E<ED><45><FE><A4><BE>S}<03>~<7E><><F3>ԏ"<14>x<FD>"<22>3<8C>+<2B><><D8>2f<><66>5H<0F><><18>X<><58><B1><AA>B
<CA>d<B3><AB>$<24>(<28>-<2D><><B8><A4>{<7B><>w<9D>T7h<16>p<95>"<22><><B9> _<><5F><88><8E><A9>5<81><35><97>LP_Q{<7B><>l<D9><6C>K<11><>$G<>=G<><47><CE><DA><F3>7<E1><37><F6>}<7D><>Y<><59><07>S+vUv! '<27><>eէ><3E><>*<2A><><9D><AE>y6<79>l<C8><6C><AC>΢M ,<2C><><8A><98><80><8D><EB>e3b|<7C><1F>ҋ<F9><D28B>EE<45>W<EA>2<><32>b<8F>q"&F<><46>z<A1><7A>Y<F1>k<92><6B>Oēˏ<1C>ub<75>T<AE><54>p<D6>L<A1><4C>}
<88>O<BB>.M<>G\T<>g%oG<02>o3<6F>r<qP<71>,/z<>M5Y<35><59><98><93><17>p-<2D>J@<40>m<D6>:*<2A>,<2C><>V6<56>= <20>Bɥ&`⓷`<60>=<<3C><><12>g<E3>5<E6>{<7B>a<A4><61>`<60><>)ʉ6 o<>p>}SB<53><42>)<29><><84><F2>H <0B><6C><C389>!<21>A<99>'<27><><93><89><>I8'<27><><02><><D399>U <0C><>alŌ8CN<><4E><80>*Y4^ <03><16><><84>{<7B>r<00><>,<2C>$<1F><>"<22><a<>^ D<><02> <0A><>@<40>{<7B>-I:<3A><><99>(<28><><C0> <20><>$<24>:<3A>~4<><34>/<2F><><B9><87><8C><DE><FD>A#b<62><7F><F4>mU 4<><34><AA><93>u<CC><75>f4<1D><><8F><A1><F0>(sSq<a~<7E><>e_<04><>/<73><DC8E>l7<6C>;<3B>.<2E><><98><E69C80>7X-<2D><17>1<AA><31>~^0X-<2D><>D<11><><FE>d6!Z<>,/Q*<1E>x<CC><01><><9D><E8><0E>)<29><>B<12>Ɯ@<40><><91><E9>`N<>c)<29>n<C4><6E>_<CB>[<5B><><DD>ͷ<C5><CDB7>,$<24><>s<F4>v<97>]<5D><><8F>uxvő.M<>I<F8>1<8F><31>u<>=<3D>k<05><>2<98>?<3F>".<2E>ŠDs-<2D>EiגC1<13>"<22><><AF>PwOd<4F><64>c:T<><54><B6><B9>lX<6C>e<AB><65>[<5B>0<A8><30>Õ <0A><><1A><><A9><16>!<12>y<><79><ED><A5><F9>[<5B><>Ys<12> <><7F> <09><><DD><F2><DA><F2><1F>[<5B><>6<EF>kԇ@^<5E>8v-<2D><><9A>
#vF<>l<08><>PR]<5D><>)<00> :@<40>A<05>)<29><><B5><E0>; A:3Ч40n0<6E><1A>I<BC><49>h<DC>9([V<><56><92>[<5B>"rl+h. ũ<>Zd׷TVnٲ<6E>
<CC>^8<><38>a<17><>u]<5D><><81>8<81>˲<98><CBB2>a$<01><><B9><89>x<02><10><>g<AE><67><98>aR$<24>@{<7B><>k<B6>^~a<><61><B1><BD>[Fo<46><6F>T/ҏ<>N<>G<B3> <0C>O&<26>O<87>kik<69><6B>=<19><><C9>r<E9>~<7E><><1E>$<24>|<7C><>A<9C> <0C><>dU<64><55><E9>2<><32><8D> <0C>b1<62>MgU<67>t<E9><74><95>5PU\%UJ<><4A><B3><81><B5>@#<23>5<9B>L<D4>I2<03>Spy<70>r<> <0A>:'<27>9<CA>n<B1> <0C><>0<96><30><91><C6>l<D3><6C>JQsK A<>-<2D><><91>ﰂB<EFB082><42><B7><E3><F7><C4>t<><74>G<9C>x<DE><78><47>L{L6<4C>Ʈ<1F>&<1E><>V<92>u<D2>O/<2F><><BF>7<A7><07><>+<2B> <0B><>+<2B>^%?<3F> <0B>^|o<><6F><D8>x<E5><5F>@gcĨA4DI<01>#2X)0s5<73><35>*;v̯<76>'<27> <20>+<2B><> <0A>j<87><6A>m<C5><6D><A6>d<E5> U<1C>P<87><50>z=QCH<43><48><81><98><AD><FF><F6><81>^8{<7B><><AD><F6><AB>۞<F9><DB9E><FD>}<7D><>yOm<4F><6D>͟<BE><CD9F><CD><FD>f<FE><19>q+<2B><12><><87>FߐG<<0F>6<AC>\>Y[<5B> <09>
<9C>ã<F1>s<80>Db<><62><82>V<><04><>\@ˈhА{(,g
<D7>_-<2D>l<9C>9j$w\<5C>ެ<C7>W<00>'n-\r<><72>U<DD><55><D3>}a<>i<97>T<C4><54>[eS<65>?<3F><>T<11><>g<><67>$3<><33>`<60>-f<><13>qxi<78>0F<30><46>r{<7B>\<5C><19>L9չD3Pʉ<50><CA89>x,<2C>)<29>F8<07>< h<> `/Z-<2D>.D<44>
4ZJ<86>0<FA>F<AB>%<0E><>!<21>;fG<66>&WU<57><55><F2>*<2A><><A5>Ju<><75>ʖ<CC><CA96>ϒ<D4><CF92>;<3B><><CB>Ļ$\<5C>|g<><02><1E><><A8><96><92><8B>UZ<02><1C><><CBAB><E5>y(<28>N<CB><4E><86><8B>`e<>J<F2>@<40>LT} X<><58>ڧc<DAA7><63>k
{<7B>ө<BC><17><><CB><01>لݳ<D984>_<><5F>084k6%~OT<4F><54><8C>ݒ<D1><47> G/<0E>"<22><>`TC<54><43><EA><91><C1><8B> <00><><A2><>$(B<>E<0E><>MF<4D>E<8B>F<D5>,4<>Qxvi<16><B9><E6A387><ED>^<5E><>K<C0>l<A8>el <0A>!<1E>w<C0><77><94><01>%zQ<7A>[E<>md<6D>
<8A><E3><CD>x
h<EE><10>s4?<3F><>><3E>Sד͚<D793>S<F5><53><E6>8<CD><38>jI
e<B3><F4><18>\[i<>P<D0>0<F3>l<A0>eQ<65>E}L+<2B><1A>K<B4><4B><05>k<96><6B><93><E6>WQH<51>\<18><10><><8C><FD>&<26><>4<D6><34><9C>4!<21><)<29><><A0>+ |J<><4A><F0>?q<><71>]<5D><>"<22>
<F7><F6><D1><15>Ž}<7D>_9<5F><39><ED>~N<><4E>M<>t<>O<><Tf`<60>S]<5D>-k0F+<2B><>D<0F>f<>xe_<65><5F>כJ<D79B><16><><EE><01><>~
<AF>
<87><F0> <0A><>W'<27>z6<7A>w<EE>C<AB>p<08><><DF>'`<60><>Z<FC>o<00><>vg9<67><39>\<5C>fk<66><6B>Y<9D><59><8B><F8><D1><FB><EF><87><02><><94><E7>T9<><39>P8u@~<7E><><10>Xk<11><08><>1 $<05><>d-<2D><><F6><A8><02>\<5C><>4<CA><34>J<D7>KU<4B>L0<4C>- z4<13>5<02><10>@<40><> <0B><><A0><BB><15><>r_)<29><><8E><B9><8B><y<><79>X<>H<B0>c<>t<F7>,<2C><><18>@<40>M<EC>:l<>*<2A>E<E4>bH:<3A><>"Թ<>6o8<6F>mX<6D>P?<3F>A<97>9<BB>)'F<><46>,<2C>f<D4>p<B4><70>
EȖ9<CB> <0B><><B2><00><>f<C9>AM<41>oD<6F>\<5C>&+<2B><AE>TL<54><4C><01><><0F>;*y`<60>K<13>L<84>
<C3><04><><08>Q<F1><51><02><00>ܱ7<DCB1>m<F3><6D><EC>3Y<33>E<1D><>ؑ$뱐<><0F>d<9B><64><AD><96><03><>s*<15><><F6>[ɩ<><C9A9><1D><>K<16>Âo<13>BL<42><4C><06><><BE>f#<23><>k<A8><>e`2L<>,"<22>r<D5><72>'#<19>.<2E>*<2A><><A5>^<5E>*%<25>_<D0>LJ<><4A>D ]4<><34>a/<12><>E<A3>D<A8>R<C5><04>ǽ<9A>f<>i<A6><69><8A>ݠ<96>(<28><,<2C><0E>I<D6>t<>y<A1>1<8D><31><D6><EB><C3>*<03><>ۨ<1C>❹ª<E29DB9>J<8E><4A>i<>mhJ<68><4A><C5><D1>h<E8>8<C5>~xx=<01><>U<E0>4<A8><34><99><9A>;aG<61><0E><>) ׌<><16>h<BC>L<F8><4C><AA><EF><E5>> 6q ^<1A><>sJ<73>Zfm(݉ϔZu-4<0F><>L<12>a<18>h><3E>JX<><58>`9<><39><10><>ɓ<EC>ۇ[=<3D><><A7>V<DB>:<3A><>k<E4>6w<36>hTo<C<><43><BD>l<DF>p:ɦr<C9A6><72>__ן<5F><D79F>^72B:<i<><69>{<7B><>{Z<>-(<08>_<E4>+_P<5F><<3C><><87><FE>ϵ<><CFB5><80>a<E8>e<CE>-Y<><59>}:>U<>'<27>Y<A3><59>at<61><74>Cp .VQX<51>0<B6><06><><B4>C"0+<1D>DF<><03><1E><><85>~<7E>C<A5>]<5D><07><><9D>`<60>&G<><47><54>K<1C>0<0F>$<24>B<9E><01>(<28>m<AF>AGe;<65><08><><35>1<A3> <08>۹<DD><DBB9><B1>r<9D> g><3E><>%<17><>}<7D><>k<90><06><><9A><E5>)<29>'<27>
g<14>L<67>e<B4>껗V6<56>><3E><><F5><E6>KWn<57><6E>K<CF>R<EE>{<7B><>#Ah<41>Ā<03><>(<28><>t<04><><B5><E0>!H売<48>s<12><CE><E893A5>+LO[<5B><><1B><06>u6:#0n<>L<B2><4C>/<2F><>p'Oo<4F><10><><8E><F4><9B>v<CD>_{<07><> <0C><>s<D1>_<BA> s`Sn<53><6E><D2>2k<32><6B><F0>c<03><>Q<B7>w<01>[<5B>#<23>TPj.Z<>0[@Q_C<5F>O9<> r<>4<FC><34>_<>kk<6B><6B><93>s<8A>d<01>Z2P<32><>$l<><6C><A2><10>`<60><b.
;0<1A>D<9D><44><94>
"<22><><98><A4>x<B4><78>n<>ב]<5D><>]Y<><59><97><94>*Eus<75><12>f<8B>"<22>}<7D>?~<7E><>ǹsp<73> <0A>$3{<7B><>l<99><6C><B1>V<E5>f)<15>kP<6B><50>o<A3>w<F0><77>C|<7C>`@<40>|<7C>*5Qѵ<00>N ]ˡO<CBA1>dt<>}<7D><>LP<4C>q<D1><71>QF<51>k<02><10>JD<04><1D><>{&$edwԣ<>k<8F><35>q<99>Ӓ+w<>F<19><>u<C7>Ƕ <20><><EA>5<9D><35>|<7C><>x*<2A> <20>r<8C>e<D2><65><E0><D3>$~ ZbG<62><47><D782><EFB886><C0>t<DB>O#<23><>is/<2F>.<2E><>ЈK<D088>c<E5><63>X<>I<C5><49>O8?<11><><D6><F1> íup<75><70><C8><E1><FA><A6>xG<78>oR<6F>2<F7><><D19D>@(<28><>C<19><><A5><B7>z<><7A><10>'<27><>?<3F>~#&<26>F<C5>Wǣ2a<10><><00>^T<>T<DF>><3E>я<DE>K<C7>H<C3><48><C3><EE>?u<><75><BC><FC>u<A3><75>q<ED>ȬO<C8AC>D<D8>L<94><4C>-<2D><><C0><FC>:~Kh~<7E><1C>Cs:͡YM<59> .<2E><><05>,b<>5<BC>1<87>+AL܄:B<><42>2-K<> <0A><><CA><FE>h<E9><68><F5><DC><FC> 9^<5E><><E6><C7><FF><8D> <20>ǿ<E7><C7BF>e<BF><1C><><FE>OA<4F>c<F5><63>f<9F><66><1F><><ED><D6><08>j<9A><6A>`f0<66>`eD<65>=I<><49><B3>@<40><>445<34><35><F3> <18>)J<>`<60>^<5E>MH<4D>8<F8><38><F7>C<>g<0E>s<CE>90<39><30>p[=8><3E>U[ j`<16>Vm<56><6D><FC>o<A3><6F><FD><0E><19><>"5<><35>l<E3>Wfʳ<66>?kqF<71>uH<75>]<5D><>N<E8>)<29>q<>гG<D0B3><47>h<E9><68><E4>ǵ<14><>W*<>?<3F>:<3A><><D5> <0A><><8B>u<1F>½M<C2BD>:<3A>4s<11>Z<1E>b<AA><62><F5><E585B5><D3>| <0C><><A6>u<DB>/<2F>\&<26><><A6><99><81>aߏtuE<75>ܑ.<2E>0<>=<3D><>t <0B><><BC><93><A2><96>5<CB>s({<7B>><3E>a<BB><61><B9>ri<1E><04>s<DF><73><A8>=<3D><><15>@$<24>+<2B>X<92><58><F2><B8><02><>] ]M<><4D>ퟚ87<38>R<>#Fݺ&t<><74>=<3D><><81><80>^w<><77><57>$<24>=<3D><>h<BF><68>e<E6>6wq<77><71><87><DD><C1><A0> <0A><><DE><DF>g$<24><><C3><EA><9B><E4>#<<3C> <0C>v<E8>G<1F><><F2> <0B><17><>!<1D><>{<7B>®倠3֤<05><>$ <20><>GXC<08><><AB><C0><F8><A9><9E>k*&^<5E><><AA><B5>Ty<><79><18>{<7B><><AF>u<E9><75><D7>څ <0B><><FF><B1>;<3B><>+:g<>x<BE><78><FF><85><9B><EE><BF>.<2E><>[q<7F><71>W<B6><57><FF><FB><BE>{d<><1C>t<DB><74>ş<9E>E<DF>܏:<3A>x|Mb<16>G׼Zt<5A><74>]<5D>hD<68><44><95>&<26> b<>€<88><C280><91><BD><03><43><CB89><B1><89><A1>Ger<65>̬~<7E><08>`<60><><BA><8A>78<1F>y <0C><><15>F<C2><46><D4>4[<13><>fSɾ<53><C9BE>A<C4><41>s<9A>W<><57><84><A5><85>-<2D><>X<99><58><B6><ED>/<2F><>M<DE><1C><><A7>|i<><69>5<93>O/<2F>]g~<7E>k_yi<79><69><C3><FC>\}<7D>U<C5><55>{<7B><03><01>x<DE>7<E6><37><B7>(x<>ѷ<B6>m<A8><6D><E1><8E>%<25><><BB><EA>K<F2>g<FC>f&
k<E5>:<3A>Dj8<6A><15>K<>ӢKH _<>Ԇ԰a8F<>Q<D3><51><F1>H b<>P<C2><14>B<1E><><BC>%O<>.H<>6^&(:Ic<49>D<BD><44>̀b<CC80><62><86>(<28>$<24>m<F2>4<08><><C9><E1><F6>;<3B><>}<7D><><87>y<>ru<13><>e<DB>I<97><49><A7><A3><A3>w<D1><77>o<A6><6F>h<91>+o<><6F><A8><FC>w޹0K<1E> <0C><><AE><F9>.[<5B><Ͻ<0F>R3<52>f<16><><E8><98><C1>e<89>TU1k<31>٥<01> <0C><>^E<>"S<><53><8A><05>P+<2B>`<60><1C><><84><B9>/<2F>F<F1><4C>l<14><><E2><E3>k<E4><6B>a.B$3<>b c`o]s<>dd<0F><9F>Y<FE><10><><F9><8C><FA>_0{<7B><>~ <0A>-<2D>k=<3D><07>H4<48><34>1<13>S2<53> <0C><><75><17><8F><01><><E2>7<FE>x<E9><78>k<>q<0F>S<FB><19><> <0B><08>/0<>*
<E3>eD<><44><F7><F9><C0>ƫ<D7>m^'-3<>")<29><>kh<6B><68>>2<19><><B9><B5><><DCA1>G<BC>I.<2E>P<D5>[<5B>:<3A><>C<B4>=<3D>?<3F><>Z~<7E><><B6>$3s<33><73><1B><>Q<F0><11><1B>V<B3><56>=<3D>pY<70><59>D uJ./LB#<23>i><3E> <09><>0Y<><59>ب<C4><D8A8>H<8D>F<B0>I><3E>$f<>g<CC><67>
7<>=<3D> <0A>|O} <0A>+<2B>i<EC><69>e<ED><65><ED><C8>/Ճ/W<>3<A8><33>q<E5><71><16><><07><>E<05>9<AD><39><EA>h <0B>H<F0>d-<2D>A<82>OS<4F>*<2A>zrX<72>э<B5><D18D><A6><1C>O<DD>V<17>rk<>%}YB?<3F>݉Y~z<17><>5S I<><49>2~'<27>F4{`<60><>Ԁ~C<43><7F><FD><A6><84><B9><BD>x<A7>z̅2<><32>œ<17><>og{<7B>7<F1>$<24><1C><><><12>B<E4>.-<2D><><9C>(_V<5F>"w ]/# S<><53><98>69<36><39>r<AD><72><FC>]<5D><><C7><D7>{<17>%<25><><F4>¸+Js6~i.<2E> <0A>C:<3A><>p<D5><70>
C#<23><>7",<2C><>0<E4>;<3B>C~ "<22>*<2A><>)cDc <20>s5<73><35><E6>(4<02><>!<21><>Yy<<06>3<C3><33><AE><B4><A2>w<85><77>s<D7>&'<27><12><0F> <0C><>k|Gauh|<7C><><59>w<CE><77>ݫ<E3><DDAB>N<F1>><13><><EE>A<><41>ۨN<DBA8><4E>uThPT ;O<>ͣd<CDA3><64><82>/{<7B>H] 'N<>h<>-F<><46><E0><C6><7F><9D>b<E8>m<EA>[<5B><>?<3F><0F><>f׍)&a qs}<7D>3~%%Z3 3)Y<><59> ٨><3E>vP"cʋ<63>ұ<F4>|<7C><><84>4Y<34>1<1C>4<FF>4<FF><34><F5><E7><8E>GK<>j<><6A>̇<D4><CC87><80><9E>3<1F><>B<FF>4Y<34>{<7B><><98><9A>9<>Je\<5C>s{<7B><07><>g<AC><1E>=<3D><><F5><80><15><><FA>;<3B><0F><>CN<43><4E>'<27><>b</ <09>r5<72>e<C0><65><D7><E0> <20><04>l<16>g0<67><30><B0><C4>j<B0><6A><96>2x<32>|t
XXxq<1C><><A0>*Ka<4B><61>U<55> <09>QH pG<70> <0B>(<28>`إ)7<> r!UH )A<> ĪWw<57>xu<78>Nx?<3F>c
,m<>3<B5>>&q"L<><06><u<><1C>09<30><39><04>%<25>&C<><43>x<89><78>g<EE>=o
$<24><><B7><A8><EF>ϼ{<7B>O<1D>c:3<>\D!<21><>*<2A>T<17>R<88><52>W<1B>!:<3A><>U%<25><>e<01>a<BE>/<2F><>M<EB>֛<><D69B><B4>̷<DF><18>ØԇQ<D487><51>Jf*<2A>m<97>4*ڽb<DABD>H<C9><48><A6>ˢ<90>|<7C>0<D8><30>x<><78><8D><82>s<97>|<7C>7<BE>a<CD><61><07>q2<71><32><86><AF>;#k`ͼ<><CDBC>p<1E>I68S!?<3F><18>ݱ<DC>xϜ<78><CF9C><9E><A6>s<C9><73>O<B7>W6<57>m<16><><C1><C0><B1><C4><EB>\<5C><>#CI<43>Ҟ]<5D><>-i<><1B><> j<>8<BA>><18><1D>q<A8>Dd7M<37><4D>U1׈w<><77><ED>R<DC><52>}<7D>OE<4F>ň'&<26><0F><>Ȩx<>
<F8>`+p<>1<0E>K<><02><><A6><EC>pZ<10>dʎ@4G<34><47>ʶx7<78>LC<4C>\64<36><34><A3>S- <0B><14>7zPsb_,<2C><><9E><CE>sÞ"<22><>L<> <09>+D,<2C><>ڵ8^>7L
<F9><9C>fe@<40>A)<29>O<9E>T<0E>q8<71>W<DA><57>s<E7> <07>TN<54>^<5E><><E4>W<CF><57>lr<6C><72><07><>O<E7>|<7C><><E1><06><><FF>+<2B><><F7>R <09><><9C><BB><A8><12>O<FF><4F><C9> <0A>+<15><><EF>έ<CF><CEAD>7<B7><37>KM<4B>߰<F7>b<F0><62>~4<><34><ED>E<17><FA><03><><15>_<1B><>"<22>9_<39><5F><58>%~<7E>3Es<45><73><BE><BC><C1>q4/<2F><04>q Y'J<>Zx<5A>m<17><><D7>8}<7D>W W1S<31>U'<27><10><>C<8A><1C><>p| <0E>9<11><>v<9B><76><AC>N<E1><4E>g<><67>w<C5><77><AC>T<1F>s<><0E><><B3>?_/<0E>${@<40><><16><>r<D6><72>^
<B3><E8><D3>av4'<27>N&<26><><98><E2><E5>]<5D><>)P<0F>ӋW><3E>au<61><75>'?<1C><>owE<77>- 8<7F><38><F6><C1>On<4F>X<DE>W><3E><>)<29>L<8C><4C><90>a8V<38>nJ<6E><18><><9B>1<CA>d<CD><64>ᱽl<E1B1BD><6C>D<BC><44>><3E><>z<FB>I<9E><49>u_֠<><D6A0><83>}<7D><><9F>v<AC><03><><D2AD>C<F0><43><98>`<60>QO2P/<2F>@s<><73>*<2A>P<FE>74<37>U# ?$/<2F><03>!<21><>yl/<2F><14><>|<06><><E1><AD>k<>C<BF><07> <09>دn<>z<83><19><06>t<B0>3k<33>S<BF>ɿR<C9BF> <0A><><AB><A8>F<98><1D>q<9C><1D><> ^u<><75><0F>+<2B><><B7><BC><FA>&<26>԰`[<5B>\<5C>(k<><6B>M<F0><4D><B1><96>Ȕ<E5><C894><9C>'<13><><F8>K<C0><4B>7<CA><37>N<E4><4E><F5><F5><9B>I<D9>7<92><37>o&<26><>ΌG`~/<2F><><C6><C4><F9>N<FC>{ <18>Ql]<5D>Wb$<24><17><><A9><AF>7<BD><37>N<D4><4E><F5>8<><6E><DEAE><BE><C6><E6>R;<3B>׶cm ͩ|<7C><><80>qf9<66><39>Z<DA>J<AA><4A><9C>C<B3>Zfit
<99>5<AB>/<2F><><E0>J<EC><4A><9B>Ƶ,<2C>8<D0>i3.W!<11><>?<3F>oA<a<>j:<3A><>PMG<4D><>><3E><>|<7C><><DC><DB><E7>3x<33><78>ǒH<>ߎ<EF><DF8E>v<><76>3o(<28>%ix{ d<><64>N<A1>$<24><>Lcza<7A><61>e<E9>)<29><>=9 <0C><>ԆŸ<D486>vf襝<19><00><>ѽ<>j<DF><6A>ghaw1'Eir <0C><>כ<D5><10><>w<B2>T<C2>M<83>UN<55> ^<5E><><89>zbXB<>m
a<CC><1F><><C5>R±1<C2B1>P<EB>%<25><>><3E>Gz?J Y<>,{is<><73>\<5C><>~<7E>W<F5>y<B0><79> <0A>7˵hb<>X=<3D><>R<A7><52>Q<C4><51>ou<><75>%<25><>Bh׀<68><1B>e<A6><19><><B7><D4>-/<2F><><D9><DA>#}<7D>'<27>YZ;<3B><1D><>ˁ<F3><CB81>)<29><>^<5E>MR<4D><52><BE><1C>aC<61><43>:<3A>4<17>|<7C><><85>0&<11><>1-V<> <0B>4<BF>8iz:s<><73>_<B9><5F><BE><E3>t-<2D><>e<CC><65><9F><BD><E6>W9<57>q<CF>f<17><>y7<><37><9D><D6>M<E3>7*ƿ24<32><34>u<DE><75><8A><EF><AE>o:{<7B><><FB><C0>\w<>?<3F><><FC>ß<FA>^<5E>3=<3D><CE>U#{<7B>3Ϻiu<69>k6<6B><02>+ZZ^<5E>!ΙK?<3F><>fpQR<><52>[U<><55>J<BA>0<14><>58<17>gFM<>q{eX }<1A>a<02><>.&<26>_<>cS>ٗJ<D997><4A>l4<>0<9C><30>#n<>K <0A>y<E6>"#3<><33>9[<1C><>kEC<45>g1;9<><39><08><><B4><FA>l<E7>=˙|<7C>|Rj<52>ӽ|<7C>!g<>8Q<7F><51><DA>x!VWН<57>! <0B>ޙ<8E>[#<23><>7vK<76><4B><96>Px<50><78>Ԋ<BD><D48A><BD><C5>.<2E><><8F>)<29><><9B>7z<37><7A>f_2<5F>)<29><><B2><EA>5X!<21><><FA><B9>3Eλ<45><CEBB>U<F1><55><B6>ަ69<36><39>-<2D><>k[җ`<60><><9D><FA><1B><><F8>ef2<66><32><F3> .O<>Ue<55><65>N<96> <20> R
<D5><D2>B BT<>Ys hjo<6A><0F></<2F>d<A6>!<21><>g<9F><67>t~xd><15>@c6l<36>Y<><59><8C>!U<1B>@<40>4<99>Ҋ<9F><D28A><8D><05><><A3> <0B><>046<34>[~Ŗ/<2F>~q<><15><>5<1B><><0F>fw<66><77><9F><B6><FA><BA>^yJ<79>+)<29>f<84><66>{<7B><>Q<FF><51><D2><E7>s<DA><05>%/<2F><><BB>Ҷn<D2B6><6E><F5><86><F9><99> <0A>׵a6<61><36>}ˆ<>3<A1>w<A7><77>N<1F><><F8>,L̝Xt
<96><BC><AF>Y<B8><B3>/<2F>ohm<68>i
<B4>`<60>
<E3><A3> '1_c<5F>Κ%:<3A><>lP<6C>/<2F><><F8><ED><A1><FF>_3R<33>Eq<45><1D><>;<3B><><86><92>͡ؿ<CDA1>8]<5D><>N<AC><4E>s<A7><73><9F><07>{<7B><><90><BE><B7><04><><BE>l˝-wƍ`<60><>+<2B>~%د<><D8AF>+<2B>~<7E><><C5><o<><6F>]<5D>`k"<22><>#<23>,p<><70><C8>p0<70>Vf <09><>ӧs$<24>.<2E><><B8>:<3A>g<12><>W<14>0,_'<27><><F8><82>Ľ<C1><C4BD><EA>&V>v<>)<29><><CB>=<3D><>t%jF<0E>p:H[<5B>ם<D2>M<89>d<F3><64><C8><C6><CE><D4><EC><9B>`PH<50>z<9C><17><>-<2D><<3C><>.<2E><><E9><DC><F3><AF>lS<6C><53><DF><EA>~<7E><12><><8D>u<99>+<2B><>c<82><63><8F>Lf<4C>3<93><33><FD><1B><><A7>w<D3>,o[<5B><>w<AD><77><D3><D9><E7>_<05><><E1><E8><A6>sѓԭ<D193><02><05><>A}<7D><>&<26><>_ڔ08M<><4D>6<D8>t<EF>ض<EF>"/<2F><17><>1<C7>3g<33><67><16>%fh9z<39><7A><A8>|<7C><><AC><BB> <0C><><BB><83><D4>$*w<>aVc<56>(rsGFIP9<50>Î8e͒<><CD92>͝儯V<E584AF>Z<A3>N<>%`<60><><BA>h<C2><68>ð<99>KP<4B>|<7C><><BE><B7><AF><07><>
<13><15>"<22>dH\0b<30><62><9F>h0&<26>>'ٴ~<7E>z<EB><7A><B2><C9><E9><F3>Š<><C5A0>7<CC><37><04><><03><>۽=2<><32>^<5E>~X}Z<>GG<47><47><8F>k<DD><6B>M<FD><4D>i<DB>Y^Ѽl<D1BC>Y<99><59><F4><CE>F<9D><46><84>p5<70><35>{<7B>'ua(<28>jR<6A>9eV1<56><31><EB><EA><<3C><>i<99>0<B9><04>>F<><1B><>?<3F><><E5> 9<><39>_<12>va<76><61>.)T<><54>4<7F>ľ_<C4BE>0$[TKa<4B><61><87><F5><E6><EF><DA><D2><FC><F4><1A><19>¸@<40>><3E><>i~Y<>Фm/<2F>eǍ3Bk|<7C><>[<5B>}<7D><>M<DD>(\`<60>9p<10><08>z@/)p<19><>QR<51><52>}X <20><><17><><BD><87><C6>O<12><>ϩO<CFA9><4F><B2><8F><ED>!<<3C><>J<97>]<5D>2zP_B<5F><42><95><ED><BA><9D><FB><C7>y<DB>v<BD><76>_<D1>]R<>v<>!<21><><99>e<E8>#b<<3C><>e<AC><65>=<3D><><A5><FE><A4><88><D9><10><><A6>#70Z<30><1D>ps7<73><37>)G<><47><F0>ղ<CD><D5B2>j<96>1<98>O<8F>bLG<0E><>N<FA>F<A0><46>R<FA><52>qp<71><70><AE><92> aKK<19>rU\<5C><n<><14><00>dL<64><4C>zBI^ <20><>S<>X<BD><58>u@<40><><94>1<DA><31>jפ<><D7A4><F2><89><81>h<1B><><F6><FD><A9>~<7E>;_9wi<77>o<CA><6F>L<F6><4C>]_9rY<72><59><01><><AB>o<>J<EB>EӑJ<D391><4A>m^<5E>"<22>[qم<71>V<DB><56>Z"/V<>a<F9><61><BF>2<DF><32><>Z'<27><>,<2C>;<3B><>l<81><6C><FC>?<3F>ݿCw<43><77><D9><EF>H<D9>y<EB><79><CC>y<>Vo&<26><>9<D8><39><6F>=\h<>v<><76><F6> <09><><A7><D5>`<60><>-<2D><><A0>`<1E>1<B5>S<A8>N<18><><81><AA><D6><E8>ME<4D>6<1C><><B8>
H4(x<>c]|<7C>t<99><74><1F><>q<7F>Mr<4D>/<2F> <0A><>Ya<0F>&<26><0F>ֵmV<6D>@<40>P<9A><18>0fO<66><4F>e<01>r <0C>+<2B>S<90><53><BA>.%<25>ec<><63><F0>"<22><>l<15><15>1e<31>Y<B1>^<5E><>T<B2><54><01>n:*<2A><02><0E><1C><>D<FB>'<27>`; ]Q<><08><>8.<2E>xY4<59>L<96> NG<4E><47>)ih<12><><CF><C4><C9>
k
<BB>#<23><><A1>z޲4<DEB2>F<8D>6v[K<><4B>{<7B><><D2><,Jp<4A><70>L<D8>7<EEA3B3><37><AB><BD>R<BD><52><A8>cr<><72><83><B1>٘ǣ6<C7A3>س<14>zE"v]!<21><><F9><9C>Q <0B>+z<><7A>a,^<5E>n<E5>
Z<B5><DF><D6><F2><F1><B7>]0V<30><56>v<DF><76>A<FC><41><83>b<19><>>ˑ(<16><><E3>l<><6C>l<><6C>1?֖զ:I<03>m<8F>25<32>U<AA><55><B3>N<CE>3<D4>=<3D>4<9C>o<><1F>iL<69><4C><90><83><AF>2<FC> /<2F><>Bג<>u<C9><75><FE><19>'<27><>o6<6F><36>"<22>G-<19>j<<3C><><9D>k<86>(q<><71><A2>O<F8>'<27>Q<FD>/<2F>Ԑ<03><00><><95><B5><FA>Z<85><5A><12>bg<62>-Q2P<32><50>ViYVS<56>w<17>VP9B<39><42>E<A9><45>Vh<56>#<23>><3E>'<27><>4-sW<73>`<60><08>a<84>&<26><><93><8E>"OZ<><5A>O<><4F><C2>zWQK<51><4B>Cod <0A>;_<>[k<><6B>,<2C><><BA><AE>su<73> <20>
`<60>вk <0B><15><><A3><01>ei<65>t<D9>È~<7E> %0L;<3B>Hi^<5E><01>q<><71><01><><1E>K<><4B><DB>r3<72><7<08><>X<8E><58>
aY<DE> <20><15><><F6>3<B1><19>bs<1A>U<B8>_<><5F><49>0 <20><><EB><CF>GXA<58>E<F2>}<7D><> <0B><>%G<>=SQߵYI<59>DNV˭<7F><CBAD><A4>gh^ <0B>,<02><><07><><F4>u6<75>W<11>hFk$<24>2՟-<2D>Ӝ<B7><D39C><04><><D6>f<F5><66>C<D6>9<ED><39><C0>G<AB><47><8B> <0A><><07><>T<82>,<04>F<1B><>TА3<D090><33><84>4<F0>5y<35>W<DD>t^<5E><>mt{<7B><><CF><F4><C2><FB><AA>3<9C><33>ަ<88><DEA6>.^<5E><><F8><1B>2c<32>;H<1E>M<B7>7<9F>:<3A>"r<>z<><7A>_<CC><5F><BA><CD> J<>V<9E><56>q<B9><71><A9><FA><01>6<F3><36><81>$w<><77>+<2B><>[<5B><>P<D0><11>S<02><>A<E8>AԷh<D4B7>)<29>K<FC><4B><A1> <20><>;% <0B><><B2>eov<6F><76><EF><DE><DD><FD>?<3F><><ED><DF><FF><A7><1F><><17><>>z<><7A><FA><C1>,<2C><><FB><E3>\<5C><><F6><07>5<B5><35><BA>EĘ4<C498>4<7F><34>vc<>X<E6><58>k<03><>֪<16>w<88>`D ,m-<2D><><F1><A5><9E>dAGg<><67>$D%.<2E><><9E>eqh<71><68>H:<3A>~h(<28>~<7E>y(<28>m<95><6D><9A>p<D8><70><B7><B7><08><><86>Gݎm<DD8E>>\\<5C>'<27>#<23>Ů<9D><C5AE><08><>Nnk~<7E>_<F9> <09>r<><72><07><><9F> <0A><1D><>ڰ%:<3A><><9C>r3<72>j<8E>z{<7B>6<03>US<55><53>glva<76><61><A9>a<C7>a<B8><61>iM<69><12>ڛh<15><>+@԰L<D4B0>Ew<45><77>օ.p<>^<5E>ݭtª<74>F<11>A=I9<49> <20><10>٣O<D9A3>z<C0>X<FA>M"0S<><<17>0<E2>> <09>"<22><><8A><B4>7<BD>Q <20><>w2<0E>
ȓ<AB><F5><AF>h<90><F8>5<14><><F7>kt<><74><A5>%<25>4Cۋh<DB8B>{h<>|-<2D>9.<2E><>Zrm7ͨ<37><04><>Er݀<72>~<7E><><9B><D8>I<9D>¦V@9<7F><7F><03><>O<><4F><A2><DE>H<82><00>=3:BhIV<49><56><B4><11>*A<>z<8E>2G<32><47><93>,<2C><><E6><BF><E4>ML<>b<95><62>A.tXE<58><45><0E><1A>^<5E><><B3>՛<E2> MN<4D>I<F5>1<E1><12>569<39>r<E0>]j<>Xy3'<27><k<>|q<><71>4<FA><ED><E0B598> <09><>-<2D>m<A3><6D><B3>v\<5C>dt<64><74><99>/<2F>p<F5>)d<><64><16><>!BX<42><58><CE>L<0E><><FB><F3><AB><65>7k<37>0<99><30>\K;<3B>h<A2><68><99>^O<><4F>
eF<B6><<3C><><9D><8A><83>H<FD>!<21><>`-m<><10><>j<11>q<90><71>^J@eP <0B>$#XRhk<68><6B>)<29>B<ED>4<AD>B<E1><42>
<D3>_<E2><A6>c<E5>H<AA><8B>Ҏ!h<>H<D0>%<25><>0[<5B>bJq<4A>X*<2A>2<Z<16> CA%3'<27>{<12><><CA><EA><B8><D8>:<3A>ł7<C582><37>I}<7D><>dܾi<DCBE><69> g<><67><93>$<24>I<B1><49><FD><FA>-b<00><>y+Q[<5B>?V<>٣Kȵ.<2E>d<97><64>f|<7C><><8B>ı<0F>_k<5F>Ȫb<C8AA>W}<7D><14><><F2><DF><EF><AD><FA>i5si!<21> )<29>͵<AC><CDB5><8D>`<60><>13<31>B)p<>M<AE>95<39>Q<90>CJ<01><><FB><99>%*Bgyrp<72><70>z)<29><>C<F3>K;Y<>}<7D><>%G<><47>u1X<31>fk<66><6B>T"<22><>P<E9><50>J<1A>ĈMP
ÆA<AC><0E><>I<C3><49> <0A><10><1A><>t<>n<6E>MR<4D>^6<><36>Zg±<67><77>} <0A>l<16>:E5<45><35><9B><D8><F5><EC><8F><D5><FB><8C>cY<><59><8B>p<B9>%<25>֨?[m#<23>K|ֵ<><D6B5><F7>u<1A>
<BA>Ҿ<8F><84>T_<07><><BB><A5>0X<30>½g<C2BD>ú<F0> 3<>Q<97>Z<0F>~<7E><><9A><A4>*<2A><>r'-<2D><><C1><0E>G<98>X|<7C>Ҳ<9A>g<00><><07><>J^r<>s;U<><55>09g<39><67><82><AC><90>d<D6>$<24>&<26><><05>$<24>'*<2A>5I<35>yqV<>T<95>IP<49>g]<5D><><BE><CD><F6>Z<F3>ttY<>m<6D>><3E>!<21>˗<>%=E}<7D>ۖ<CA>r<CD><72><82><D1><EF>=<3D><>ˆ<FA>;<3B><><B1>Uӫ/<2F>d<BA><64>8<85><38>Z<C8><5A>f<B1>S<87><0E><><A3><AE><BE><BE><DD><D8><EC><FC><BE><CF><ED><F6>Up<55>8<99><38><1E>2<F6>8<8A><38>8̓'<07>43t}<7D>E<C5>7=<3D><><BF><8C>i<EF>C]6tȺ<74>}<7D><>V<87><56>L<97><4C>zM<7A>6`A<17>D2<44><32><9C><B5><E7>=\<0F><><95><BD>$XP<58><50>=<3D>%<25><><EC>~<7E><><BD>=<3D><>z<00>C,<2C><>H<BC><48><92>%]_}`r<><72>7]<5D><>`
<FA>4<98><B4>l<06><><8B>P<CA>b<F2>%7<>u<E6>-<2D>دU<D8AF><55>KK<4B>aWI
<12><> <0B><@tm<74><6D>+<2B>I=<3D>D<01>zT}<7D><>W^<5E>B<9A>a<A3>Fb<46>:Z<><5A>{<<3C>NDc<44><63><D6><E6>V<A7>A<9A>,<w<><77>պ<EA>N<CE>S<A0>v<82> S<><04>h<EB>S<03>Eˋ<45>N<8C>i<86><0E><><71><D0B4><06><> `<60>t<B9>D<B0>h<>u<C3>q<90>Oʄ<><CA84><99>8<0E><><88><B4>r7<>%<25><><A9>|Ns;<3B>%<25><><E6>V}<;<3B><><AA><CA><F2><8C> QvSp5<11>^<5E>N<EB> <20><>1<80><31><DA>g9O4<4F>:<3A>h<B8>5<CD><35><7A><1B><>gY<67><59>䴁S<E4B481><53><CF><DF><F2><C0>^<5E>!<21><><BA>M<F7><1B><>`<60>:<3A><> <0B>,<2C><><B3><85><F1><AE><BF>;<3B><>nN<6E>D<CF><44>}<7D><>'d<>5,<2C>ق]p^A<><41>`:<3A><C2>le<10><>}i<>ۅ<82>B<BE><42><98>$J9<4A>) s<>dC<><43>4<85><34>Kጇ+SƔ&)<29><><15>><0E><>_޼>)<29>r<><72><94>R<D7>i$<24><><FD><9B>#6<><36><9F>_<E4><1B><0F><>\G<><47>>sU8<16>i<>c<BB>hjI<6A><49>.<2E><18>y<DB><08><1E><><8F>2<E8>5mm<0E><><87><13><>"<22>}F<>)<29><>͖<96><CD96>L<F8><4C><1C><>Y<B3><59>J<CC><4A><A7><C7> <0E><>CNi<4E><69><<3C><>!<17>,<2C><>-<2D><><0F>)<29><><F3><12><><BD></`<60><><F5><F0>)<13>݋<E6><DD8B><BC>F<CD><46><8F>]j<1D><><8E> <20><><B8><AC>Z<B5>2<E3>a<9B>&Ηt<CE97><02><><A1><E6>H<CB>`<60>$<24>&n<>$wZހ<><DE80><D9><ED>V9%<25>)<29><>3<9D><33>q<AD><71><9F>ln<6C><6E><00><><B5><84>* <0B><>.<2E><>
<16><><9B><C8><10><><D6>Ϊ<DB><CEAA>X<C9>Y<FE>V<FE><56>0<CB><30>@<40><>}<7D>A.<2E><><80>"<22>X<C6>8<86><38><D9>e<1B>a<FE>:v<>Q<F7>?\<5C>}<7D>)g<><67>һ:]<5D><>s_<73>;<3B><>;<3B><><DF><DE><F6><EC>2cO<63>\<5C>0<97><07><06>ͧ<E0><CDA7>p<BC>7<CD><37><B7>~<03>U<BD>@<40><><AD> <0C><>C<1F><13><>ӫ<97>&<26>4<AA><34>?T<><54><1F>iY<69>S<CE>-<2D><>vFĘ<46><C498><D0>Z<A2>`<60>)<29>pj<70>Qw<51>m<A2>B<0F>6<AB>v<AD>R<BA><52>qC<71>[<5B><>T@G {<7B>8<A0><38>m<00><><AC><D8><D2><EA><B5><F4><90>1Y<31><59><B3>c<> w\<5C> <0C><>b<>{<7B><>"<22><16><>
<BF><A4><88><05><>Al<00>4<C3>h<>'<27> ԃChUk(<28><><87>?<3F><><86>Zh2<68>8)1<>u<DA>C<02>j`<60>F<D0>q<DE>'!<16><>iav!d<><64><B3>2%<07><>JDsJ<>S<>%<1E>kG<6B>Ҵ3l<33>v<8D>k<A4><6B><A0>><3E>~ <1C>G c2<63>><3E>
K:i:3<><33>Ǹ<AE><17><>Zf<5A>;<3B>Qv<51><76>k<AA>V<E1>L 4 =<3D><><1F>+`U<><55><B8><B9><B2>QW<51><57>}M߫`H<><48>/8<><38>Џch'ٷ<>k<18>W<BD>^~/<2F>w<CD><77><89>><3E>,a~<7E>wlwV<77>S<D1>(<28><04><><AA>,<2C><05>Ӿ<04><>r<1B>Y<A5>I<DB><49>Z<CE><5A><FB> )<01>$<24><><E8>Qk'v<>Hj<48><6A>pUvѸɂ<D1B8><C982>‚٦N<D9A6><4E>Z<05>O<>~X<>J0<4A><15>8h[<5B><>0H<30>R<DF> <20>?0<1D>3;=|F<>:
k=<3D>l<B9><6C>g_G<5F><47>0n<30>iI8J\,ep<><70><E1><F1>u<E3><75><F9><1D><><EF>><3E>O<EA>-l<11>zʹ<7A><CDB4><FD><94><A0>ZA<00><>'<27> tq$<24><>"<22><>«<96><C2AB>'<27>l<AF>\G<>ڎ<CC> <09><>#p<><70><AA>O<94>><3E>6<E8><36>ﻢ-<2D><>o<96><6F><18><11>Ç;<3B><>}<7D><>\n<><6E>oC<6F><43><FD>d<06>o<03>,<07>
<F3>RU<52><55>@<40><><9A><F4>U<A8>W<04>o`J)<29>9<CC>ٯ<98><D9AF><B4><88><FB>`SRHr<48><72>9jDa<><61>eqU<71>+<10><><8C>0<A6>,<10>7<E0><BD><7F><BD>%<25><>~ 6<> <09><>jf<6A><66>7P<37><50><B9>@’<><C292><A6><E0><B4>y3<79>Gg<47><67><B5>Drg<72><67>l:<3A>kN<6B>W<><17><>k<92><1E>)<29>t<E9><74><B5><8E>wa<77>T<E1><54>9<C1>5<AD><35><E9><F7>{<7B>6<87><><E4B3B6>ӎ<84> sY<73><59><C3><EC><E9><A2><EB>sWm:<3A>m<B5>ʐC<CA90><43><FF>V<7F><56><B3><AB><A7> <><7F><F5>:<3A><><91><8D>+<2B><><85>*<2A>KnM<6E>/<2F>̌<0F>jm<6A><6D><95>
y^<5E>}<7D><><F6><B9><A7>#F$<1F><>ƺϵF ~<7E><31><CDB7><B8><82><E9>ǯ<BF><19>g<97><18><><94>ԏ#d <09><0F><06><>X<9B><58>5`<60><><B3>fl}.8<B5>|.D5h~ uGa<47>vTL<54>)X<><58><85><BD><B8>d0m<30>Y<87>\cNJ'㊗n<E38A97><6E><B9><EB><EC><F3><EF><BA><F9><C5><F8><BA>_<F3> <20>:/<2F>72<32><7F><F6>Có|gl\y<>m<99><6D><D6> <0A><>fl<66><<3C>`<60><1C><>ٗn<D997><6E><BE>ϦO<CFA6>h<BD><68><BC><7F>,ϸy<CFB8>I<DE><49>_tj<74>i<BA>IþS/=<3D>R<FD><52><DB><F0><BC><F5>7<F3>z<AE><7A><15>h<E7><68><F5>5<7F>O<FF><1F><1E><>@`<60> mz<6D><12>><3E><>`<60>'@<40><10>.<2E> &D/<2F><1F><11><1F>1<D9><31>3FH<46><48><D3><0E><><93><F5><82><83>F<0E><>l$<24><>~&<1C>Fv<46><76>q<9C>,<2C>#d<>Y<E3>v<B3><76>W<E0>=<3D><>l<C3><6C><C2><EF>Y<CF><59><EE><EE>Ÿ߲<>om{r<><72><A1><F8>pddD<64><44>,M<>W<AE>ށ<F4>A%<25>y<84>4<F0><1A>V<A0><56>zd<7A>Z<8C><19>wkU<18><>5<19><><DA><FE> ʦ<><CAA6><D1><1E>P<10><><B5><94>U\<5C><>Q<8A>^<5E>_<<3C><>'<27>\<5C><><9C>V<85>h<8A><68><A8><FE>ڡ<D0><DAA1>E<B5>[R6<0E><>ұ<B3> <20><><B1>8<><1A><18><>K<D0>?<3F><13>`<60>1<14><04>G<E3>do<64>/+<13>W@Ł<><C581>&<26><1F> TZk<5A><6B>tt8H<13>hU<68>x<FF>'d<>O<12>v<>N<9D>-'~<7E><><C4>R<0F><><FE> GR<47><1B><><EC>0=<3D><><C0><A1><B3><19>c<AC><63><EC><A0><F5><8D>r7O=.<2E>I<18>NHw<48><77><1E>cn<0F><1C><>9<><39>e<D6><65>@f]<5D>.<2E>Y<D2><59>30 Nod<6F>n<98>J<B9><4A><B3> :<3A><>澩Z<E6BEA9><5A>M<8B>0<8E><30><BB>W<ED><44><C58C>n<90>m<D8>W<06>o0<6F><30><8E> <1A>Wܘ1<DC98><31>p<DE>q<D0>4<C5><34><89>|<7C><>)<29><>q
<A2><8C><95><F8>F<CC>Ģw<C4A2>7<8F><01><><0E><>M_I<5F><49><EA>u<86><75>6=<3D>,]<5D>}y19w<39>`'<27><><F7><6F><D1AC><D8>B[yw<79>Kk<4B>{]b<><62>Y<B7><59><16><><FE><E9>+Ii<49>9N<39><4E><1D>L<81><4C><FF><FA><C2><E9><16>-<2D>=]3/Y<>خV<1D><>k<A7><6B><F0><DC>?a]<5D>L\׶<> <0A><><87><BA>Q<00><>m<18>t<EB>:k~@<40> <09><><9F><C7>? <0A><><B4><DD>*v<03>(aMl<4D><6C><A6><8D>ղ<AC>><10><><C4>i*R<>i<0F><>l<D6>O<D9><1F><><FA>β@<40>_<02>U<A3>;5<><52>o<8D><6F>#<23>bN<62>9k<39><6B><A4>'<27>;<0E><><05><><B4><ED><E8> <0A>KF,u j<><6A><1C> hI<68>J<A5><4A>>BCK(<28><><9D>><3E><16>I<86>紌}ђ4C&5l<35><1C><>c~<7E><><AF>e<CC>7>v<><76><1F><><98>5<A2><35><B1><1E><>y<7F>$I<>3<ED>gK<67>/D<> <66>:<3A><>eSke<65>(YD<59>h<9B>fke<6B>{
<C1><81><B5>g<B6><AD>/_ݻ<5F>9$u<>7<F5><37><AF><15><>C}V<07><><89><18><><11>ڬw<DAAC><0E><>*Z
w<CD><07><03>5<D6><35><FF><8C>Dj<44>?ņ<>D<CD>(%+<18><><83><8A>T4.<2E>Y|gi <05>e<EC><65>FiI <0A><1C><>݂<CA>=V<>F<> <05>~<7E><><F1>Ƙ!<21>m<AD>hb<68><62>Zbx`o;͓<><CD93><A7>r<B9>FGC2<43>@<40>>K8<4B>,m<><6D><96><A1><E5><D5>0<><30>.<2E>-<2D>#_,<2C><><B4>Ԅ<B0><D484>]<5D><><06><>}n<>d<97><64>r<1E>M<94>i<D8><69><A3><96><8E>DX<13><>5<E8>ZH<5A>.*"<0E>f<A8>Gi<47>i <0C>h<F4><68>8Qk<51>T<15>}<7D><>1<82><31>"<22><>9<BE>x:<3A><>[<5B> !h<>W<<3C><>8:<3A> <0A>*<2A> 4q<34>:<3A><18>G<B3>, <16><D}<7D><><92><80><AB>]@r<><72><BA><A8><93><B7>T<8A>T<08><>Sd<>E$<24><>E<C3>_<E3><16>( ξ<><CEBE>j<C5>4<D2> 6<>j$<24><> <16>jހ<><06>f<17><>c<1D>h<><68><A0>=7<>* <0A>@<14>$9g<39><05><03>T9<54>Kr(.<2E>y<D1> \<5C><>ֿMt_!(S<><53><0E><>Pĉ-g}Q<><.<2E>D<1F>"<22>G%yh!vd<76>R<B2><52>!<1D><03>~<7E>匴K<E58CB4><03>] <<3C><><9D>?<3F>"<22>apCDKK<4B>n<E7>e3mLk : ½ F>(<28><>|<02>ލ<85><DE8D>ݴ<94><DDB4><1B>{`<60>X<B1><58>`E<><45>>;<3B>S<C5>8X4D<><44><07>D|<7C>qHP<48>5M5<4D>@[<17>iġH<C4A1><48><>DR<44><52><BE> p&b<><62><B1><11><>jD\<5C>T<FA><54>;<0F><05><07>$`Rl;I<><49><BB>,f|<07><><E9>m5<6D>8<A1><38>ZK<><4B><8D>/X핓j<ED9593><6A>փ<84>ֶ<D1><D6B6><98>@tڶ<74><DAB6><BB><FE><FA>kx<>^0 |,t<><74><9D>^<5E><><13><>I\<03>ux+<1A>z3<7A><13>[<5B><><EF>՝w<D59D><77><8C>6O-<2D><><8D><05><>Ԃ<CC><D482><EC>cX<63><58><D0><F8><F0>=<3D>E<82><15><>Q<A4>\<5C><><18><13><>T+wh<><68><AF>j<D1><6A>Ћ9 <09><>ThPd<50> h<>%Sj<53><6A>f<E0>x%<25><>!<21>t<F4><74>FX<46><58><B0><D2><F2>&Y!K<>}<08>#<23>iu<69><75><98><8D><90>#G<><47>~<7E>kxc<78><63>F<F0>x<>&,<2C><>C4<01><><DE>#<1A><>?<<19>" <20><><B2>w<FF>F9<46><39>6<B5>a%<25><>hL<68><4C><00><>l <20>f<ED><66><80><95><F2>K<C1> <0B><> S_<53><5F><8E>+<07>Z<DC>cPd<><64>D<>@<40><>Z<A8><5A>"<22>
<A7><E5><D8>cB<84>'_._<>Z{<7B>[<5B>Ex<10><><AE><8A><FA>0>lB!.<2E><>^Aw<41><77>*Ō<1F><><1B>%<25><>F<99>1<19>׬%C<><<3C><>w<F1>L€-A˸<41><CBB8><8F><C9><F5>f<E1>s<17>2<FA><32><A0><89><81><08><>L2I<32>6<18>f<CC><66>fe<66><65>a6<61><36><C9>ɗYV0<56><30><16><><FE><80>b+x<>E^<5E>jr<6A><72> <<3C>Hx<48><78><F2>i3<69><33>?W<57><7F>S<D6>˔n~<18><>L<99><4C><99>fšl,5
Ҽ<10><><8B>Զj<13><14><><E4>D<CC>%*<2A>Z<CD>Q<18>B><3E><><8A><85>c<D4>Y<85><59>y<04>)<29>o&<26><>"<22>Î<93>g<<3C><0E>LT<4C>1<><31><9D><DF><D2>-^`<60>whP@<40>lCM@<40>ieV<65>p:<3A><><04> <0A><>U<99><55>$Q<><03><>9 iiE<69><17><>8V-c5<63><35><1C><><8E>ѠH<D1A0>m<BD>"딠{ݴ<><DDB4>B
<F3><13>j@<40><4D>UT?<3F>eQ<65><51><77><C89F><C9><C6><FB><C8><E1>'4<>8{<7B><><E1><F5><18><>e<BA><j&k<>Sm<53><6D>M<>m9<6D>V<B5><56>D<1F><>i<E1>pѪr<D1AA><72>X<><58><A2><81><BA><87> <20><>y<E7><79><B3>t{<7B>JF<4A> <09><10>`<60><>D<BB><44>5:<3A><>X<DE>DU:<3A><>{.<2E><>t<8B>x<DC><78>9<><39>P<17>~i<> <0B><>wp<77>y<>h<11> <09><05>t:7:<3A>}<7D>O<BA>& <0B>,m<><0F><><AB><BC><C3><CA><FB>c~<7E>y3<19>[&6<>uZ<75><5A><D4><16>F<EC>l2<6C>%<25><1C><><E7><FE><9D><93><EE><FF>\K!4O<34>{<16><><A9>ə<B3>wg<0F><><D0><F0><D4>oM<6F><4D><B8>po<70><6F>Y<BB>][<5B> ZcJ<63><4A>lY<6C><59>Ho/<2F><><E2>)<29><>:<3A><>=<3D><>/<2F><>v<F3><76>6<B7><36><DC><FC><BB><EA>ջ<D9>y<D5><79><F7><8F>֟߅x<DF85><78><A3>_<D6>\<5C>bѠ<>"<22>Q<F7>}<7D><>><3E>up2<70>r!<21>%<XY<58><08>ƃ7<><37><B3><DF><E2>w<DC>><3E><><06><><F2>ٯn<<3C>&a<><61>?<3F><>j?<1C><13><><C0><E1><1D>xdA.<2E><>P<><<3C>U<0E><>7rN1<>7$<24>|<7C><><F7>~<7E><><1F><> <0C><><93><1C><><FC>I<A0><49>΃<B0><CE83><A7><B6>V><19><>qN+<2B>ǚ3<><33>Ԅ<><D484><FA><0A>!<21>u<CE><15>R<E2>&{<7B><>c<>k2<6B>Hq<48> <0C>FH#H|<7C><>#[6<><36><8A><왲<><EC99B2><B5><E7><FF>1R<11><><E4>!ZJ<5A>4<E7><34><8A><EE>'k^!M<><4D>sdZ1<5A>:n,<2C>x<89><78>#<23><><C0><F1>w<B0>؜]<5D>)V,<2C><><EE><E2><DE><F6><<3C> 諛C<E8AB9B><43><15>ô<7F><C3B4><FF><9E><87><E6>bP?<08>B'e<>sx<><78>Bm<42><6D><A4><9D><8A>D`<60>*<2A><><FB><F5>u<F8>$<24>~<14>Dˣ<>q<B8><71>w<D4>٦~!<21>{<7B>5d<35><64>j<F5>7<E2><10><><BE>` Nn<4E>^m垨<6D><E59EA8><D4><E6><D1>L<CA>>+<2B><><01>DCg<05>*B<><42>i<D4>i(<28><><8B>8<C1> <09><><F5><90>N<BC><4E>O<>X<DC>?<0E><>!<21><><12><><EB><E8><AB>M_<4D><5F> <09>Iݔv<17>5h破s<E7A0B4>Ict<63><74><1D>r<C4>o<><6F><CA><D6>
3<E3><81><1C>@:]<5D><><C8><CF>ǖ<FD>N<A5> <20>(<28>`i9<69><39>%$<24>v<B0>2<C8><32><91>@NJfM)<29>hV<68>F<BB>ͪ<E7><CDAA><8D><A2><A7>+ 4;<02>z<B0>
#<23>><3E>Ra<52><61><8E>i<D3><69><C7>x<E9>L<D8><4C>x%$b<>G <09>B<8B>V[<00>C<FD>HNFA(-<2D>o&<26>(T<><54><80>Ph<>_=؈<>%:6:<16><><F8><15>g<><67>2<9C>v@<40><10>\<5C><><D1>]<5D>+z<>:2z<32><7A>'<27><><6B><C598> Ɩ΃<C696>{F<><46><B7><A9><B4>7c<37><63><A4> 氽IIn<49><0F>,Y<>9|\d<><64>ҩ#<23>Z<D4>Z<E8>+ <0A>><3E>
S"Y-hU4<>Շ<E3> x<><78><CE>c@n<>$j<1B><>OP9J<39> <0B>3!a<>t[<5B><>n<07><>z<11>`ֿ<>_<A6>ѣz<D1A3>h<D3> <06><><DA><CB>iD<0F>r<0F>L<BD>{<7B>^<5E><><F6><B5>Z]6-<2D>fjNيK<D98A>><3E>K6a<36>g<FF>՘<8C><D598>n<C6>RGa<47>&E<><45><FD>ڛP<DA9B>g<EF><67>b<F0><62>xy<>I<ED><49>lV<6C>O<1B><>F<D0>V <0B>n <0A><><12><01>k`j<><6A><9B><7F>D{`<60>s1<73><31><94><8F><06>
ڏoe<C4>#^)΍4<CE8D>6^<5E><>0C<30>F#m9%W-<2D>Vڻm<DABB><6D><99>9<BF><39><81>)|V<>x<C2>k&<26>[hS<68>h!<21><><A7><CF><F6>-<2D><>I~<7E>>4p<34>Kn<>9<87><39><D4>(<28>8@<16>Q<93>ɛ <04>͋<03>-<2D>X<B0>\;2ݖ$w<>[<5B><><92>Ӊ<E9>,9<>k|<01>N<C2><4E><87>rg<72><67><FD><F0><B1><DB><1E><>l'?<3F>̴<D3><CCB4><80>f<9C>Lٯk
<BE> <0C><><F5>R<1F><17>@<40><><99><8C><D6><F8><C8>,h<>Z<A6>8<9C>J*<2A>د<>n<B9>Ge)褢$<24><><9F>,s<>N<0F><>4Z<34>t<>uE<75><45>b<8E><62> 0S<17>c<D0>PiWk<06>؜<CD><D89C><CA><D9>b<A1><62><1F><>}v<>86<38><36>[<1F>qq1.<2E>!<21>!|F<>;<3B><>a.7<93><F4>a<C1>'0MR<4D>a<85><61><82>N<C3>"<22><>{<7B>;<3B><><FF>_<1F><"
<9E><EF>xz][v;w<>ht|<7C><><DE>~<7E><>}<7D>w<<3C><>{<7B><><86>aw<61>q<DA><71><17><>{l<><16><><B1><C7><FB>(><1<>׷<><D7B7>_ <09>㚡y{'eJ#<23>/Mh_f`<60><><82><B5><89><FB><92>Y<D9>h<94><68>P <20><>a.<2E><>+<2B><>Q4+<2B><><C1>I<9B><49><10>k<E9>%/v<><06>?<3F><>c<0E>I$<07><><B9>%Wn^<5E><>B.vH(d<><64><BC><E1><90><F7><FB>2<><32>n<18>ŭ<83>o;<3B><><FD><B1>3<8A><33><BB><CC>Ao<41>A2Y<32><59><12><>M<BC>KV<4B><56>#<23><>vx<76><78>R<93><52><80>1<F2><1E><>)<06><01>b
<9C><D4><D3>.E<>ڢVK}<7D>bp<>';<3B>F<F7>D4<44>=]%<25><>=}<7D>2}z<>G<C7>7n<37><6E><A0>к<E3>Wv<1D>O<A1><4F><C6><7F><EA><E6>s<EE><73><A8>L;ڴ<>vo<76>J;<3B>!<21>M<EA><4D>Ti <0B><><04>z<91><7A>Z<BF><5A>\}<7D><><AB><06>B<B4>~<14><1D><1C><>p<A5>4<><34>&&>KJ漢<4A><14>jl<6A><6C>Op<4F><><7F><82><13><>}<7D><>><03>%<25>֡u#<23><><A0><FB>d[<5B>V<BB>9<E4><39><1E><><<3C><<3C>i]<5D> 9t(<28>:<3A>}蕭<><01><><1C><>U<B3><55><A1>(<28>c/*<2A><><A0><9B>3r<18>Pm<50><6D><F0>{5!F<><46><45><CDA1>N<>O<81>]246 <1F><><8F><93><FE>bT<62>?<3F><><FA>:F<>|<7C>@[<5B>3<05>֩<9B>$tl<74>y<F6><79>P<1D>}<7D>`s<>cFF<><46><87>'<15>\<5C>h<A9><68>D (<28>~**&<26>4<15><><54>a<C6><61><97><FD>K><3E><><BD>qa7<61><37>nr\<5C>u);T<><54>]xx׮<78><#S<>9uR/<2F> ųآ1A<1F><><F5><A3><C3><00><><BB><B7><9E><F1>Y<B5>*<2A>.o%<25><>6<E7><36>i<98>:.<2E><><FC><F4><18><>$<.<2E><><EB><1B><><A4><F1><F6><F6><BE>v<E4><76>k߾=y<>i<9C>q<81><71><90>׮ݾ[fM<66>qZ<71>:y:<3A><>Bg<42><1C><><8F>&̇X<CC87><58><B2><ED><EF>qۉ<DB89> <0C><><BF>у<88><D183><CA>p<CE>3<7F> <09>hUO)f<>lڦbӮc<D3AE><63>W
6<87>#<23>D<1D><><9F><E7>`S<><53>5<A5><35>ű<>U<D6>|<7C><><8A><E7>>2<>4<A3><34><FF> <0C><><13> <09><><D1>Nf<4E>8><3E>L)<29>ZU<5A><55>5<17><1B><> S<><53>I<E3>0du<06><><04><05>f<13> <0B><>Ɛc<>~<7E><><EF><98>^U<>]4)+<2B><19><><02>)5aQh<>^<5E><>8>ydk=N$<24><>H<06><><86>K<8E>s<A2><73><8A>+<2B><><9D>)<29><>B<AF>H*$iirߙ<10>Vh<56><68><10><>h<>R<C8>Cx<43>c<><E3BA87>R^<5E>_<E0><5F><8B>ч<C3>)<29><><A2><F8>ɻ<D9>&<26> <0C>VY<56>]<5D>W<57><7F>ԯ<9A><D4AF><F8><DC>6<8C><36><91><9C>N<BD><10><>C<B6>Dλи<CEBB>w<92><77>;<3B>A<><41><CB><FD><E3>:<3A>-<2D><13><>àf<CD80><66><80>M<8B><01><><94>p <0B>ϖ[h<>NK,<2C>:<3A><>@<16>Q<AB>,><3E>TwĶxiJuVb<56>.>Xv<58><76><9F><D9>)AbQ<62> a<>9ʲ?<3F>V<82><56>@<40><>,<2C>:Q<>'<27>B<A8><42><84><CF><EE><C1><04> <09><>F<FC><46>xb<78>| <16><1F><>~<7E>у<F0><D183><FC>I<FC><49>
<97><D3> 7<>]V옩bҪ<62><D2AA> f6<><36>j<05><><13><>4>kE<6B><45>_)<29><><8C> <0C><><15>f<9F><66>`|t<><74><BA>hO]<5D><><B6><8B>NI{2 G%3<>6<14><><D4>@<40>0$<24><> D<>`;.[<5B><19><><BD>'<27><>&<26><><DD><D5>%_<>%;<3B><>̠7y<79><7F><C5>O<4F><7F>c<94>տx `slR<6C><52>ـ<1B><><FA> u<><75><0F><>G<17>f1h<31>V3<>䬉`h<><00><>|<7C>|<7C><>k'<27><>9/(_U/~<7E>x<A5><78>S <20>5<C1><17>}<7D><00> <0B><>FI<46>`<60>P<D3><43> f<><66><99><13><1F><><BE><84><9F><95>ݻ<DD><DDBB>`<60><><A9>V<AF>z-<2D>N<FC><4E> k<0E><><E3>d<FA>L<AC>e "<22><><FC>7y<37>8<A2>t |f<><>/X4<58> <0B><><EF>[t<>9;p<>)<29>/<2F>y<9E>#<23>ü<AC><02>@~<7E><><BD>-<2D> <20><><AC><FE><A8>d<9B>,<2C>GZ<47>:<3A><><F5>S.{<7B>J<E4>ɳ0<>.<2E><>x<>c`d```dp\<5C><>SO<<3C><>Wy<> @<11><><<3C>z0<7A><30><FA><BF>9<FF>wY%<25>\&<26>(h3 <0B>x<D9>c`d``<60><><95>&<26><>]f<><66>A<01><01>;Kx<4B>c<DA><63><DC><C1><A0><C1><B2> <09><><A7>L= <0C><08>q<10>100܄<30><DC84>@> <0B><><90><F6> 9<><39><13>_@<40><><EC> f<><66> 5<><0F><>!j<><6A><FE>`<14>aX<16><><88>j<A0>z<18><>4#<23>f<01>1<07><><11><07>Y<B3><59><D0><F4> <07><>yI<>!<21>+<2B><56><C4AE>l<FF>~<7E><>(<28><14>z<8B><7A>P<> T;u<>v<A0><04><05>43 <0C>' <0B><>A<BF> g <20><><F1><95><00><><03>{<18><>c P<><<02>n@<40>
H !‡Q<0F><>^@,<2C><><8A>*<2A><08>L@<40>
gE<67> ,G <20>0<F6><30><80>  <0C> '<27><>G(Ƅ<11>&<26>dAg@)` <20><>sP!H<><48>O<FF>?<01>*R<1A>|x<>c``Ђ<>4<C2>%<25> <20><01>cc <0B>*<2A>s<C6><73><8C>̘f0<66>azǬ<7A><C7AC><C3><EC><C3><FC><85>5<88><35><85>M<8F>ͅ<89><11><0F><06>S8 88<>pqq<71>pup<75><70><0E><><E3><9E><C0>ǎg<03> o<19>*>+<2B><04>.<2E>;<3B>7|:<04> <09> <09> NJ<10>%,&<26>'<27>#<23>$<24>KTMt<4D>X<92><58>-q<1F>6<F1>M<12>$u$gH<67><48>򒪑<91>&uMꉴ<4D><EA89B4><88><B4><81>t<9F><74>6<F4><07>_d<5F>d<F8>d<A2>ȼ<96>5<93>=$' <20>%<25>F<F7>M~<7E><><01>G
l
Z
n
y
>)f)QrR:<3A>\<5C><>NEDe<44><65>3U<11><0E>9<D5><39>TߩE<DFA9>u<A9><75>S{<7B>Χ<A1><CEA7>~N<>B#Ec<45><63><87><A6><15><<3C>7<AD>ڛ<><B4><7F><E9><B8><E8>ݧ<D0>L/Mo<4D><6F>/}+ <09>m<83>j<86>u<86><75><86>8<8C>v'O0<4F>2Yd<59>b<CA>f<9A><66>L<CF>,<2C>l<C6>9<8B>y<97><79><1A>?[,%,#,<2C>Y^<5E><><B1><92><B0>j<B3><6A>f<BA>c]b}<7D><><CF>&<26><C3><E68EAD>
;;<0F>=v<><76> <0A>g909$8lqTr<54>p<EC><70><FC><E0><D4>ù<F4><C3B9><C3><F9><9B>K<8D><4B><Qˆ<51><00><00>xڭR<DAAD>N<CD>@<18>4<12>I8<49><38><F7><E0> "<22><>x<10><>FѣT(<28>B<95><42>T<12><>g<C2><67>ŃG<C583>@<40>ç<DF>`<60>]$<24><>ivw<76><77>|<7C><>S<00><><1A>/<2F><05>h<><18>+<2B>zX<7A><12><14>1<D6><07>#<23>ó<D8>Q<C2><51><E4><F0>n<><6E>“<AC>jO
O!<21><>+#<23>Px<1A><><8B><FA>3<C2><19><><85>g
<BF>"<22><>=<3D>!<21>߇ah<61>n<DA>]w,<2C><AF><E59B96>&<<3C><><B4>5ب#<23><>G<81>4<8E>Ha<48><61>·vp<76><16>]<5D>߀<C482><DF80>\>Ɛ<>/wU<77>U<AE>Ηdn<64><6E><F1>(<28><>m<88>z<9E><1C>W<93><57><A4><1A>C}<7D>=G<>۸aE<61><45>bgRz)<29><><E0><84><A7>W<18><>SiyD<79><44><0E><><8C>Sy<0F><>=<3D><><99><C1><B0><A7><92><D4><E8><ED>u2X<><58>t<>X<98>\@<40><> j
N<8D>Uqr<85><89><9B>X<95>#<23><><C7>X<D3><58>-<2D><C7><7F><A9>P>&<26>]~<7E>6};ʵϪ@<40><CD><7F><E3><94>B<B2><42> 2<>W<D9><57><99><F6><FD><A5><99>3<C8><33><87>2<CC>,2<><32>c<FF> <0B>Ɉ<8D>x<>m<DA>UהeF<>ـ`<60><>ݭs<DDAD><73><BF><F3><08><><F3><D9><02><>(*vwwwwawwǁ?Ÿ<><C29F><A0><F8><CD><F6><CC>^3kf?<3F><>5k:c:<3A><><A3> :E<><45><E7>?;<1D>0<C6>3<B6>3<B6>3<B1>q,<2C>x&<26>(<28><>8K<38>$<13><>R,<2C>2,<2C><><DB><F9>X<E5>X<><58>X<95>UX<55><58>X<D5>5X<35><58>X<B5>uX<75><58>X<F5> ؐ<>ؘMؔ<4D>؜<><D892>
z<94>T<D4>4<B4><F4>ٚmؖ<ED>؞ؑ<><D891><C9><14>2`<60><>م]ٍ<>ك=ً<>ه<>9<FD>9<><39>9<83>C9<43><39>9<C3>#9<><39>9<A3>c9<63><39>9<E3>9<>iLg's
39<95>Y<CC>f<0E>1<A7><31>9<D3>y<83><79>Y<C9><59>|<7C><>\<5C><>|.<2E>B.<2E>b.<2E>R.<2E>r<E3><72>J<E0><4A>j<E2><6A>Z<E1><5A>zn<7A>Fn<46>fn<66>Vn<56>v<E3><76>N<E0><4E>n<E2><6E>^<5E><>~<1E>A<1E>a<1E>Q<1E>q<E3><71>I<E0><49>i<E2><69>Y<E1><59>y^<5E>E^<5E>e^<5E>U^c<01><>o<>o<><0E><><1E><><1F><1F> <09><><19><>_<>_<> <0A><><1D><>?<3F>?<3F> <0B><><1B><><BF><F3>i3<69>ϙ<E7> <09>f<F3><66>v<E8>S<BB>;<3B><><B9> <0B>p<DF>n<>-<2D>ʭ<DD><CAAD>mݾ;y<><79><B8>p<C8><70>q<91>ysg<73><67><8F>F<A8><46>n<8C>a<ED>_j<5F><6A>x<><78><89>x<><78><89><|<7C><>x<><78><F8><A0>k'vb'<27>k/<2F>b/<2F>b<F6><62>W<B0>+<2B><15>
{<7B><><85>^a<><61>W<B0><57><D8><EB><D9><EB><D9><EB><D9><EB><D9><EB><D9><EB><D9><EB><D9><EB><D9><EB><D9>+<2B><><ED>J{<7B><><A5>^i<><69>W<B4>+<2B><><ED>*{<7B><><95>^e<><65>W٫<57>U<EC>*{<7B><><95>^m<><6D><53><DBA9>vj;<3B><><B5>Nc<4E><63>^<5E><><8D>^c<><63><AF><B1>k<D8>5<EC>{<7B><><AD>^k<><6B><AF><B5>k<DA><6B><ED>Z{<7B><><AD>^<5E>^<5E>^<5E>^<5E>^<5E>^<5E>^<5E>^؋<7F><D88B><EE><A3>><3E><1F>­<DF><C2AD><DC><DA>{<7B>;<3B>G<BC><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<FD><47><D1><1F>G<DD><47>}t<1F>G<DD><47>}t<1F>G<DD><47>}tݧ<><DDA7><B6><A7>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FA><8F><FE><A3>?<3F><><FF><B9><EF>; <0B>=<3D><01>]3@<40><01><><FF><01>K<>PX<50><01>Y<8E>F+X!<21>YK<59>RX!<21><>Y<1D>+\XY<58>+R<>X<E6><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dashboard for {{full_path}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
<link href="{{path_to_root}}css/nv.d3.css" rel="stylesheet">
<link href="{{path_to_root}}css/style.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="{{path_to_root}}js/html5shiv.js"></script>
<script src="{{path_to_root}}js/respond.min.js"></script>
<![endif]-->
</head>
<body>
<header>
<div class="container">
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
{{breadcrumbs}}
</ol>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>Classes</h2>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3>Coverage Distribution</h3>
<div id="classCoverageDistribution" style="height: 300px;">
<svg></svg>
</div>
</div>
<div class="col-md-6">
<h3>Complexity</h3>
<div id="classComplexity" style="height: 300px;">
<svg></svg>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3>Insufficient Coverage</h3>
<div class="scrollbox">
<table class="table">
<thead>
<tr>
<th>Class</th>
<th class="text-right">Coverage</th>
</tr>
</thead>
<tbody>
{{insufficient_coverage_classes}}
</tbody>
</table>
</div>
</div>
<div class="col-md-6">
<h3>Project Risks</h3>
<div class="scrollbox">
<table class="table">
<thead>
<tr>
<th>Class</th>
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
</tr>
</thead>
<tbody>
{{project_risks_classes}}
</tbody>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Methods</h2>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3>Coverage Distribution</h3>
<div id="methodCoverageDistribution" style="height: 300px;">
<svg></svg>
</div>
</div>
<div class="col-md-6">
<h3>Complexity</h3>
<div id="methodComplexity" style="height: 300px;">
<svg></svg>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3>Insufficient Coverage</h3>
<div class="scrollbox">
<table class="table">
<thead>
<tr>
<th>Method</th>
<th class="text-right">Coverage</th>
</tr>
</thead>
<tbody>
{{insufficient_coverage_methods}}
</tbody>
</table>
</div>
</div>
<div class="col-md-6">
<h3>Project Risks</h3>
<div class="scrollbox">
<table class="table">
<thead>
<tr>
<th>Method</th>
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
</tr>
</thead>
<tbody>
{{project_risks_methods}}
</tbody>
</table>
</div>
</div>
</div>
<footer>
<hr/>
<p>
<small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
</p>
</footer>
</div>
<script src="{{path_to_root}}js/jquery.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/holder.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/d3.min.js" type="text/javascript"></script>
<script src="{{path_to_root}}js/nv.d3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
nv.addGraph(function() {
var chart = nv.models.multiBarChart();
chart.tooltips(false)
.showControls(false)
.showLegend(false)
.reduceXTicks(false)
.staggerLabels(true)
.yAxis.tickFormat(d3.format('d'));
d3.select('#classCoverageDistribution svg')
.datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
nv.addGraph(function() {
var chart = nv.models.multiBarChart();
chart.tooltips(false)
.showControls(false)
.showLegend(false)
.reduceXTicks(false)
.staggerLabels(true)
.yAxis.tickFormat(d3.format('d'));
d3.select('#methodCoverageDistribution svg')
.datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function getCoverageDistributionData(data, label) {
var labels = [
'0%',
'0-10%',
'10-20%',
'20-30%',
'30-40%',
'40-50%',
'50-60%',
'60-70%',
'70-80%',
'80-90%',
'90-100%',
'100%'
];
var values = [];
$.each(labels, function(key) {
values.push({x: labels[key], y: data[key]});
});
return [
{
key: label,
values: values,
color: "#4572A7"
}
];
}
nv.addGraph(function() {
var chart = nv.models.scatterChart()
.showDistX(true)
.showDistY(true)
.showLegend(false)
.forceX([0, 100]);
chart.scatter.onlyCircles(false);
chart.tooltipContent(function(key, y, e, graph) {
return '<p>' + graph.point.class + '</p>';
});
chart.xAxis.axisLabel('Code Coverage (in percent)');
chart.yAxis.axisLabel('Cyclomatic Complexity');
d3.select('#classComplexity svg')
.datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
.transition()
.duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
nv.addGraph(function() {
var chart = nv.models.scatterChart()
.showDistX(true)
.showDistY(true)
.showLegend(false)
.forceX([0, 100]);
chart.scatter.onlyCircles(false);
chart.tooltipContent(function(key, y, e, graph) {
return '<p>' + graph.point.class + '</p>';
});
chart.xAxis.axisLabel('Code Coverage (in percent)');
chart.yAxis.axisLabel('Method Complexity');
d3.select('#methodComplexity svg')
.datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
.transition()
.duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function getComplexityData(data, label) {
var values = [];
$.each(data, function(key) {
var value = Math.round(data[key][0]*100) / 100;
values.push({
x: value,
y: data[key][1],
class: data[key][2],
size: 0.05,
shape: 'diamond'
});
});
return [
{
key: label,
values: values,
color: "#4572A7"
}
];
}
});
</script>
</body>
</html>
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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
*/
use SebastianBergmann\Environment\Runtime;
/**
* Base class for PHP_CodeCoverage_Report_Node renderers.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2014 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 $generator;
/**
* @var string
*/
protected $date;
/**
* @var integer
*/
protected $lowUpperBound;
/**
* @var integer
*/
protected $highLowerBound;
/**
* @var string
*/
protected $version;
/**
* Constructor.
*
* @param string $templatePath
* @param string $generator
* @param string $date
* @param integer $lowUpperBound
* @param integer $highLowerBound
*/
public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
{
$version = new SebastianBergmann\Version('2.0.6', dirname(dirname(dirname(dirname(__DIR__)))));
$this->templatePath = $templatePath;
$this->generator = $generator;
$this->date = $date;
$this->lowUpperBound = $lowUpperBound;
$this->highLowerBound = $highLowerBound;
$this->version = $version->getVersion();
}
/**
* @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)
{
$runtime = new Runtime;
$template->setVar(
array(
'id' => $node->getId(),
'full_path' => $node->getPath(),
'path_to_root' => $this->getPathToRoot($node),
'breadcrumbs' => $this->getBreadcrumbs($node),
'date' => $this->date,
'version' => $this->version,
'runtime_name' => $runtime->getName(),
'runtime_version' => $runtime->getVersion(),
'runtime_link' => $runtime->getVendorUrl(),
'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();
$pathToRoot = array();
$max = count($path);
if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
$max--;
}
for ($i = 0; $i < $max; $i++) {
$pathToRoot[] = str_repeat('../', $i);
}
foreach ($path as $step) {
if ($step !== $node) {
$breadcrumbs .= $this->getInactiveBreadcrumb(
$step, array_pop($pathToRoot)
);
} else {
$breadcrumbs .= $this->getActiveBreadcrumb($step);
}
}
return $breadcrumbs;
}
protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
{
$buffer = sprintf(
' <li class="active">%s</li>' . "\n",
$node->getName()
);
if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
$buffer .= ' <li>(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
}
return $buffer;
}
protected function getInactiveBreadcrumb(PHP_CodeCoverage_Report_Node $node, $pathToRoot)
{
return sprintf(
' <li><a href="%sindex.html">%s</a></li>' . "\n",
$pathToRoot,
$node->getName()
);
}
protected function getPathToRoot(PHP_CodeCoverage_Report_Node $node)
{
$id = $node->getId();
$depth = substr_count($id, '/');
if ($id != 'index' &&
$node instanceof PHP_CodeCoverage_Report_Node_Directory) {
$depth++;
}
return str_repeat('../', $depth);
}
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';
} elseif ($percent >= $this->lowUpperBound &&
$percent < $this->highLowerBound) {
return 'warning';
} else {
return 'success';
}
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Zsolt Takács <zsolt@takacs.cc>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Zsolt Takács <zsolt@takacs.cc>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_Crap4j
{
private $threshold = 30;
/**
* @param PHP_CodeCoverage $coverage
* @param string $target
* @param string $name
* @return string
*/
public function process(PHP_CodeCoverage $coverage, $target = null, $name = null)
{
$document = new DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true;
$root = $document->createElement('crap_result');
$document->appendChild($root);
$project = $document->createElement('project', is_string($name) ? $name : '');
$root->appendChild($project);
$root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
$stats = $document->createElement('stats');
$methodsNode = $document->createElement('methods');
$report = $coverage->getReport();
unset($coverage);
$fullMethodCount = 0;
$fullCrapMethodCount = 0;
$fullCrapLoad = 0;
$fullCrap = 0;
foreach ($report as $item) {
if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
continue;
}
$file = $document->createElement('file');
$file->setAttribute('name', $item->getPath());
$classes = $item->getClassesAndTraits();
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
$crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']);
$fullCrap += $method['crap'];
$fullCrapLoad += $crapLoad;
$fullMethodCount++;
if ($method['crap'] >= $this->threshold) {
$fullCrapMethodCount++;
}
$methodNode = $document->createElement('method');
$methodNode->appendChild($document->createElement('package', ''));
$methodNode->appendChild($document->createElement('className', $className));
$methodNode->appendChild($document->createElement('methodName', $methodName));
$methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
$methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
$methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap'])));
$methodNode->appendChild($document->createElement('complexity', $method['ccn']));
$methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage'])));
$methodNode->appendChild($document->createElement('crapLoad', round($crapLoad)));
$methodsNode->appendChild($methodNode);
}
}
}
$stats->appendChild($document->createElement('name', 'Method Crap Stats'));
$stats->appendChild($document->createElement('methodCount', $fullMethodCount));
$stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount));
$stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad)));
$stats->appendChild($document->createElement('totalCrap', $fullCrap));
$stats->appendChild($document->createElement('crapMethodPercent', $this->roundValue(100 * $fullCrapMethodCount / $fullMethodCount)));
$root->appendChild($stats);
$root->appendChild($methodsNode);
if ($target !== null) {
if (!is_dir(dirname($target))) {
mkdir(dirname($target), 0777, true);
}
return $document->save($target);
} else {
return $document->saveXML();
}
}
private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent)
{
$crapLoad = 0;
if ($crapValue > $this->threshold) {
$crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
$crapLoad += $cyclomaticComplexity / $this->threshold;
}
return $crapLoad;
}
private function roundValue($value)
{
return round($value, 2);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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 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->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;
}
/**
* 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->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) {
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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
*/
private 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
*/
private 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
*/
private 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] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
}
$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
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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->parent->getPath() === 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_File
{
/**
* @var DOMDocument
*/
protected $dom;
/**
* @var DOMElement
*/
protected $contextNode;
public function __construct(DOMElement $context)
{
$this->dom = $context->ownerDocument;
$this->contextNode = $context;
}
public function getTotals()
{
$totalsContainer = $this->contextNode->firstChild;
if (!$totalsContainer) {
$totalsContainer = $this->contextNode->appendChild(
$this->dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'totals'
)
);
}
return new PHP_CodeCoverage_Report_XML_Totals($totalsContainer);
}
public function getLineCoverage($line)
{
$coverage = $this->contextNode->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0', 'coverage'
)->item(0);
if (!$coverage) {
$coverage = $this->contextNode->appendChild(
$this->dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'coverage'
)
);
}
$lineNode = $coverage->appendChild(
$this->dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'line'
)
);
return new PHP_CodeCoverage_Report_XML_File_Coverage($lineNode, $line);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_File_Report extends PHP_CodeCoverage_Report_XML_File
{
public function __construct($name)
{
$this->dom = new DOMDocument;
$this->dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
$this->contextNode = $this->dom->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0', 'file'
)->item(0);
$this->setName($name);
}
private function setName($name)
{
$this->contextNode->setAttribute('name', $name);
}
public function asDom()
{
return $this->dom;
}
public function getFunctionObject($name)
{
$node = $this->contextNode->appendChild(
$this->dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'function'
)
);
return new PHP_CodeCoverage_Report_XML_File_Method($node, $name);
}
public function getClassObject($name)
{
return $this->getUnitObject('class', $name);
}
public function getTraitObject($name)
{
return $this->getUnitObject('trait', $name);
}
private function getUnitObject($tagName, $name)
{
$node = $this->contextNode->appendChild(
$this->dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', $tagName
)
);
return new PHP_CodeCoverage_Report_XML_File_Unit($node, $name);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_File_Unit
{
/**
* @var DOMElement
*/
private $contextNode;
public function __construct(DOMElement $context, $name)
{
$this->contextNode = $context;
$this->setName($name);
}
private function setName($name)
{
$this->contextNode->setAttribute('name', $name);
}
public function setLines($start, $executable, $executed)
{
$this->contextNode->setAttribute('start', $start);
$this->contextNode->setAttribute('executable', $executable);
$this->contextNode->setAttribute('executed', $executed);
}
public function setCrap($crap)
{
$this->contextNode->setAttribute('crap', $crap);
}
public function setPackage($full, $package, $sub, $category)
{
$node = $this->contextNode->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0', 'package'
)->item(0);
if (!$node) {
$node = $this->contextNode->appendChild(
$this->contextNode->ownerDocument->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'package'
)
);
}
$node->setAttribute('full', $full);
$node->setAttribute('name', $package);
$node->setAttribute('sub', $sub);
$node->setAttribute('category', $category);
}
public function setNamespace($namespace)
{
$node = $this->contextNode->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0', 'namespace'
)->item(0);
if (!$node) {
$node = $this->contextNode->appendChild(
$this->contextNode->ownerDocument->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'namespace'
)
);
}
$node->setAttribute('name', $namespace);
}
public function addMethod($name)
{
$node = $this->contextNode->appendChild(
$this->contextNode->ownerDocument->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'method'
)
);
return new PHP_CodeCoverage_Report_XML_File_Method($node, $name);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_File_Coverage
{
/**
* @var XMLWriter
*/
private $writer;
/**
* @var DOMElement
*/
private $contextNode;
/**
* @var bool
*/
private $finalized = false;
public function __construct(DOMElement $context, $line)
{
$this->contextNode = $context;
$this->writer = new XMLWriter();
$this->writer->openMemory();
$this->writer->startElementNs(null, $context->nodeName, 'http://schema.phpunit.de/coverage/1.0');
$this->writer->writeAttribute('nr', $line);
}
public function addTest($test)
{
if ($this->finalized) {
throw new PHP_CodeCoverage_Exception('Coverage Report already finalized');
}
$this->writer->startElement('covered');
$this->writer->writeAttribute('by', $test);
$this->writer->endElement();
}
public function finalize()
{
$this->writer->endElement();
$fragment = $this->contextNode->ownerDocument->createDocumentFragment();
$fragment->appendXML($this->writer->outputMemory());
$this->contextNode->parentNode->replaceChild(
$fragment,
$this->contextNode
);
$this->finalized = true;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_File_Method
{
/**
* @var DOMElement
*/
private $contextNode;
public function __construct(DOMElement $context, $name)
{
$this->contextNode = $context;
$this->setName($name);
}
private function setName($name)
{
$this->contextNode->setAttribute('name', $name);
}
public function setSignature($signature)
{
$this->contextNode->setAttribute('signature', $signature);
}
public function setLines($start, $end = null)
{
$this->contextNode->setAttribute('start', $start);
if ($end !== null) {
$this->contextNode->setAttribute('end', $end);
}
}
public function setTotals($executable, $executed, $coverage)
{
$this->contextNode->setAttribute('executable', $executable);
$this->contextNode->setAttribute('executed', $executed);
$this->contextNode->setAttribute('coverage', $coverage);
}
public function setCrap($crap)
{
$this->contextNode->setAttribute('crap', $crap);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_Directory extends PHP_CodeCoverage_Report_XML_Node
{
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_Tests
{
private $contextNode;
private $codeMap = array(
0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
5 => 'RISKY' // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
);
public function __construct(DOMElement $context)
{
$this->contextNode = $context;
}
public function addTest($test, $result)
{
$node = $this->contextNode->appendChild(
$this->contextNode->ownerDocument->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'test'
)
);
$node->setAttribute('name', $test);
$node->setAttribute('result', (int) $result);
$node->setAttribute('status', $this->codeMap[(int) $result]);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_Node
{
/**
* @var DOMDocument
*/
private $dom;
/**
* @var DOMElement
*/
private $contextNode;
public function __construct(DOMElement $context)
{
$this->setContextNode($context);
}
protected function setContextNode(DOMElement $context)
{
$this->dom = $context->ownerDocument;
$this->contextNode = $context;
}
public function getDom()
{
return $this->dom;
}
protected function getContextNode()
{
return $this->contextNode;
}
public function getTotals()
{
$totalsContainer = $this->getContextNode()->firstChild;
if (!$totalsContainer) {
$totalsContainer = $this->getContextNode()->appendChild(
$this->dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'totals'
)
);
}
return new PHP_CodeCoverage_Report_XML_Totals($totalsContainer);
}
public function addDirectory($name)
{
$dirNode = $this->getDom()->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'directory'
);
$dirNode->setAttribute('name', $name);
$this->getContextNode()->appendChild($dirNode);
return new PHP_CodeCoverage_Report_XML_Directory($dirNode);
}
public function addFile($name, $href)
{
$fileNode = $this->getDom()->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'file'
);
$fileNode->setAttribute('name', $name);
$fileNode->setAttribute('href', $href);
$this->getContextNode()->appendChild($fileNode);
return new PHP_CodeCoverage_Report_XML_File($fileNode);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_Totals
{
/**
* @var DOMNode
*/
private $container;
/**
* @var DOMElement
*/
private $linesNode;
/**
* @var DOMElement
*/
private $methodsNode;
/**
* @var DOMElement
*/
private $functionsNode;
/**
* @var DOMElement
*/
private $classesNode;
/**
* @var DOMElement
*/
private $traitsNode;
public function __construct(DOMElement $container)
{
$this->container = $container;
$dom = $container->ownerDocument;
$this->linesNode = $dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'lines')
;
$this->methodsNode = $dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'methods'
);
$this->functionsNode = $dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'functions'
);
$this->classesNode = $dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'classes'
);
$this->traitsNode = $dom->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'traits'
);
$container->appendChild($this->linesNode);
$container->appendChild($this->methodsNode);
$container->appendChild($this->functionsNode);
$container->appendChild($this->classesNode);
$container->appendChild($this->traitsNode);
}
public function getContainer()
{
return $this->container;
}
public function setNumLines($loc, $cloc, $ncloc, $executable, $executed)
{
$this->linesNode->setAttribute('total', $loc);
$this->linesNode->setAttribute('comments', $cloc);
$this->linesNode->setAttribute('code', $ncloc);
$this->linesNode->setAttribute('executable', $executable);
$this->linesNode->setAttribute('executed', $executed);
$this->linesNode->setAttribute(
'percent', PHP_CodeCoverage_Util::percent($executed,$executable, true)
);
}
public function setNumClasses($count, $tested)
{
$this->classesNode->setAttribute('count', $count);
$this->classesNode->setAttribute('tested', $tested);
$this->classesNode->setAttribute(
'percent', PHP_CodeCoverage_Util::percent($tested,$count, true)
);
}
public function setNumTraits($count, $tested)
{
$this->traitsNode->setAttribute('count', $count);
$this->traitsNode->setAttribute('tested', $tested);
$this->traitsNode->setAttribute(
'percent', PHP_CodeCoverage_Util::percent($tested,$count, true)
);
}
public function setNumMethods($count, $tested)
{
$this->methodsNode->setAttribute('count', $count);
$this->methodsNode->setAttribute('tested', $tested);
$this->methodsNode->setAttribute(
'percent', PHP_CodeCoverage_Util::percent($tested,$count, true)
);
}
public function setNumFunctions($count, $tested)
{
$this->functionsNode->setAttribute('count', $count);
$this->functionsNode->setAttribute('tested', $tested);
$this->functionsNode->setAttribute(
'percent', PHP_CodeCoverage_Util::percent($tested,$count, true)
);
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
/**
* @category PHP
* @package CodeCoverage
* @author Arne Blankerts <arne@blankerts.de>
* @copyright 2009-2014 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 2.0.0
*/
class PHP_CodeCoverage_Report_XML_Project extends PHP_CodeCoverage_Report_XML_Node
{
public function __construct($name)
{
$this->init();
$this->setProjectName($name);
}
private function init()
{
$dom = new DOMDocument;
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><project/></phpunit>');
$this->setContextNode(
$dom->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0', 'project'
)->item(0)
);
}
private function setProjectName($name)
{
$this->getContextNode()->setAttribute('name', $name);
}
public function getTests()
{
$testsNode = $this->getContextNode()->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0', 'tests'
)->item(0);
if (!$testsNode) {
$testsNode = $this->getContextNode()->appendChild(
$this->getDom()->createElementNS(
'http://schema.phpunit.de/coverage/1.0', 'tests'
)
);
}
return new PHP_CodeCoverage_Report_XML_Tests($testsNode);
}
public function asDom()
{
return $this->getDom();
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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
*/
private $templatePath;
/**
* @var string
*/
private $generator;
/**
* @var integer
*/
private $lowUpperBound;
/**
* @var integer
*/
private $highLowerBound;
/**
* Constructor.
*
* @param integer $lowUpperBound
* @param integer $highLowerBound
* @param string $generator
*/
public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '')
{
$this->generator = $generator;
$this->highLowerBound = $highLowerBound;
$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->generator,
$date,
$this->lowUpperBound,
$this->highLowerBound
);
$directory = new PHP_CodeCoverage_Report_HTML_Renderer_Directory(
$this->templatePath,
$this->generator,
$date,
$this->lowUpperBound,
$this->highLowerBound
);
$file = new PHP_CodeCoverage_Report_HTML_Renderer_File(
$this->templatePath,
$this->generator,
$date,
$this->lowUpperBound,
$this->highLowerBound
);
$directory->render($report, $target . 'index.html');
$dashboard->render($report, $target . 'dashboard.html');
foreach ($report as $node) {
$id = $node->getId();
if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
if (!file_exists($target . $id)) {
mkdir($target . $id, 0777, true);
}
$directory->render($node, $target . $id . '/index.html');
$dashboard->render($node, $target . $id . '/dashboard.html');
} else {
$dir = dirname($target . $id);
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
$file->render($node, $target . $id . '.html');
}
}
$this->copyFiles($target);
}
/**
* @param string $target
*/
private function copyFiles($target)
{
$dir = $this->getDirectory($target . 'css');
copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
copy($this->templatePath . 'css/nv.d3.css', $dir . 'nv.d3.css');
copy($this->templatePath . 'css/style.css', $dir . 'style.css');
$dir = $this->getDirectory($target . 'fonts');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff');
$dir = $this->getDirectory($target . 'js');
copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
copy($this->templatePath . 'js/holder.js', $dir . 'holder.js');
copy($this->templatePath . 'js/html5shiv.js', $dir . 'html5shiv.js');
copy($this->templatePath . 'js/jquery.js', $dir . 'jquery.js');
copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
copy($this->templatePath . 'js/respond.min.js', $dir . 'respond.min.js');
}
/**
* @param string $directory
* @return string
* @throws PHP_CodeCoverage_Exception
* @since Method available since Release 1.2.0
*/
private 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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 $lowUpperBound;
protected $highLowerBound;
protected $showUncoveredFiles;
protected $showOnlySummary;
protected $colors = array(
'green' => "\x1b[30;42m",
'yellow' => "\x1b[30;43m",
'red' => "\x1b[37;41m",
'header' => "\x1b[1;37;40m",
'reset' => "\x1b[0m",
'eol' => "\x1b[2K",
);
public function __construct($lowUpperBound, $highLowerBound, $showUncoveredFiles, $showOnlySummary)
{
$this->lowUpperBound = $lowUpperBound;
$this->highLowerBound = $highLowerBound;
$this->showUncoveredFiles = $showUncoveredFiles;
$this->showOnlySummary = $showOnlySummary;
}
/**
* @param PHP_CodeCoverage $coverage
* @param bool $showColors
* @return string
*/
public function process(PHP_CodeCoverage $coverage, $showColors = false)
{
$output = PHP_EOL . PHP_EOL;
$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'];
}
$classes = sprintf(
' Classes: %6s (%d/%d)',
PHP_CodeCoverage_Util::percent(
$report->getNumTestedClassesAndTraits(),
$report->getNumClassesAndTraits(),
true
),
$report->getNumTestedClassesAndTraits(),
$report->getNumClassesAndTraits()
);
$methods = sprintf(
' Methods: %6s (%d/%d)',
PHP_CodeCoverage_Util::percent(
$report->getNumTestedMethods(),
$report->getNumMethods(),
true
),
$report->getNumTestedMethods(),
$report->getNumMethods()
);
$lines = sprintf(
' Lines: %6s (%d/%d)',
PHP_CodeCoverage_Util::percent(
$report->getNumExecutedLines(),
$report->getNumExecutableLines(),
true
),
$report->getNumExecutedLines(),
$report->getNumExecutableLines()
);
$padding = max(array_map('strlen', array($classes, $methods, $lines)));
if ($this->showOnlySummary) {
$title = 'Code Coverage Report Summary:';
$padding = max($padding, strlen($title));
$output .= $this->format($colors['header'], $padding, $title);
} else {
$date = date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
$title = 'Code Coverage Report:';
$output .= $this->format($colors['header'], $padding, $title);
$output .= $this->format($colors['header'], $padding, $date);
$output .= $this->format($colors['header'], $padding, '');
$output .= $this->format($colors['header'], $padding, ' Summary:');
}
$output .= $this->format($colors['classes'], $padding, $classes);
$output .= $this->format($colors['methods'], $padding, $methods);
$output .= $this->format($colors['lines'], $padding, $lines);
if ($this->showOnlySummary) {
return $output . PHP_EOL;
}
$classCoverage = array();
foreach ($report as $item) {
if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
continue;
}
$classes = $item->getClassesAndTraits();
foreach ($classes as $className => $class) {
$classStatements = 0;
$coveredClassStatements = 0;
$coveredMethods = 0;
$classMethods = 0;
foreach ($class['methods'] as $method) {
if ($method['executableLines'] == 0)
continue;
$classMethods++;
$classStatements += $method['executableLines'];
$coveredClassStatements += $method['executedLines'];
if ($method['coverage'] == 100) {
$coveredMethods++;
}
}
if (!empty($class['package']['namespace'])) {
$namespace = '\\' . $class['package']['namespace'] . '::';
} elseif (!empty($class['package']['fullPackage'])) {
$namespace = '@' . $class['package']['fullPackage'] . '::';
} else {
$namespace = '';
}
$classCoverage[$namespace . $className] = array(
'namespace' => $namespace,
'className ' => $className,
'methodsCovered' => $coveredMethods,
'methodCount' => $classMethods,
'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
;
}
}
return $output . PHP_EOL;
}
protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
{
$coverage = PHP_CodeCoverage_Util::percent(
$numberOfCoveredElements, $totalNumberOfElements
);
if ($coverage > $this->highLowerBound) {
return $this->colors['green'];
} elseif ($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) . ')';
}
private function format($color, $padding, $string)
{
$reset = $color ? $this->colors['reset'] : '';
return $color . str_pad($string, $padding) . $reset . PHP_EOL;
}
}
<?php
/**
* PHP_CodeCoverage
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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();
foreach ($classes as $className => $class) {
$classStatements = 0;
$coveredClassStatements = 0;
$coveredMethods = 0;
$classMethods = 0;
foreach ($class['methods'] as $methodName => $method) {
if ($method['executableLines'] == 0) {
continue;
}
$classMethods++;
$classStatements += $method['executableLines'];
$coveredClassStatements += $method['executedLines'];
if ($method['coverage'] == 100) {
$coveredMethods++;
}
$methodCount = 0;
for ($i = $method['startLine'];
$i <= $method['endLine'];
$i++) {
if (isset($coverage[$i]) && ($coverage[$i] !== null)) {
$methodCount = max($methodCount, count($coverage[$i]));
}
}
$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', $classMethods);
$xmlMetrics->setAttribute('coveredmethods', $coveredMethods);
$xmlMetrics->setAttribute('conditionals', 0);
$xmlMetrics->setAttribute('coveredconditionals', 0);
$xmlMetrics->setAttribute('statements', $classStatements);
$xmlMetrics->setAttribute(
'coveredstatements',
$coveredClassStatements
);
$xmlMetrics->setAttribute(
'elements',
$classMethods +
$classStatements
/* + conditionals */
);
$xmlMetrics->setAttribute(
'coveredelements',
$coveredMethods +
$coveredClassStatements
/* + coveredconditionals */
);
$xmlClass->appendChild($xmlMetrics);
}
foreach ($coverage as $line => $data) {
if ($data === null || isset($lines[$line])) {
continue;
}
$lines[$line] = array(
'count' => count($data), 'type' => 'stmt'
);
}
ksort($lines);
foreach ($lines as $line => $data) {
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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-2014 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 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
*/
use SebastianBergmann\Environment\Runtime;
/**
* Provides collection functionality for PHP code coverage information.
*
* @category PHP
* @package CodeCoverage
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2014 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
*/
private $driver;
/**
* @var PHP_CodeCoverage_Filter
*/
private $filter;
/**
* @var boolean
*/
private $cacheTokens = false;
/**
* @var boolean
*/
private $checkForUnintentionallyCoveredCode = false;
/**
* @var boolean
*/
private $forceCoversAnnotation = false;
/**
* @var boolean
*/
private $mapTestClassNameToCoveredClassName = false;
/**
* @var boolean
*/
private $addUncoveredFilesFromWhitelist = true;
/**
* @var boolean
*/
private $processUncoveredFilesFromWhitelist = false;
/**
* @var mixed
*/
private $currentId;
/**
* Code coverage data.
*
* @var array
*/
private $data = array();
/**
* @var array
*/
private $ignoredLines = array();
/**
* Test data.
*
* @var array
*/
private $tests = array();
/**
* Constructor.
*
* @param PHP_CodeCoverage_Driver $driver
* @param PHP_CodeCoverage_Filter $filter
* @throws PHP_CodeCoverage_Exception
*/
public function __construct(PHP_CodeCoverage_Driver $driver = null, PHP_CodeCoverage_Filter $filter = null)
{
if ($driver === null) {
$runtime = new Runtime;
if ($runtime->isHHVM()) {
$driver = new PHP_CodeCoverage_Driver_HHVM;
} elseif ($runtime->hasXdebug()) {
$driver = new PHP_CodeCoverage_Driver_Xdebug;
} else {
throw new PHP_CodeCoverage_Exception('No code coverage driver available');
}
}
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.
* Set $raw = true to bypass all filters.
*
* @param bool $raw
* @return array
* @since Method available since Release 1.1.0
*/
public function getData($raw = false)
{
if (!$raw && $this->addUncoveredFilesFromWhitelist) {
$this->addUncoveredFilesFromWhitelist();
}
// We need to apply the blacklist filter a second time
// when no whitelist is used.
if (!$raw && !$this->filter->hasWhitelist()) {
$this->applyListsFilter($this->data);
}
return $this->data;
}
/**
* Sets the coverage data.
*
* @param array $data
* @since Method available since Release 2.0.0
*/
public function setData(array $data)
{
$this->data = $data;
}
/**
* Returns the test data.
*
* @return array
* @since Method available since Release 1.1.0
*/
public function getTests()
{
return $this->tests;
}
/**
* Sets the test data.
*
* @param array $tests
* @since Method available since Release 2.0.0
*/
public function setTests(array $tests)
{
$this->tests = $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
* @param mixed $linesToBeCovered
* @param array $linesToBeUsed
* @return array
* @throws PHP_CodeCoverage_Exception
*/
public function stop($append = true, $linesToBeCovered = array(), array $linesToBeUsed = array())
{
if (!is_bool($append)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1,
'boolean'
);
}
if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
2,
'array or false'
);
}
$data = $this->driver->stop();
$this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
$this->currentId = null;
return $data;
}
/**
* Appends code coverage data.
*
* @param array $data
* @param mixed $id
* @param boolean $append
* @param mixed $linesToBeCovered
* @param array $linesToBeUsed
* @throws PHP_CodeCoverage_Exception
*/
public function append(array $data, $id = null, $append = true, $linesToBeCovered = array(), array $linesToBeUsed = array())
{
if ($id === null) {
$id = $this->currentId;
}
if ($id === null) {
throw new PHP_CodeCoverage_Exception;
}
$this->applyListsFilter($data);
$this->applyIgnoredLinesFilter($data);
$this->initializeFilesThatAreSeenTheFirstTime($data);
if (!$append) {
return;
}
if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
$this->applyCoversAnnotationFilter(
$data,
$linesToBeCovered,
$linesToBeUsed
);
}
if (empty($data)) {
return;
}
$status = null;
if ($id instanceof PHPUnit_Framework_TestCase) {
$status = $id->getStatus();
$id = get_class($id) . '::' . $id->getName();
} elseif ($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;
}
/**
* @since Method available since Release 1.1.0
*/
public function getCacheTokens()
{
return $this->cacheTokens;
}
/**
* @param boolean $flag
* @throws PHP_CodeCoverage_Exception
* @since Method available since Release 2.0.0
*/
public function setCheckForUnintentionallyCoveredCode($flag)
{
if (!is_bool($flag)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1,
'boolean'
);
}
$this->checkForUnintentionallyCoveredCode = $flag;
}
/**
* @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 $linesToBeCovered
* @param array $linesToBeUsed
* @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode
*/
private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed)
{
if ($linesToBeCovered === false ||
($this->forceCoversAnnotation && empty($linesToBeCovered))) {
$data = array();
return;
}
if (empty($linesToBeCovered)) {
return;
}
if ($this->checkForUnintentionallyCoveredCode) {
$this->performUnintentionallyCoveredCodeCheck(
$data,
$linesToBeCovered,
$linesToBeUsed
);
}
$data = array_intersect_key($data, $linesToBeCovered);
foreach (array_keys($data) as $filename) {
$_linesToBeCovered = array_flip($linesToBeCovered[$filename]);
$data[$filename] = array_intersect_key(
$data[$filename],
$_linesToBeCovered
);
}
}
/**
* Applies the blacklist/whitelist filtering.
*
* @param array $data
*/
private function applyListsFilter(array &$data)
{
foreach (array_keys($data) as $filename) {
if ($this->filter->isFiltered($filename)) {
unset($data[$filename]);
}
}
}
/**
* Applies the "ignored lines" filtering.
*
* @param array $data
*/
private function applyIgnoredLinesFilter(array &$data)
{
foreach (array_keys($data) as $filename) {
if (!$this->filter->isFile($filename)) {
continue;
}
foreach ($this->getLinesToBeIgnored($filename) as $line) {
unset($data[$filename][$line]);
}
if (empty($data[$filename])) {
unset($data[$filename]);
}
}
}
/**
* @param array $data
* @since Method available since Release 1.1.0
*/
private function initializeFilesThatAreSeenTheFirstTime(array $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.
*/
private 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
*/
private 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 lines of a source file that should be ignored.
*
* @param string $filename
* @return array
* @throws PHP_CodeCoverage_Exception
* @since Method available since Release 2.0.0
*/
private function getLinesToBeIgnored($filename)
{
if (!is_string($filename)) {
throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
1,
'string'
);
}
if (!isset($this->ignoredLines[$filename])) {
$this->ignoredLines[$filename] = array();
$ignore = false;
$stop = false;
$lines = file($filename);
$numLines = count($lines);
foreach ($lines as $index => $line) {
if (!trim($line)) {
$this->ignoredLines[$filename][] = $index + 1;
}
}
if ($this->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;
} elseif ($_token == '// @codeCoverageIgnoreStart' ||
$_token == '//@codeCoverageIgnoreStart') {
$ignore = true;
} elseif ($_token == '// @codeCoverageIgnoreEnd' ||
$_token == '//@codeCoverageIgnoreEnd') {
$stop = true;
}
// Do not ignore the whole line when there is a token
// before the comment on the same line
if (0 === strpos($_token, $_line)) {
$count = substr_count($token, "\n");
$line = $token->getLine();
for ($i = $line; $i < $line + $count; $i++) {
$this->ignoredLines[$filename][] = $i;
}
if ($token instanceof PHP_Token_DOC_COMMENT) {
// The DOC_COMMENT token does not contain the
// final \n character in its text
if (substr(trim($lines[$i-1]), -2) == '*/') {
$this->ignoredLines[$filename][] = $i;
}
}
}
break;
case 'PHP_Token_INTERFACE':
case 'PHP_Token_TRAIT':
case 'PHP_Token_CLASS':
case 'PHP_Token_FUNCTION':
$docblock = $token->getDocblock();
$this->ignoredLines[$filename][] = $token->getLine();
if (strpos($docblock, '@codeCoverageIgnore')) {
$endLine = $token->getEndLine();
for ($i = $token->getLine(); $i <= $endLine; $i++) {
$this->ignoredLines[$filename][] = $i;
}
} elseif ($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++) {
$this->ignoredLines[$filename][] = $i;
}
} 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++) {
$this->ignoredLines[$filename][] = $i;
}
for ($i = $token->getEndLine();
$i > $lastMethod['endLine'];
$i--) {
$this->ignoredLines[$filename][] = $i;
}
}
}
break;
case 'PHP_Token_NAMESPACE':
$this->ignoredLines[$filename][] = $token->getEndLine();
// Intentional fallthrough
case 'PHP_Token_OPEN_TAG':
case 'PHP_Token_CLOSE_TAG':
case 'PHP_Token_USE':
$this->ignoredLines[$filename][] = $token->getLine();
break;
}
if ($ignore) {
$this->ignoredLines[$filename][] = $token->getLine();
if ($stop) {
$ignore = false;
$stop = false;
}
}
}
$this->ignoredLines[$filename][] = $numLines + 1;
$this->ignoredLines[$filename] = array_unique(
$this->ignoredLines[$filename]
);
sort($this->ignoredLines[$filename]);
}
return $this->ignoredLines[$filename];
}
/**
* @param array $data
* @param array $linesToBeCovered
* @param array $linesToBeUsed
* @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode
* @since Method available since Release 2.0.0
*/
private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
{
$allowedLines = $this->getAllowedLines(
$linesToBeCovered,
$linesToBeUsed
);
$message = '';
foreach ($data as $file => $_data) {
foreach ($_data as $line => $flag) {
if ($flag == 1 &&
(!isset($allowedLines[$file]) ||
!isset($allowedLines[$file][$line]))) {
$message .= sprintf(
'- %s:%d' . PHP_EOL,
$file,
$line
);
}
}
}
if (!empty($message)) {
throw new PHP_CodeCoverage_Exception_UnintentionallyCoveredCode(
$message
);
}
}
/**
* @param array $linesToBeCovered
* @param array $linesToBeUsed
* @return array
* @since Method available since Release 2.0.0
*/
private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed)
{
$allowedLines = array();
foreach (array_keys($linesToBeCovered) as $file) {
if (!isset($allowedLines[$file])) {
$allowedLines[$file] = array();
}
$allowedLines[$file] = array_merge(
$allowedLines[$file],
$linesToBeCovered[$file]
);
}
foreach (array_keys($linesToBeUsed) as $file) {
if (!isset($allowedLines[$file])) {
$allowedLines[$file] = array();
}
$allowedLines[$file] = array_merge(
$allowedLines[$file],
$linesToBeUsed[$file]
);
}
foreach (array_keys($allowedLines) as $file) {
$allowedLines[$file] = array_flip(
array_unique($allowedLines[$file])
);
}
return $allowedLines;
}
}
<?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
{
/**
* 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
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
*
* @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;
$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 int $inline The level where you switch to inline YAML
* @param int $indent The amount of spaces to use for indentation of nested nodes.
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $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;
/**
* 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 bool 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 bool 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));
}
}
<?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
{
const FOLDED_SCALAR_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
private $offset = 0;
private $lines = array();
private $currentLineNb = -1;
private $currentLine = '';
private $refs = array();
/**
* Constructor
*
* @param int $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 bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $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 (!preg_match('//u', $value)) {
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) && false === strpos($values['key'],' #')) {
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 int The current line number
*/
private function getRealCurrentLineNb()
{
return $this->currentLineNb + $this->offset;
}
/**
* Returns the current line indentation.
*
* @return int The current line indentation
*/
private function getCurrentLineIndentation()
{
return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
}
/**
* Returns the next embed block of YAML.
*
* @param int $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);
// Comments must not be removed inside a string block (ie. after a line ending with "|")
$removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~';
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
while ($this->moveToNextLine()) {
$indent = $this->getCurrentLineIndentation();
if ($indent === $newIndent) {
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
}
if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem($this->currentLine)) {
$this->moveToPreviousLine();
break;
}
if ($this->isCurrentLineBlank()) {
$data[] = substr($this->currentLine, $newIndent);
continue;
}
if ($removeComments && $this->isCurrentLineComment()) {
continue;
}
if ($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 bool
*/
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
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
*
* @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('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $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 int $indentation The indentation that was used to begin this folded scalar
*
* @return string The text value
*/
private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
{
$notEOF = $this->moveToNextLine();
if (!$notEOF) {
return '';
}
$isCurrentLineBlank = $this->isCurrentLineBlank();
$text = '';
// leading blank lines are consumed before determining indentation
while ($notEOF && $isCurrentLineBlank) {
// newline only if not EOF
if ($notEOF = $this->moveToNextLine()) {
$text .= "\n";
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
// determine indentation if not specified
if (0 === $indentation) {
if (preg_match('/^ +/', $this->currentLine, $matches)) {
$indentation = strlen($matches[0]);
}
}
if ($indentation > 0) {
$pattern = sprintf('/^ {%d}(.*)$/', $indentation);
while (
$notEOF && (
$isCurrentLineBlank ||
preg_match($pattern, $this->currentLine, $matches)
)
) {
if ($isCurrentLineBlank) {
$text .= substr($this->currentLine, $indentation);
} else {
$text .= $matches[1];
}
// newline only if not EOF
if ($notEOF = $this->moveToNextLine()) {
$text .= "\n";
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
} elseif ($notEOF) {
$text .= "\n";
}
if ($notEOF) {
$this->moveToPreviousLine();
}
// replace all non-trailing single newlines with spaces in folded blocks
if ('>' === $separator) {
preg_match('/(\n*)$/', $text, $matches);
$text = preg_replace('/(?<!\n)\n(?!\n)/', ' ', rtrim($text, "\n"));
$text .= $matches[1];
}
// deal with trailing newlines as indicated
if ('' === $indicator) {
$text = preg_replace('/\n+$/s', "\n", $text);
} elseif ('-' === $indicator) {
$text = preg_replace('/\n+$/s', '', $text);
}
return $text;
}
/**
* Returns true if the next line is indented.
*
* @return bool Returns true if the next line is indented, false otherwise
*/
private function isNextLineIndented()
{
$currentIndentation = $this->getCurrentLineIndentation();
$EOF = !$this->moveToNextLine();
while (!$EOF && $this->isCurrentLineEmpty()) {
$EOF = !$this->moveToNextLine();
}
if ($EOF) {
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 bool 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 bool 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 bool 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 bool 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 bool 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;
/**
* 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 int
*/
protected $indentation = 4;
/**
* Sets the indentation.
*
* @param int $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 int $inline The level where you switch to inline YAML
* @param int $indent The level of indentation (used internally)
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $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
/*
* 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.
// @deprecated since 2.5, to be removed in 3.0
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 "\r";
case 'e':
return "\x1B";
case ' ':
return ' ';
case '"':
return '"';
case '/':
return '/';
case '\\':
return '\\';
case 'N':
// U+0085 NEXT LINE
return "\xC2\x85";
case '_':
// U+00A0 NO-BREAK SPACE
return "\xC2\xA0";
case 'L':
// U+2028 LINE SEPARATOR
return "\xE2\x80\xA8";
case 'P':
// U+2029 PARAGRAPH SEPARATOR
return "\xE2\x80\xA9";
case 'x':
return self::utf8chr(hexdec(substr($value, 2, 2)));
case 'u':
return self::utf8chr(hexdec(substr($value, 2, 4)));
case 'U':
return self::utf8chr(hexdec(substr($value, 2, 8)));
}
}
/**
* Get the UTF-8 character for the given code point.
*
* @param int $c The unicode code point
*
* @return string The corresponding UTF-8 character
*/
private static function utf8chr($c)
{
if (0x80 > $c %= 0x200000) {
return chr($c);
}
if (0x800 > $c) {
return chr(0xC0 | $c>>6).chr(0x80 | $c & 0x3F);
}
if (0x10000 > $c) {
return chr(0xE0 | $c>>12).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
}
return chr(0xF0 | $c>>18).chr(0x80 | $c>>12 & 0x3F).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
}
}
<?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\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;
if (!defined('JSON_UNESCAPED_UNICODE')) {
define('JSON_UNESCAPED_SLASHES', 64);
define('JSON_UNESCAPED_UNICODE', 256);
}
/**
* 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 int $parsedLine The line where the error occurred
* @param int $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 int The file line
*/
public function getParsedLine()
{
return $this->parsedLine;
}
/**
* Sets the line where the error occurred.
*
* @param int $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, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
}
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 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;
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 bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $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 bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $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 bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $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 (int) $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 int &$i
* @param bool $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));
}
if ($evaluate) {
$output = self::evaluateScalar($output);
}
}
return $output;
}
/**
* Parses a quoted scalar to YAML.
*
* @param string $scalar
* @param int &$i
*
* @return string A YAML string
*
* @throws ParseException When malformed inline YAML string is parsed
*/
private static function parseQuotedScalar($scalar, &$i)
{
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 int &$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 int &$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);
$scalarLower = strtolower($scalar);
switch (true) {
case 'null' === $scalarLower:
case '' === $scalar:
case '~' === $scalar:
return;
case 'true' === $scalarLower:
return true;
case 'false' === $scalarLower:
return false;
// Optimise for returning strings.
case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
switch (true) {
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;
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 is_numeric($scalar):
return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
case '.inf' === $scalarLower:
case '.nan' === $scalarLower:
return -log(0);
case '-.inf' === $scalarLower:
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
/**
* Exporter
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Exporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link https://github.com/sebastianbergmann/exporter
*/
namespace SebastianBergmann\Exporter;
/**
* A nifty utility for visualizing PHP variables.
*
* <code>
* <?php
* use SebastianBergmann\Exporter\Exporter;
*
* $exporter = new Exporter;
* print $exporter->export(new Exception);
* </code>
*
* @package Exporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link https://github.com/sebastianbergmann/exporter
*/
class Exporter
{
/**
* Exports a value as 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
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
*/
public function export($value, $indentation = 0)
{
return $this->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 SebastianBergmann\Exporter\Context $processed Contains all objects and arrays that have previously been rendered
* @return string
* @see SebastianBergmann\Exporter\Exporter::export
*/
protected function recursiveExport(&$value, $indentation, $processed = NULL)
{
if ($value === NULL) {
return 'null';
}
if ($value === TRUE) {
return 'true';
}
if ($value === FALSE) {
return 'false';
}
if (is_float($value) && floatval(intval($value)) === $value) {
return "$value.0";
}
if (is_resource($value)) {
return sprintf(
'resource(%d) of type (%s)',
$value,
get_resource_type($value)
);
}
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) .
"'";
}
$whitespace = str_repeat(' ', 4 * $indentation);
if (!$processed) {
$processed = new Context;
}
if (is_array($value)) {
if (($key = $processed->contains($value)) !== FALSE) {
return 'Array &' . $key;
}
$key = $processed->add($value);
$values = '';
if (count($value) > 0) {
foreach ($value as $k => $v) {
$values .= sprintf(
'%s %s => %s' . "\n",
$whitespace,
$this->recursiveExport($k, $indentation),
$this->recursiveExport($value[$k], $indentation + 1, $processed)
);
}
$values = "\n" . $values . $whitespace;
}
return sprintf('Array &%s (%s)', $key, $values);
}
if (is_object($value)) {
$class = get_class($value);
if ($hash = $processed->contains($value)) {
return sprintf('%s Object &%s', $class, $hash);
}
$hash = $processed->add($value);
$values = '';
$array = $this->toArray($value);
if (count($array) > 0) {
foreach ($array as $k => $v) {
$values .= sprintf(
'%s %s => %s' . "\n",
$whitespace,
$this->recursiveExport($k, $indentation),
$this->recursiveExport($v, $indentation + 1, $processed)
);
}
$values = "\n" . $values . $whitespace;
}
return sprintf('%s Object &%s (%s)', $class, $hash, $values);
}
return var_export($value, TRUE);
}
/**
* Exports a value into a single-line string
*
* The output of this method is similar to the output of
* SebastianBergmann\Exporter\Exporter::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
* @return string
* @see SebastianBergmann\Exporter\Exporter::export
*/
public function shortenedExport($value)
{
if (is_string($value)) {
$string = $this->export($value);
if (strlen($string) > 40) {
$string = substr($string, 0, 30) . '...' . substr($string, -7);
}
return str_replace("\n", '\n', $string);
}
if (is_object($value)) {
return sprintf(
'%s Object (%s)',
get_class($value),
count($this->toArray($value)) > 0 ? '...' : ''
);
}
if (is_array($value)) {
return sprintf(
'Array (%s)',
count($value) > 0 ? '...' : ''
);
}
return $this->export($value);
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param mixed $value
* @return array
*/
public function toArray($value)
{
if (!is_object($value)) {
return (array)$value;
}
$array = array();
foreach ((array)$value as $key => $val) {
// 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];
}
// See https://github.com/php/php-src/commit/5721132
if ($key === "\0gcdata") {
continue;
}
$array[$key] = $val;
}
// Some internal classes like SplObjectStorage don't work with the
// above (fast) mechanism nor with reflection in Zend.
// Format the output similarly to print_r() in this case
if ($value instanceof \SplObjectStorage) {
// However, the fast method does work in HHVM, and exposes the
// internal implementation. Hide it again.
if (property_exists('\SplObjectStorage', '__storage')) {
unset($array['__storage']);
} else if (property_exists('\SplObjectStorage', 'storage')) {
unset($array['storage']);
}
if (property_exists('\SplObjectStorage', '__key')) {
unset($array['__key']);
}
foreach ($value as $key => $val) {
$array[spl_object_hash($val)] = array(
'obj' => $val,
'inf' => $value->getInfo(),
);
}
}
return $array;
}
}
<?php
/**
* Exporter
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Exporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link https://github.com/sebastianbergmann/exporter
*/
namespace SebastianBergmann\Exporter;
/**
* Exception for Exporter runtime errors.
*
* @package Exporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link https://github.com/sebastianbergmann/exporter
*/
class Exception extends \RuntimeException
{
}
<?php
/**
* Exporter
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Exporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Adam Harvey <aharvey@php.net>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link https://github.com/sebastianbergmann/exporter
*/
namespace SebastianBergmann\Exporter;
/**
* A context containing previously rendered arrays and objects when recursively
* exporting a value.
*
* @package Exporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Adam Harvey <aharvey@php.net>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link https://github.com/sebastianbergmann/exporter
*/
class Context {
/**
* Previously seen arrays.
*
* @var array[] $arrays
*/
protected $arrays = array();
/**
* Previously seen objects.
*
* @var SplObjectStorage $objects
*/
protected $objects;
/** Initialises the context. */
public function __construct()
{
$this->arrays = array();
$this->objects = new \SplObjectStorage;
}
/**
* Adds a value to the export context.
*
* @param mixed $value The value to add.
* @return mixed The ID of the stored value, either as a string or integer.
* @throws SebastianBergmann\Exporter\Exception Thrown if $value is not an array or object.
*/
public function add(&$value)
{
if (is_array($value)) {
return $this->addArray($value);
}
else if (is_object($value)) {
return $this->addObject($value);
}
throw new ExporterException(
'Only arrays and objects are supported'
);
}
/**
* Checks if the given value exists within the context.
*
* @param mixed $value The value to check.
* @return mixed The string or integer ID of the stored value if it has
* already been seen, or boolean false if the value is not
* stored.
* @throws SebastianBergmann\Exporter\Exception Thrown if $value is not an array or object.
*/
public function contains(&$value)
{
if (is_array($value)) {
return $this->containsArray($value);
}
else if (is_object($value)) {
return $this->containsObject($value);
}
throw new Exception(
'Only arrays and objects are supported'
);
}
/**
* Stores an array within the context.
*
* @param array $value The value to store.
* @return integer The internal ID of the array.
*/
protected function addArray(array &$value)
{
if (($key = $this->containsArray($value)) !== FALSE) {
return $key;
}
$this->arrays[] = &$value;
return count($this->arrays) - 1;
}
/**
* Stores an object within the context.
*
* @param object $value
* @return string The ID of the object.
*/
protected function addObject($value)
{
if (!$this->objects->contains($value)) {
$this->objects->attach($value);
}
return spl_object_hash($value);
}
/**
* Checks if the given array exists within the context.
*
* @param array $value The array to check.
* @return mixed The integer ID of the array if it exists, or boolean false
* otherwise.
*/
protected function containsArray(array &$value)
{
$keys = array_keys($this->arrays, $value, TRUE);
$gen = '_Exporter_Key_'.hash('sha512', microtime(TRUE));
foreach ($keys as $key) {
$this->arrays[$key][$gen] = $gen;
if (isset($value[$gen]) && $value[$gen] === $gen) {
unset($this->arrays[$key][$gen]);
return $key;
}
unset($this->arrays[$key][$gen]);
}
return FALSE;
}
/**
* Checks if the given object exists within the context.
*
* @param object $value The object to check.
* @return mixed The string ID of the object if it exists, or boolean false
* otherwise.
*/
protected function containsObject($value)
{
if ($this->objects->contains($value)) {
return spl_object_hash($value);
}
return FALSE;
}
}
phpunit/phpunit: 4.1.1
phpunit/dbunit: 1.3.1
phpunit/php-code-coverage: 2.0.6
phpunit/php-file-iterator: 1.3.4
phpunit/php-invoker: 1.1.3
phpunit/php-text-template: 1.2.0
phpunit/php-timer: 1.0.5
phpunit/php-token-stream: 1.2.2
phpunit/phpunit-mock-objects: 2.1.0
phpunit/phpunit-selenium: 1.3.3
sebastian/comparator: 1.0.0
sebastian/diff: 1.1.0
sebastian/environment: 1.0.0
sebastian/exporter: 1.0.1
sebastian/version: 1.0.3
symfony/yaml: v2.4.5
<?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)
);
}
<?php
/**
* If Ececution was stopped by calling exit();
* php does not append append.php, so no code coverage date is collected
* We have to add shutdown handler to append this file manualy.
* @author Arbuzov <info@whitediver.com>
*
*/
class PHPUnit_Extensions_SeleniumCommon_ExitHandler
{
/**
* Register handler.
* If project have own shutdown hanldler user have to add function to handler
*
*/
public static function init()
{
register_shutdown_function( array( 'PHPUnit_Extensions_SeleniumCommon_ExitHandler', 'handle' ) );
}
/**
* Manual include apendable files
*/
public static function handle()
{
$execFile = ini_get('auto_append_file');
if ($execFile!=='') {
include_once ($execFile);
}
}
}
<?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
*/
// 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);
}
include ('ExitHandler.php');
PHPUnit_Extensions_SeleniumCommon_ExitHandler::init();
<?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 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: @package_version@
* @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();
if (isset($staticProperties['browsers'])) {
$browsers = $staticProperties['browsers'];
} else if (is_callable("{$className}::browsers")) {
$browsers = $className::browsers();
} else {
$browsers = null;
}
//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 ($browsers) {
foreach ($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 ($browsers) {
foreach ($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
*/
/**
* 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: @package_version@
* @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.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: @package_version@
* @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: @package_version@
* @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 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: @package_version@
* @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.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: @package_version@
* @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.3.2
*/
/**
* Sends a file to a RC
* Returns the FQ path to the transfered file
*
* @package PHPUnit_Selenium
* @author Kevin Ran <heilong24@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: @package_version@
* @link http://www.phpunit.de/
* @since Class available since Release 1.3.2
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
/**
* @var
*/
private static $_zipArchive;
public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
{
if (!is_file($argument)) {
throw new BadMethodCallException("No such file: {$argument}");
}
$zipfile_path = $this->_zipArchiveFile($argument);
$contents = file_get_contents($zipfile_path);
if ($contents === false) {
throw new Exception("Unable to read generated zip file: {$zipfile_path}");
}
$file = base64_encode($contents);
parent::__construct(array('file' => $file), $url);
unlink($zipfile_path);
}
public function httpMethod()
{
return 'POST';
}
/**
* Creates a zip archive with the given file
*
* @param string $file_path FQ path to file
* @return string Generated zip file
*/
protected function _zipArchiveFile( $file_path )
{
// file MUST be readable
if( !is_readable( $file_path ) ) {
throw new Exception( "Unable to read {$file_path}" );
} // if !file_data
$filename_hash = sha1( time() . $file_path );
$tmp_dir = $this->_getTmpDir();
$zip_filename = "{$tmp_dir}{$filename_hash}.zip";
$zip = $this->_getZipArchiver();
if ($zip->open($zip_filename, ZIPARCHIVE::CREATE) === FALSE) {
throw new Exception( "Unable to create zip archive: {$zip_filename}" );
}
$zip->addFile($file_path, basename($file_path));
$zip->close();
return $zip_filename;
}
/**
* Returns a runtime instance of a ZipArchive
*
* @return ZipArchive
*/
protected function _getZipArchiver()
{
// create ZipArchive if necessary
if (!static::$_zipArchive) {
static::$_zipArchive = new ZipArchive();
}
return static::$_zipArchive;
}
/**
* Calls sys_get_temp_dir and ensures that it has a trailing slash
* ( behavior varies across systems )
*
* @return string
*/
protected function _getTmpDir()
{
return rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}
}
<?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: @package_version@
* @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 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: @package_version@
* @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: @package_version@
* @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.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: @package_version@
* @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.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: @package_version@
* @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 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: @package_version@
* @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.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: @package_version@
* @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.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: @package_version@
* @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 (!is_array($element)) {
$element = array(
'element' => $element,
);
}
$validKeys = array(
'element' => NULL,
'xoffset' => NULL,
'yoffset' => NULL,
);
$jsonParameters = array_intersect_key($element, $validKeys);
if (isset($jsonParameters['element'])) {
if (!($jsonParameters['element'] instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) {
throw new PHPUnit_Extensions_Selenium2TestCase_Exception('Only moving over an element is supported. Please pass a PHPUnit_Extensions_Selenium2TestCase_Element instance.');
}
$jsonParameters['element'] = $jsonParameters['element']->getId();
}
if (isset($jsonParameters['xoffset']) || isset($jsonParameters['yoffset'])) {
// @see https://github.com/sebastianbergmann/phpunit-selenium/pull/250#issuecomment-21308153
// @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/moveto
error_log('Even though this method is a part of the WebDriver Wire protocol it might be not supported by your browser yet');
}
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 Andrew Krasichkov <krasichkovandrew@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.3.2
*/
/**
* Get the log for a given log type. Log buffer is reset after each request.
*
* @package PHPUnit_Selenium
* @author Andrew Krasichkov <krasichkovandrew@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: @package_version@
* @link http://www.phpunit.de/
* @since Class available since Release 1.3.2
*/
class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log
extends PHPUnit_Extensions_Selenium2TestCase_Command
{
public function __construct($type, $commandUrl)
{
$jsonParameters = array('type' => $type);
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 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: @package_version@
* @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 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: @package_version@
* @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-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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: @package_version@
* @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.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: @package_version@
* @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.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: @package_version@
* @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.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: @package_version@
* @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.
* @method string file($file_path) Upload a local file. Returns the fully qualified path to the transferred file.
* @method array log(string $type) Get the log for a given log type. Log buffer is reset after each request.
* @method array logTypes() Get available log types.
*/
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',
'log' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log',
'logTypes' => $this->attributeCommandFactoryMethod('log/types'),
'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',
'file' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File'
);
}
private function attributeCommandFactoryMethod($urlSegment)
{
$url = $this->url->addCommand($urlSegment);
return function ($jsonParameters, $commandUrl) use ($url) {
return new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute($jsonParameters, $url);
};
}
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.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: @package_version@
* @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 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: @package_version@
* @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 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: @package_version@
* @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
* @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: @package_version@
* @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. 'Link te'
* @return PHPUnit_Extensions_Selenium2TestCase_Element
*/
public function byPartialLinkText($value)
{
return $this->by('partial 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: @package_version@
* @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()
{
$selectedOption = $this->selectedOption();
if ($selectedOption === NULL) {
return '';
}
return $selectedOption->text();
}
/**
* @return string
*/
public function selectedValue()
{
$selectedOption = $this->selectedOption();
if ($selectedOption === NULL) {
return '';
}
return $selectedOption->value();
}
/**
* @return string
*/
public function selectedId()
{
$selectedOption = $this->selectedOption();
if ($selectedOption === NULL) {
return '';
}
return $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;
}
}
return NULL;
}
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
*/
/**
* 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: @package_version@
* @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 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: @package_version@
* @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
*/
/**
* 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: @package_version@
* @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-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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: @package_version@
* @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 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: @package_version@
* @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.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: @package_version@
* @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
*/
/**
* 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: @package_version@
* @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.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: @package_version@
* @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-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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: @package_version@
* @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-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: @package_version@
* @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.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: @package_version@
* @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.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: @package_version@
* @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()
{
$url = $this->info['url'];
$sessionId = $this->jsonResponse['sessionId'];
// if url doesn't have sessionId included - append it manually
// this change was performed in selenium v2.34
// @see https://code.google.com/p/selenium/issues/detail?id=6089
// @see https://github.com/sebastianbergmann/phpunit-selenium/issues/265
if (strpos($url, $sessionId) === FALSE) {
$url .= '/' . $sessionId;
}
return new PHPUnit_Extensions_Selenium2TestCase_URL($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.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: @package_version@
* @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.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: @package_version@
* @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 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: @package_version@
* @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-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: @package_version@
* @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
* @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: @package_version@
* @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 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: @package_version@
* @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: @package_version@
* @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
*/
/**
* 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: @package_version@
* @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-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: @package_version@
* @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 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: @package_version@
* @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.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: @package_version@
* @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: @package_version@
* @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 = '', array $browser = array())
{
parent::__construct($name, $data, $dataName);
$this->testId = md5(uniqid(rand(), TRUE));
$this->getDriver($browser);
}
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.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: @package_version@
* @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 string file($file_path) Upload a local file. Returns the fully qualified path to the transferred file.
* @method array log(string $type) Get the log for a given log type. Log buffer is reset after each request.
* @method array logTypes() Get available log types.
* @method void closeWindow() Close the current window.
* @method void close() Close the current window and clear session data.
*/
abstract class PHPUnit_Extensions_Selenium2TestCase extends PHPUnit_Framework_TestCase
{
const VERSION = '1.3.3';
/**
* @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: @package_version@
* @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
/**
* Environment
*
* Copyright (c) 2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Environment
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/environment
*/
namespace SebastianBergmann\Environment;
/**
* Utility class for HHVM/PHP environment handling.
*
* @package Environment
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/environment
*/
class Runtime
{
/**
* @var string
*/
private static $binary;
/**
* Returns true when the runtime used is HHVM or
* the runtime used is PHP + Xdebug.
*
* @return boolean
*/
public function canCollectCodeCoverage()
{
return $this->isHHVM() || $this->hasXdebug();
}
/**
* Returns the path to the binary of the current runtime.
* Appends ' --php' to the path when the runtime is HHVM.
*
* @return string
*/
public function getBinary()
{
// HHVM
if (self::$binary === null && $this->isHHVM()) {
if ((self::$binary = getenv('PHP_BINARY')) === false) {
self::$binary = PHP_BINARY;
}
self::$binary = escapeshellarg(self::$binary) . ' --php';
}
// PHP >= 5.4.0
if (self::$binary === null && defined('PHP_BINARY')) {
self::$binary = escapeshellarg(PHP_BINARY);
}
// PHP < 5.4.0
if (self::$binary === null) {
if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
if (strpos($_SERVER['_'], 'phpunit') !== false) {
$file = file($_SERVER['_']);
if (strpos($file[0], ' ') !== false) {
$tmp = explode(' ', $file[0]);
self::$binary = escapeshellarg(trim($tmp[1]));
} else {
self::$binary = escapeshellarg(ltrim(trim($file[0]), '#!'));
}
} elseif (strpos(basename($_SERVER['_']), 'php') !== false) {
self::$binary = escapeshellarg($_SERVER['_']);
}
}
}
if (self::$binary === null) {
$possibleBinaryLocations = array(
PHP_BINDIR . '/php',
PHP_BINDIR . '/php-cli.exe',
PHP_BINDIR . '/php.exe'
);
foreach ($possibleBinaryLocations as $binary) {
if (is_readable($binary)) {
self::$binary = escapeshellarg($binary);
break;
}
}
}
if (self::$binary === null) {
self::$binary = 'php';
}
return self::$binary;
}
/**
* @return string
*/
public function getNameWithVersion()
{
return $this->getName() . ' ' . $this->getVersion();
}
/**
* @return string
*/
public function getName()
{
if ($this->isHHVM()) {
return 'HHVM';
} else {
return 'PHP';
}
}
/**
* @return string
*/
public function getVendorUrl()
{
if ($this->isHHVM()) {
return 'http://hhvm.com/';
} else {
return 'http://php.net/';
}
}
/**
* @return string
*/
public function getVersion()
{
if ($this->isHHVM()) {
return HHVM_VERSION;
} else {
return PHP_VERSION;
}
}
/**
* Returns true when the runtime used is PHP and Xdebug is loaded.
*
* @return boolean
*/
public function hasXdebug()
{
return $this->isPHP() && extension_loaded('xdebug');
}
/**
* Returns true when the runtime used is HHVM.
*
* @return boolean
*/
public function isHHVM()
{
return defined('HHVM_VERSION');
}
/**
* Returns true when the runtime used is PHP.
*
* @return boolean
*/
public function isPHP()
{
return !$this->isHHVM();
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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()
{
foreach ($this->matchers as $matcher) {
if ($matcher->hasMatchers()) {
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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';
$invocationIsNever = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' && $this->invocationMatcher->isNever();
if (!$invocationIsAny && !$invocationIsNever) {
$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(),
PHPUnit_Framework_TestFailure::exceptionToString($e)
)
);
}
}
/**
* @since Method available since Release 1.2.4
*/
public function hasMatchers()
{
if ($this->invocationMatcher !== NULL &&
!$this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount) {
return TRUE;
}
return FALSE;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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
*/
if (!function_exists('trait_exists')) {
function trait_exists($traitname, $autoload = true)
{
return false;
}
}
/**
* Mock Object Code Generator
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Class available since Release 1.0.0
*/
class PHPUnit_Framework_MockObject_Generator
{
/**
* @var array
*/
private static $cache = array();
/**
* @var array
*/
protected $blacklistedMethodNames = array(
'__CLASS__' => TRUE,
'__DIR__' => TRUE,
'__FILE__' => TRUE,
'__FUNCTION__' => TRUE,
'__LINE__' => TRUE,
'__METHOD__' => TRUE,
'__NAMESPACE__' => TRUE,
'__TRAIT__' => TRUE,
'__clone' => TRUE,
'__halt_compiler' => TRUE,
'abstract' => TRUE,
'and' => TRUE,
'array' => TRUE,
'as' => TRUE,
'break' => TRUE,
'callable' => 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,
'insteadof' => 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,
'switch' => TRUE,
'throw' => TRUE,
'trait' => TRUE,
'try' => TRUE,
'unset' => TRUE,
'use' => TRUE,
'var' => TRUE,
'while' => TRUE,
'xor' => TRUE
);
/**
* @var boolean
*/
protected $soapLoaded = NULL;
/**
* Returns a mock object for the specified class.
*
* @param array|string $type
* @param array $methods
* @param array $arguments
* @param string $mockClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @param boolean $callOriginalMethods
* @param object $proxyTarget
* @return object
* @throws InvalidArgumentException
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 1.0.0
*/
public function getMock($type, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = TRUE, $callOriginalMethods = FALSE, $proxyTarget = NULL)
{
if (!is_array($type) && !is_string($type)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'array or 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 = $this->generate(
$type,
$methods,
$mockClassName,
$callOriginalClone,
$callAutoload,
$cloneArguments,
$callOriginalMethods
);
return $this->getObject(
$mock['code'],
$mock['mockClassName'],
$type,
$callOriginalConstructor,
$callAutoload,
$arguments,
$callOriginalMethods,
$proxyTarget
);
}
/**
* @param string $code
* @param string $className
* @param array|string $type
* @param boolean $callOriginalConstructor
* @param boolean $callAutoload
* @param array $arguments
* @param boolean $callOriginalMethods
* @param object $proxyTarget
* @return object
*/
protected function getObject($code, $className, $type = '', $callOriginalConstructor = FALSE, $callAutoload = FALSE, array $arguments = array(), $callOriginalMethods = FALSE, $proxyTarget = NULL)
{
$this->evalClass($code, $className);
if ($callOriginalConstructor &&
is_string($type) &&
!interface_exists($type, $callAutoload)) {
if (count($arguments) == 0) {
$object = new $className;
} else {
$class = new ReflectionClass($className);
$object = $class->newInstanceArgs($arguments);
}
} else {
// We have to use this dirty trick instead of ReflectionClass::newInstanceWithoutConstructor()
// because of https://github.com/sebastianbergmann/phpunit-mock-objects/issues/154
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)
);
}
if ($callOriginalMethods) {
if (!is_object($proxyTarget)) {
if (count($arguments) == 0) {
$proxyTarget = new $type;
} else {
$class = new ReflectionClass($type);
$proxyTarget = $class->newInstanceArgs($arguments);
}
}
$object->__phpunit_setOriginalObject($proxyTarget);
}
return $object;
}
/**
* @param string $code
* @param string $className
*/
protected function evalClass($code, $className)
{
if (!class_exists($className, FALSE)) {
eval($code);
}
}
/**
* 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
* @throws PHPUnit_Framework_Exception
*/
public 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)) {
$reflector = new ReflectionClass($originalClassName);
$methods = $mockedMethods;
foreach ($reflector->getMethods() as $method) {
if ($method->isAbstract() && !in_array($method->getName(), $methods)) {
$methods[] = $method->getName();
}
}
if (empty($methods)) {
$methods = NULL;
}
return $this->getMock(
$originalClassName,
$methods,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
} else {
throw new PHPUnit_Framework_Exception(
sprintf('Class "%s" does not exist.', $originalClassName)
);
}
}
/**
* Returns a mock object for the specified trait with all abstract methods
* of the trait mocked. Concrete methods to mock can be specified with the
* `$mockedMethods` parameter.
*
* @param string $traitName
* @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.2.3
* @throws InvalidArgumentException
*/
public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $mockedMethods = array(), $cloneArguments = TRUE)
{
if (!is_string($traitName)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
}
if (!is_string($mockClassName)) {
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 = $this->generateClassName(
$traitName, '', 'Trait_'
);
$templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
DIRECTORY_SEPARATOR;
$classTemplate = new Text_Template(
$templateDir . 'trait_class.tpl'
);
$classTemplate->setVar(
array(
'prologue' => 'abstract ',
'class_name' => $className['className'],
'trait_name' => $traitName
)
);
$this->evalClass(
$classTemplate->render(),
$className['className']
);
return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
}
/**
* 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
* @throws PHPUnit_Framework_Exception
*/
public 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 = $this->generateClassName(
$traitName, $traitClassName, 'Trait_'
);
$templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
DIRECTORY_SEPARATOR;
$classTemplate = new Text_Template(
$templateDir . 'trait_class.tpl'
);
$classTemplate->setVar(
array(
'prologue' => '',
'class_name' => $className['className'],
'trait_name' => $traitName
)
);
return $this->getObject(
$classTemplate->render(),
$className['className']
);
}
/**
* @param array|string $type
* @param array $methods
* @param string $mockClassName
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @param boolean $callOriginalMethods
* @return array
*/
public function generate($type, array $methods = NULL, $mockClassName = '', $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = TRUE, $callOriginalMethods = FALSE)
{
if (is_array($type)) {
sort($type);
}
if ($mockClassName == '') {
$key = md5(
is_array($type) ? join('_', $type) : $type .
serialize($methods) .
serialize($callOriginalClone) .
serialize($cloneArguments) .
serialize($callOriginalMethods)
);
if (isset(self::$cache[$key])) {
return self::$cache[$key];
}
}
$mock = $this->generateMock(
$type,
$methods,
$mockClassName,
$callOriginalClone,
$callAutoload,
$cloneArguments,
$callOriginalMethods
);
if (isset($key)) {
self::$cache[$key] = $mock;
}
return $mock;
}
/**
* @param string $wsdlFile
* @param string $className
* @param array $methods
* @param array $options
* @return string
* @throws PHPUnit_Framework_Exception
*/
public function generateClassFromWsdl($wsdlFile, $className, array $methods = array(), array $options = array())
{
if ($this->soapLoaded === NULL) {
$this->soapLoaded = extension_loaded('soap');
}
if ($this->soapLoaded) {
$options = array_merge($options, array('cache_wsdl'=>FALSE));
$client = new SoapClient($wsdlFile, $options);
$_methods = array_unique($client->__getFunctions());
unset($client);
sort($_methods);
$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($className, '\\') !== FALSE) {
$parts = explode('\\', $className);
$className = array_pop($parts);
$namespace = 'namespace ' . join('\\', $parts) . ';' . "\n\n";
}
$classTemplate->setVar(
array(
'namespace' => $namespace,
'class_name' => $className,
'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 array|string $type
* @param array|null $methods
* @param string $mockClassName
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @param boolean $callOriginalMethods
* @return array
* @throws PHPUnit_Framework_Exception
*/
protected function generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods)
{
$templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
DIRECTORY_SEPARATOR;
$classTemplate = new Text_Template(
$templateDir . 'mocked_class.tpl'
);
$additionalInterfaces = array();
$cloneTemplate = '';
$isClass = FALSE;
$isInterface = FALSE;
$mockClassName = $this->generateClassName(
$type, $mockClassName, 'Mock_'
);
if (is_array($type)) {
foreach ($type as $_type) {
if (!interface_exists($_type, $callAutoload)) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Interface "%s" does not exist.', $_type
)
);
}
$additionalInterfaces[] = $_type;
foreach (get_class_methods($_type) as $method) {
if (in_array($method, $methods)) {
throw new PHPUnit_Framework_Exception(
sprintf(
'Duplicate method "%s" not allowed.', $method
)
);
}
$methods[] = $method;
}
}
}
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)) {
// https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
if ($isInterface && $class->implementsInterface('Traversable') &&
!$class->implementsInterface('Iterator') &&
!$class->implementsInterface('IteratorAggregate')) {
$additionalInterfaces[] = 'Iterator';
$methods = array_merge($methods, get_class_methods('Iterator'));
}
foreach ($methods as $methodName) {
try {
$method = $class->getMethod($methodName);
if ($this->canMockMethod($method)) {
$mockedMethods .= $this->generateMockedMethodDefinitionFromExisting(
$templateDir,
$method,
$cloneArguments,
$callOriginalMethods
);
}
} catch (ReflectionException $e) {
$mockedMethods .= $this->generateMockedMethodDefinition(
$templateDir, $mockClassName['fullClassName'], $methodName, $cloneArguments
);
}
}
} else {
foreach ($methods as $methodName) {
$mockedMethods .= $this->generateMockedMethodDefinition(
$templateDir, $mockClassName['fullClassName'], $methodName, $cloneArguments
);
}
}
$method = '';
if (!in_array('method', $methods)) {
$methodTemplate = new Text_Template(
$templateDir . 'mocked_class_method.tpl'
);
$method = $methodTemplate->render();
}
$classTemplate->setVar(
array(
'prologue' => isset($prologue) ? $prologue : '',
'epilogue' => isset($epilogue) ? $epilogue : '',
'class_declaration' => $this->generateMockClassDeclaration(
$mockClassName,
$isInterface,
$additionalInterfaces
),
'clone' => $cloneTemplate,
'mock_class_name' => $mockClassName['className'],
'mocked_methods' => $mockedMethods,
'method' => $method
)
);
return array(
'code' => $classTemplate->render(),
'mockClassName' => $mockClassName['className']
);
}
/**
* @param array|string $type
* @param string $className
* @param string $prefix
* @return array
*/
protected function generateClassName($type, $className, $prefix)
{
if (is_array($type)) {
$type = join('_', $type);
}
if ($type[0] == '\\') {
$type = substr($type, 1);
}
$classNameParts = explode('\\', $type);
if (count($classNameParts) > 1) {
$type = array_pop($classNameParts);
$namespaceName = join('\\', $classNameParts);
$fullClassName = $namespaceName . '\\' . $type;
} else {
$namespaceName = '';
$fullClassName = $type;
}
if ($className == '') {
do {
$className = $prefix . $type . '_' .
substr(md5(microtime()), 0, 8);
} while (class_exists($className, FALSE));
}
return array(
'className' => $className,
'originalClassName' => $type,
'fullClassName' => $fullClassName,
'namespaceName' => $namespaceName
);
}
/**
* @param array $mockClassName
* @param boolean $isInterface
* @param array $additionalInterfaces
* @return array
*/
protected function generateMockClassDeclaration(array $mockClassName, $isInterface, array $additionalInterfaces = array())
{
$buffer = 'class ';
$additionalInterfaces[] = 'PHPUnit_Framework_MockObject_MockObject';
$interfaces = implode(', ', $additionalInterfaces);
if ($isInterface) {
$buffer .= sprintf(
"%s implements %s, %s%s",
$mockClassName['className'],
$interfaces,
!empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
$mockClassName['originalClassName']
);
} else {
$buffer .= sprintf(
"%s extends %s%s implements %s",
$mockClassName['className'],
!empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
$mockClassName['originalClassName'],
$interfaces
);
}
return $buffer;
}
/**
* @param string $templateDir
* @param ReflectionMethod $method
* @param boolean $cloneArguments
* @param boolean $callOriginalMethods
* @return string
*/
protected function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method, $cloneArguments, $callOriginalMethods)
{
if ($method->isPrivate()) {
$modifier = 'private';
} elseif ($method->isProtected()) {
$modifier = 'protected';
} else {
$modifier = 'public';
}
if ($method->isStatic()) {
$modifier .= ' static';
}
if ($method->returnsReference()) {
$reference = '&';
} else {
$reference = '';
}
return $this->generateMockedMethodDefinition(
$templateDir,
$method->getDeclaringClass()->getName(),
$method->getName(),
$cloneArguments,
$modifier,
$this->getMethodParameters($method),
$this->getMethodParameters($method, TRUE),
$reference,
$callOriginalMethods
);
}
/**
* @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 $callOriginalMethods
* @return string
*/
protected function generateMockedMethodDefinition($templateDir, $className, $methodName, $cloneArguments = TRUE, $modifier = 'public', $arguments_decl = '', $arguments_call = '', $reference = '', $callOriginalMethods = FALSE)
{
$templateFile = sprintf(
'%s_method.tpl',
$callOriginalMethods ? 'proxied' : 'mocked'
);
$template = new Text_Template($templateDir . $templateFile);
$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 function canMockMethod(ReflectionMethod $method)
{
if ($method->isConstructor() ||
$method->isFinal() ||
isset($this->blacklistedMethodNames[$method->getName()])) {
return FALSE;
}
return TRUE;
}
/**
* Returns the parameters of a function or method.
*
* @param ReflectionMethod $method
* @param boolean $forCall
* @return string
* @since Method available since Release 2.0.0
*/
protected function getMethodParameters(ReflectionMethod $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 ';
} elseif ((defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.4.0', '>='))
&& $parameter->isCallable()) {
$typeHint = 'callable ';
} else {
try {
$class = $parameter->getClass();
} catch (ReflectionException $e) {
throw new PHPUnit_Framework_MockObject_Exception(
sprintf(
'Cannot mock %s::%s() because a class or ' .
'interface used in the signature is not loaded',
$method->getDeclaringClass()->getName(),
$method->getName()
),
0,
$e
);
}
if ($class !== NULL) {
$typeHint = $class->getName() . ' ';
}
}
if ($parameter->isDefaultValueAvailable()) {
$value = $parameter->getDefaultValue();
$default = ' = ' . var_export($value, TRUE);
} elseif ($parameter->isOptional()) {
$default = ' = null';
}
}
if ($parameter->isPassedByReference()) {
$reference = '&';
}
$parameters[] = $typeHint . $reference . $name . $default;
}
return join(', ', $parameters);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @copyright 2010 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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::export($this->value)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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::export($this->value)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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::export($this->exception)
);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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
*/
use SebastianBergmann\Exporter\Exporter;
/**
* Represents a static invocation.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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()
{
$exporter = new Exporter;
return sprintf(
"%s::%s(%s)",
$this->className,
$this->methodName,
join(
', ',
array_map(
array($exporter, '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;
}
}
}
{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];
}
}
$this->__phpunit_getInvocationMocker()->invoke(
new PHPUnit_Framework_MockObject_Invocation_Object(
'{class_name}', '{method_name}', $arguments, $this, {clone_arguments}
)
);
return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $arguments);
}
public function method()
{
$any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
$expects = $this->expects($any);
return call_user_func_array(array($expects, 'method'), func_get_args());
}
public function __clone()
{
$this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
}
{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;
}
{prologue}{class_declaration}
{
private $__phpunit_invocationMocker;
private $__phpunit_originalObject;
{clone}{mocked_methods}
public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
{
return $this->__phpunit_getInvocationMocker()->expects($matcher);
}
{method}
public function __phpunit_setOriginalObject($originalObject)
{
$this->__phpunit_originalObject = $originalObject;
}
public function __phpunit_getInvocationMocker()
{
if ($this->__phpunit_invocationMocker === NULL) {
$this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;
}
return $this->__phpunit_invocationMocker;
}
public function __phpunit_hasMatchers()
{
return $this->__phpunit_getInvocationMocker()->hasMatchers();
}
public function __phpunit_verify()
{
$this->__phpunit_getInvocationMocker()->verify();
$this->__phpunit_invocationMocker = NULL;
}
}{epilogue}
public function {method_name}({arguments})
{
}
{namespace}class {class_name} extends \SoapClient
{
public function __construct($wsdl, array $options)
{
parent::__construct('{wsdl}', $options);
}
{methods}}
{prologue}class {class_name}
{
use {trait_name};
}
public function __clone()
{
$this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
parent::__clone();
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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
*/
private $testCase;
/**
* @var string
*/
private $type;
/**
* @var array
*/
private $methods = array();
/**
* @var string
*/
private $mockClassName = '';
/**
* @var array
*/
private $constructorArgs = array();
/**
* @var boolean
*/
private $originalConstructor = TRUE;
/**
* @var boolean
*/
private $originalClone = TRUE;
/**
* @var boolean
*/
private $autoload = TRUE;
/**
* @var boolean
*/
private $cloneArguments = FALSE;
/**
* @var boolean
*/
private $callOriginalMethods = FALSE;
/**
* @var object
*/
private $proxyTarget = NULL;
/**
* @param PHPUnit_Framework_TestCase $testCase
* @param array|string $type
*/
public function __construct(PHPUnit_Framework_TestCase $testCase, $type)
{
$this->testCase = $testCase;
$this->type = $type;
}
/**
* Creates a mock object using a fluent interface.
*
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getMock()
{
return $this->testCase->getMock(
$this->type,
$this->methods,
$this->constructorArgs,
$this->mockClassName,
$this->originalConstructor,
$this->originalClone,
$this->autoload,
$this->cloneArguments,
$this->callOriginalMethods,
$this->proxyTarget
);
}
/**
* 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->type,
$this->constructorArgs,
$this->mockClassName,
$this->originalConstructor,
$this->originalClone,
$this->autoload,
$this->methods,
$this->cloneArguments
);
}
/**
* Creates a mock object for a trait using a fluent interface.
*
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getMockForTrait()
{
return $this->testCase->getMockForTrait(
$this->type,
$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;
}
/**
* Enables the invocation of the original methods.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 2.0.0
*/
public function enableProxyingToOriginalMethods()
{
$this->callOriginalMethods = TRUE;
return $this;
}
/**
* Disables the invocation of the original methods.
*
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 2.0.0
*/
public function disableProxyingToOriginalMethods()
{
$this->callOriginalMethods = FALSE;
$this->proxyTarget = NULL;
return $this;
}
/**
* Sets the proxy target.
*
* @param object $object
* @return PHPUnit_Framework_MockObject_MockBuilder
* @since Method available since Release 2.0.0
*/
public function setProxyTarget($object)
{
$this->proxyTarget = $object;
return $this;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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 $value
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willReturn($value)
{
$stub = new PHPUnit_Framework_MockObject_Stub_Return(
$value
);
return $this->will($stub);
}
/**
* @param array $valueMap
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willReturnMap(array $valueMap)
{
$stub = new PHPUnit_Framework_MockObject_Stub_ReturnValueMap(
$valueMap
);
return $this->will($stub);
}
/**
* @param mixed $argumentIndex
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willReturnArgument($argumentIndex)
{
$stub = new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
$argumentIndex
);
return $this->will($stub);
}
/**
* @param callable $callback
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willReturnCallback($callback)
{
$stub = new PHPUnit_Framework_MockObject_Stub_ReturnCallback(
$callback
);
return $this->will($stub);
}
/**
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willReturnSelf()
{
$stub = new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
return $this->will($stub);
}
/**
* @param mixed $value, ...
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willReturnOnConsecutiveCalls()
{
$args = func_get_args();
$stub = new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
return $this->will($stub);
}
/**
* @param Exception $exception
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function willThrowException(Exception $exception)
{
$stub = new PHPUnit_Framework_MockObject_Stub_Exception($exception);
return $this->will($stub);
}
/**
* @param mixed $id
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function after($id)
{
$this->matcher->afterMatchBuilderId = $id;
return $this;
}
/**
* Validate that a parameters matcher can be defined, throw exceptions otherwise.
*
* @throws PHPUnit_Framework_Exception
*/
private function canDefineParameters()
{
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'
);
}
}
/**
* @param mixed $argument, ...
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function with()
{
$args = func_get_args();
$this->canDefineParameters();
$this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($args);
return $this;
}
/**
* @param mixed ...$argument
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function withConsecutive() {
$args = func_get_args();
$this->canDefineParameters();
$this->matcher->parametersMatcher =
new PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($args);
return $this;
}
/**
* @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
*/
public function withAnyParameters()
{
$this->canDefineParameters();
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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);
/**
* @return PHPUnit_Framework_MockObject_InvocationMocker
* @since Method available since Release 2.0.0
*/
public function __phpunit_setOriginalObject($originalObject);
/**
* @return PHPUnit_Framework_MockObject_InvocationMocker
*/
public function __phpunit_getInvocationMocker();
/**
* Verifies that the current expectation is valid. If everything is OK the
* code should just return, if not it must throw an exception.
*
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function __phpunit_verify();
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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;
return $this->verify();
}
/**
* 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()
)
);
}
return true;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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 integer $expectedCount
*/
public function __construct($expectedCount)
{
$this->expectedCount = $expectedCount;
}
/**
* @return boolean
*/
public function isNever()
{
return $this->expectedCount == 0;
}
/**
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
*/
/**
* Invocation matcher which looks for sets of specific parameters in the invocations.
*
* Checks the parameters of the incoming invocations, the parameter list is
* checked against the defined constraints in $parameters. If the constraint
* is met it will return true in matches().
*
* It takes a list of match groups and and increases a call index after each invocation.
* So the first invocation uses the first group of constraints, the second the next and so on.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
*/
class PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters
extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
{
/**
* @var array
*/
private $_parameterGroups = array();
/**
* @var array
*/
private $_invocations = array();
/**
* @param array $parameterGroups
*/
public function __construct(array $parameterGroups)
{
foreach ($parameterGroups as $index => $parameters) {
foreach ($parameters as $parameter) {
if (!($parameter instanceof \PHPUnit_Framework_Constraint))
{
$parameter = new \PHPUnit_Framework_Constraint_IsEqual($parameter);
}
$this->_parameterGroups[$index][] = $parameter;
}
}
}
/**
* @return string
*/
public function toString()
{
$text = 'with consecutive parameters';
return $text;
}
/**
* @param PHPUnit_Framework_MockObject_Invocation $invocation
* @return bool
*/
public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
{
$this->_invocations[] = $invocation;
$callIndex = count($this->_invocations) - 1;
$this->verifyInvocation($invocation, $callIndex);
return FALSE;
}
public function verify()
{
foreach ($this->_invocations as $callIndex => $invocation) {
$this->verifyInvocation($invocation, $callIndex);
}
}
/**
* Verify a single invocation
*
* @param PHPUnit_Framework_MockObject_Invocation $invocation
* @param int $callIndex
* @throws PHPUnit_Framework_ExpectationFailedException
*/
private function verifyInvocation(PHPUnit_Framework_MockObject_Invocation $invocation, $callIndex)
{
if (isset($this->_parameterGroups[$callIndex])) {
$parameters = $this->_parameterGroups[$callIndex];
}
if ($invocation === NULL) {
throw new PHPUnit_Framework_ExpectationFailedException(
'Mocked method does not exist.'
);
}
if (count($invocation->parameters) < count($parameters)) {
throw new PHPUnit_Framework_ExpectationFailedException(
sprintf(
'Parameter count for invocation %s is too low.',
$invocation->toString()
)
);
}
foreach ($parameters as $i => $parameter) {
$parameter->evaluate(
$invocation->parameters[$i],
sprintf(
'Parameter %s for invocation #%d %s does not match expected ' .
'value.',
$i,
$callIndex,
$invocation->toString()
)
);
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2010-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
* @copyright 2010-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-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.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2012 Sebastian Bergmann <sebastian@phpunit.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 2.0.0
*/
/**
* Exception class uses by PHPUnit_MockObject.
*
* @package PHPUnit_MockObject
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2010-2012 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phpunit-mock-objects
* @since Interface available since Release 2.0.0
*/
class PHPUnit_Framework_MockObject_Exception extends RuntimeException
{
}
<?php
/**
* php-file-iterator
*
* 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.
*
* @package File
* @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
* @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 <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
* @version Release: @package_version@
* @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-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <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
* @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 <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
* @version Release: @package_version@
* @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, RecursiveDirectoryIterator::FOLLOW_SYMLINKS)
),
$suffixes,
$prefixes,
$exclude,
$path
)
);
}
}
return $iterator;
}
}
<?php
/**
* php-file-iterator
*
* 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.
*
* @package File
* @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
* @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 <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
* @version Release: @package_version@
* @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;
}
}
-----BEGIN CERTIFICATE-----
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
-----END CERTIFICATE-----
<?php
/**
* Copyright (c) 2013-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Version
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2013-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/version
* @since File available since Release 1.0.0
*/
namespace SebastianBergmann;
/**
* @package Version
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2013-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/version
* @since Class available since Release 1.0.0
*/
class Version
{
private $path;
private $release;
private $version;
/**
* @param string $release
* @param string $path
*/
public function __construct($release, $path)
{
$this->release = $release;
$this->path = $path;
}
/**
* @return string
*/
public function getVersion()
{
if ($this->version === null) {
if (count(explode('.', $this->release)) == 3) {
$this->version = $this->release;
} else {
$this->version = $this->release . '-dev';
}
$git = $this->getGitInformation($this->path);
if ($git) {
if (count(explode('.', $this->release)) == 3) {
$this->version = $git;
} else {
$git = explode('-', $git);
$this->version = $this->release . '-' . $git[2];
}
}
}
return $this->version;
}
/**
* @param string $path
* @return boolean|string
*/
private function getGitInformation($path)
{
if (!is_dir($path . DIRECTORY_SEPARATOR . '.git')) {
return false;
}
$dir = getcwd();
chdir($path);
$result = @exec('git describe --tags 2>&1', $output, $returnCode);
chdir($dir);
if ($returnCode !== 0) {
return false;
}
return $result;
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Jeff Welch <whatthejeff@gmail.com>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares DateTime instances for equality.
*
* @package Comparator
* @author Jeff Welch <whatthejeff@gmail.com>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class DateTimeComparator extends ObjectComparator
{
/**
* 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 \DateTime && $actual instanceof \DateTime;
}
/**
* 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
$delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
$expectedLower = clone $expected;
$expectedUpper = clone $expected;
if ($actual < $expectedLower->sub($delta) ||
$actual > $expectedUpper->add($delta)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->dateTimeToString($expected),
$this->dateTimeToString($actual),
false,
'Failed asserting that two DateTime objects are equal.'
);
}
}
/**
* Returns an ISO 8601 formatted string representation of a datetime or
* 'Invalid DateTime object' if the provided DateTime was not properly
* initialized.
*
* @param \DateTime $datetime
* @return string
*/
protected function dateTimeToString(\DateTime $datetime)
{
$string = $datetime->format(\DateTime::ISO8601);
return $string ? $string : 'Invalid DateTime object';
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares scalar or NULL values for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class ScalarComparator extends 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.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 ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two strings are equal.'
);
}
throw new ComparisonFailure(
$expected,
$actual,
// no diff is required
'',
'',
false,
sprintf(
'Failed asserting that %s matches expected %s.',
$this->exporter->export($actual),
$this->exporter->export($expected)
)
);
}
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares arrays for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class ArrayComparator extends 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
* @param array $processed
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.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",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$equal = false;
continue;
}
try {
$comparator = $this->factory->getComparatorFor($value, $actual[$key]);
$comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
$expString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$actString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($actual[$key])
);
} catch (ComparisonFailure $e) {
$expString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$e->getExpectedAsString()
? $this->indent($e->getExpectedAsString())
: $this->exporter->shortenedExport($e->getExpected())
);
$actString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$e->getActualAsString()
? $this->indent($e->getActualAsString())
: $this->exporter->shortenedExport($e->getActual())
);
$equal = false;
}
}
foreach ($remaining as $key => $value) {
$actString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$equal = false;
}
$expString .= ')';
$actString .= ')';
if (!$equal) {
throw new 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
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
use SebastianBergmann\Exporter\Exporter;
/**
* Abstract base class for comparators which compare values for equality.
*
* @package Comparator
* @subpackage Framework
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
abstract class Comparator
{
/**
* @var Factory
*/
protected $factory;
/**
* @var Exporter
*/
protected $exporter;
public function __construct()
{
$this->exporter = new Exporter;
}
/**
* @param Factory $factory
*/
public function setFactory(Factory $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 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.0, $canonicalize = false, $ignoreCase = false);
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @author Alexander <iam.asm89@gmail.com>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares numerical values for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @author Alexander <iam.asm89@gmail.com>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class NumericComparator extends ScalarComparator
{
/**
* 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
// or both of them are strings
return is_numeric($expected) && is_numeric($actual) &&
!(is_double($expected) || is_double($actual)) &&
!(is_string($expected) && 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.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 ComparisonFailure(
$expected,
$actual,
'',
'',
false,
sprintf(
'Failed asserting that %s matches expected %s.',
$this->exporter->export($actual),
$this->exporter->export($expected)
)
);
}
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
use SebastianBergmann\Diff\Differ;
/**
* Thrown when an assertion for string equality failed.
*
* @package Comparator
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class ComparisonFailure extends \RuntimeException
{
/**
* 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()
{
if (!$this->actualAsString && !$this->expectedAsString) {
return '';
}
$differ = new Differ("\n--- Expected\n+++ Actual\n");
return $differ->diff($this->expectedAsString, $this->actualAsString);
}
/**
* @return string
*/
public function toString()
{
return $this->message . $this->getDiff();
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares doubles for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class DoubleComparator extends NumericComparator
{
/**
* 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if ($delta == 0) {
$delta = self::EPSILON;
}
parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase);
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares objects for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class ObjectComparator extends ArrayComparator
{
/**
* 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
* @param array $processed
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
{
if (get_class($actual) !== get_class($expected)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
sprintf(
'%s is not instance of expected class "%s".',
$this->exporter->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 (ComparisonFailure $e) {
throw new 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 $this->exporter->toArray($object);
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Factory for comparators which compare values for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class Factory
{
/**
* @var Comparator[]
*/
private $comparators = array();
/**
* Constructs a new factory.
*/
public function __construct()
{
$this->register(new TypeComparator);
$this->register(new ScalarComparator);
$this->register(new NumericComparator);
$this->register(new DoubleComparator);
$this->register(new ArrayComparator);
$this->register(new ResourceComparator);
$this->register(new ObjectComparator);
$this->register(new ExceptionComparator);
$this->register(new SplObjectStorageComparator);
$this->register(new DOMNodeComparator);
$this->register(new MockObjectComparator);
$this->register(new DateTimeComparator);
}
/**
* 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 Comparator
*/
public function getComparatorFor($expected, $actual)
{
foreach ($this->comparators as $comparator) {
if ($comparator->accepts($expected, $actual)) {
return $comparator;
}
}
}
/**
* 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 Comparator $comparator The registered comparator
*/
public function register(Comparator $comparator)
{
array_unshift($this->comparators, $comparator);
$comparator->setFactory($this);
}
/**
* Unregisters a comparator.
*
* This comparator will no longer be returned by getInstance().
*
* @param Comparator $comparator The unregistered comparator
*/
public function unregister(Comparator $comparator)
{
foreach ($this->comparators as $key => $_comparator) {
if ($comparator === $_comparator) {
unset($this->comparators[$key]);
}
}
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares Exception instances for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class ExceptionComparator extends ObjectComparator
{
/**
* 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'],
$array['xdebug_message']
);
return $array;
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares \SplObjectStorage instances for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class SplObjectStorageComparator extends 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
foreach ($actual as $object) {
if (!$expected->contains($object)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two objects are equal.'
);
}
}
foreach ($expected as $object) {
if (!$actual->contains($object)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two objects are equal.'
);
}
}
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares values for type equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class TypeComparator extends 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if (gettype($expected) != gettype($actual)) {
throw new ComparisonFailure(
$expected,
$actual,
// we don't need a diff
'',
'',
false,
sprintf(
'%s does not match expected type "%s".',
$this->exporter->shortenedExport($actual),
gettype($expected)
)
);
}
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares PHPUnit_Framework_MockObject_MockObject instances for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class MockObjectComparator extends ObjectComparator
{
/**
* 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
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
use DOMDocument;
use DOMNode;
/**
* Compares DOMNode instances for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class DOMNodeComparator extends ObjectComparator
{
/**
* 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 DOMNode && $actual instanceof DOMNode;
}
/**
* 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
$expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
$actualAsString = $this->nodeToText($actual, true, $ignoreCase);
if ($expectedAsString !== $actualAsString) {
if ($expected instanceof DOMDocument) {
$type = 'documents';
} else {
$type = 'nodes';
}
throw new ComparisonFailure(
$expected,
$actual,
$expectedAsString,
$actualAsString,
false,
sprintf("Failed asserting that two DOM %s are equal.\n", $type)
);
}
}
/**
* Returns the normalized, whitespace-cleaned, and indented textual
* representation of a DOMNode.
*
* @param DOMNode $node
* @param boolean $canonicalize
* @param boolean $ignoreCase
* @return string
*/
private function nodeToText(DOMNode $node, $canonicalize, $ignoreCase)
{
if ($canonicalize) {
$document = new DOMDocument;
$document->loadXML($node->C14N());
$node = $document;
}
if ($node instanceof DOMDocument) {
$document = $node;
} else {
$document = $node->ownerDocument;
}
$document->formatOutput = true;
$document->normalizeDocument();
if ($node instanceof DOMDocument) {
$text = $node->saveXML();
} else {
$text = $document->saveXML($node);
}
if ($ignoreCase) {
$text = strtolower($text);
}
return $text;
}
}
<?php
/**
* Comparator
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
namespace SebastianBergmann\Comparator;
/**
* Compares resources for equality.
*
* @package Comparator
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/comparator
*/
class ResourceComparator extends 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 ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if ($actual != $expected) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual)
);
}
}
}
<?php
/**
* Diff
*
* 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 Diff
* @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.github.com/sebastianbergmann/diff
*/
namespace SebastianBergmann\Diff;
/**
* Unified diff parser.
*
* @package Diff
* @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.github.com/sebastianbergmann/diff
*/
class Parser
{
public function parse($string)
{
$lines = preg_split('(\r\n|\r|\n)', $string);
$lineCount = count($lines);
$diffs = array();
$diff = null;
$collected = array();
for ($i = 0; $i < $lineCount; ++$i) {
if (preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
if ($diff !== null) {
$this->parseFileDiff($diff, $collected);
$diffs[] = $diff;
$collected = array();
}
$diff = new Diff($fromMatch['file'], $toMatch['file']);
++$i;
} else {
$collected[] = $lines[$i];
}
}
if (count($collected) && ($diff !== null)) {
$this->parseFileDiff($diff, $collected);
$diffs[] = $diff;
}
return $diffs;
}
private function parseFileDiff(Diff $diff, array $lines)
{
$chunks = array();
while (count($lines)) {
while (!preg_match('(^@@\\s+-(?P<start>\\d+)(?:,\\s*(?P<startrange>\\d+))?\\s+\\+(?P<end>\\d+)(?:,\\s*(?P<endrange>\\d+))?\\s+@@)', $last = array_shift($lines), $match)) {
if ($last === null) {
break 2;
}
}
$chunk = new Chunk(
$match['start'],
isset($match['startrange']) ? max(1, $match['startrange']) : 1,
$match['end'],
isset($match['endrange']) ? max(1, $match['endrange']) : 1
);
$diffLines = array();
$last = null;
while (count($lines) &&
(preg_match('(^(?P<type>[+ -])(?P<line>.*))', $last = array_shift($lines), $match) ||
(strpos($last, '\\ No newline at end of file' ) === 0))) {
if (count($match)) {
$type = Line::UNCHANGED;
if ($match['type'] == '+') {
$type = Line::ADDED;
} else if ($match['type'] == '-') {
$type = Line::REMOVED;
}
$diffLines[] = new Line($type, $match['line']);
}
}
$chunk->setLines($diffLines);
$chunks[] = $chunk;
if ($last !== null) {
array_unshift($lines, $last);
}
}
$diff->setChunks($chunks);
}
}
<?php
/**
* Diff
*
* 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 Diff
* @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.github.com/sebastianbergmann/diff
*/
namespace SebastianBergmann\Diff;
/**
* @package Diff
* @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.github.com/sebastianbergmann/diff
*/
class Line
{
const ADDED = 1;
const REMOVED = 2;
const UNCHANGED = 3;
private $type;
private $content;
public function __construct($type = self::UNCHANGED, $content = null)
{
$this->type = $type;
$this->content = $content;
}
public function getContent()
{
return $this->content;
}
public function getType()
{
return $this->type;
}
}
<?php
/**
* Diff
*
* 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 Diff
* @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.github.com/sebastianbergmann/diff
*/
namespace SebastianBergmann\Diff;
/**
* @package Diff
* @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.github.com/sebastianbergmann/diff
*/
class Chunk
{
private $start;
private $startRange;
private $end;
private $endRange;
private $lines;
public function __construct($start = null, $startRange = 1, $end = null, $endRange = 1, array $lines = array())
{
$this->start = (int) $start;
$this->startRange = (int) $startRange;
$this->end = (int) $end;
$this->endRange = (int) $endRange;
$this->lines = $lines;
}
public function getStart()
{
return $this->start;
}
public function getStartRange()
{
return $this->startRange;
}
public function getEnd()
{
return $this->end;
}
public function getEndRange()
{
return $this->endRange;
}
public function getLines()
{
return $this->lines;
}
public function setLines(array $lines)
{
$this->lines = $lines;
}
}
<?php
/**
* Diff
*
* 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 Diff
* @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.github.com/sebastianbergmann/diff
*/
namespace SebastianBergmann\Diff;
/**
* Diff implementation.
*
* @package Diff
* @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.github.com/sebastianbergmann/diff
*/
class Differ
{
/**
* @var string
*/
private $header;
/**
* Constructor
*
* @param string $header
*/
public function __construct($header = "--- Original\n+++ New\n")
{
$this->header = $header;
}
/**
* Returns the diff between two arrays or strings as string.
*
* @param array|string $from
* @param array|string $to
* @return string
*/
public function diff($from, $to)
{
$buffer = $this->header;
$diff = $this->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);
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.
*
* Each array element contains 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 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 = $this->longestCommonSubsequence(
array_values($from), array_values($to)
);
$diff = array();
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
*/
private 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
/**
* Diff
*
* 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 Diff
* @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.github.com/sebastianbergmann/diff
*/
namespace SebastianBergmann\Diff;
/**
* @package Diff
* @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.github.com/sebastianbergmann/diff
*/
class Diff
{
private $from;
private $to;
private $chunks;
public function __construct($from, $to, array $chunks = array())
{
$this->from = $from;
$this->to = $to;
$this->chunks = $chunks;
}
public function getFrom()
{
return $this->from;
}
public function getTo()
{
return $this->to;
}
public function getChunks()
{
return $this->chunks;
}
public function setChunks(array $chunks)
{
$this->chunks = $chunks;
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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);
$tableNames = array();
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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 AND
TC.CONSTRAINT_NAME = KCU.CONSTRAINT_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-2014, 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 DbUnit
* @author Mike Lively <m@digitalsandwich.com>
* @copyright 2002-2014 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://www.phpunit.de/
* @since File available since Release 1.0.0
*/
/**
* Provides functionality to retrieve meta data from a Firebird database.
*
* @package DbUnit
* @author Matheus Degiovani (matheus@gigatron.com.br)
* @copyright 2002-2014 Matheus Degiovani (matheus@gigatron.com.br)
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version Release: 1.1.2
* @link http://www.phpunit.de/
* @since
*/
class PHPUnit_Extensions_Database_DB_MetaData_Firebird extends PHPUnit_Extensions_Database_DB_MetaData
{
/**
* The command used to perform a TRUNCATE operation.
* @var string
*/
protected $truncateCommand = 'DELETE FROM';
/**
* 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
";
$query = "
select
RDB$RELATION_NAME as TABLE_NAME
from RDB$RELATIONS
where
((RDB$RELATION_TYPE = 0) or
(RDB$RELATION_TYPE is null)) and
(RDB$SYSTEM_FLAG = 0)
order by (RDB$RELATION_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
";
$columnQuery = "
select
rf.RDB\$FIELD_NAME as COLUMN_NAME,
rf.RDB\$FIELD_POSITION as ORDINAL_POSITION
from RDB\$RELATION_FIELDS as rf
where
upper(RDB\$RELATION_NAME) = upper(?)
order by
ORDINAL_POSITION
";
$columnStatement = $this->pdo->prepare($columnQuery);
$columnStatement->execute(array($tableName));
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
";
$keyQuery = "
select
idseg.rdb\$field_name as COLUMN_NAME,
idseg.rdb\$field_position as ORDINAL_POSITION,
rc.rdb\$relation_name as tablename,
rc.rdb\$constraint_name as pk_name
from
RDB\$RELATION_CONSTRAINTS AS rc
left join
rdb\$index_segments as idseg on
(rc.rdb\$index_name = idseg.rdb\$index_name)
where
rc.RDB\$CONSTRAINT_TYPE = 'PRIMARY KEY'
and upper(rc.RDB\$RELATION_NAME) = upper(?)
order by
rc.rdb\$constraint_name, idseg.rdb\$field_position
";
$keyStatement = $this->pdo->prepare($keyQuery);
$keyStatement->execute(array($tableName));
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 false;
}
/**
* Returns a quoted schema object. (table name, column name, etc)
*
* @param string $object
* @return string
*/
public function quoteSchemaObject($object) {
return $object; //firebird does not allow object quoting
}
}
<?php
/**
* Provides functionality to retrieve meta data from an Dblib (SQL Server) database.
*
* @package DbUnit
* @author Tom Ford <tom@switchsystems.co.uk>
* @copyright 2002-2014 Sebastian Bergmann <sb@sebastian-bergmann.de>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://www.phpunit.de/
*/
class PHPUnit_Extensions_Database_DB_MetaData_Dblib 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 name
FROM sys.tables
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 sql server database.
*
* @param string $tableName
*/
protected function loadColumnInfo($tableName)
{
$query = "SELECT name
FROM sys.columns
WHERE object_id = OBJECT_ID('".$tableName."')
ORDER BY column_id";
$result = $this->pdo->query($query);
while ($columnName = $result->fetchColumn(0)) {
$this->columns[$tableName][] = $columnName;
}
$keyQuery = "SELECT COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
FROM sys.indexes AS i INNER JOIN
sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID
AND i.index_id = ic.index_id
WHERE i.is_primary_key = 1 AND OBJECT_NAME(ic.OBJECT_ID) = '".$tableName."'";
$result = $this->pdo->query($keyQuery);
while ($columnName = $result->fetchColumn(0)) {
$this->keys[$tableName][] = $columnName;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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',
'firebird' => 'PHPUnit_Extensions_Database_DB_MetaData_Firebird',
'dblib' => 'PHPUnit_Extensions_Database_DB_MetaData_Dblib'
);
/**
* 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Matthew Turland <tobias382@gmail.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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;
case 'mysqlxml':
$mysqlXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml();
$mysqlXmlPersistor->setFileName($spec);
return $mysqlXmlPersistor;
default:
throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me. PERSISTOR");
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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) {
$thisValue = $this->getValue($i, $columnName);
$otherValue = $other->getValue($i, $columnName);
if (is_numeric($thisValue) && is_numeric($otherValue)) {
if ($thisValue != $otherValue) {
return FALSE;
}
} elseif ($thisValue !== $otherValue) {
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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;
$numOfTableInstanceColumns = count($tableInstanceColumns);
foreach ($rowElement->children() as $columnValue) {
if ($index >= $numOfTableInstanceColumns) {
throw new PHPUnit_Extensions_Database_Exception("More row values defined as columns exists.");
}
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Yash Parghi <yash@yashparghi.com>
* @copyright 2013 Sebastian Bergmann <sebastian@phpunit.de>
* @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.3.1
*/
/**
* An interface for parsing YAML files.
*
* @package DbUnit
* @author Yash Parghi <yash@yashparghi.com>
* @copyright 2013 Sebastian 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 1.3.1
*/
interface PHPUnit_Extensions_Database_DataSet_IYamlParser {
/**
* @param string $yamlFile
* @return array parsed YAML
*/
public function parseYaml($yamlFile);
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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 $motherDataSet;
/**
* 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 = array())
{
$this->motherDataset = new PHPUnit_Extensions_Database_DataSet_DefaultDataSet();
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())) {
$this->motherDataset->addTable($dataSet->getTable($tableName));
} else {
$other = $dataSet->getTable($tableName);
$table = $this->getTable($tableName);
if (!$table->getTableMetaData()->matches($other->getTableMetaData()))
{
throw new InvalidArgumentException("There is already a table named $tableName with different table definition");
}
$table->addTableRows($dataSet->getTable($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 $this->motherDataset->getIterator($reverse);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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();
}
/**
* Checks if a given row is in the table
*
* @param array $row
*
* @return bool
*/
public function assertContainsRow(Array $row)
{
$this->loadData();
return parent::assertContainsRow($row);
}
/**
* Loads data into local data table if it's not already loaded
*/
protected function loadData()
{
if ($this->data === NULL) {
$data = array();
for($row = 0;$row < $this->originalTable->getRowCount();$row++) {
$tRow = array();
foreach($this->getTableMetaData()->getColumns() as $col) {
$tRow[$col] = $this->getValue($row, $col);
}
$data[$row] = $tRow;
}
$this->data = $data;
}
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 Yash Parghi <yash@yashparghi.com>
* @copyright 2013 Sebastian Bergmann <sebastian@phpunit.de>
* @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.3.1
*/
/**
* The default YAML parser, using Symfony/Yaml.
*
* @package DbUnit
* @author Yash Parghi <yash@yashparghi.com>
* @copyright 2013 Sebastian 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 1.3.1
*/
class PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser implements PHPUnit_Extensions_Database_DataSet_IYamlParser {
public function parseYaml($yamlFile) {
return Symfony\Component\Yaml\Yaml::parse($yamlFile);
}
}
<?php
/**
* PHPUnit
*
* Copyright (c) 2002-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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();
/**
* @var PHPUnit_Extensions_Database_DataSet_IYamlParser
*/
protected $parser;
/**
* Creates a new YAML dataset
*
* @param string $yamlFile
* @param PHPUnit_Extensions_Database_DataSet_IYamlParser $parser
*/
public function __construct($yamlFile, $parser = NULL)
{
if ($parser == NULL) {
$parser = new PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser();
}
$this->parser = $parser;
$this->addYamlFile($yamlFile);
}
/**
* Adds a new yaml file to the dataset.
* @param string $yamlFile
*/
public function addYamlFile($yamlFile)
{
$data = $this->parser->parseYaml($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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Matthew Turland <tobias382@gmail.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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();
}
/**
* Checks if a given row is in the table
*
* @param array $row
*
* @return bool
*/
public function assertContainsRow(Array $row)
{
$this->loadData();
return parent::assertContainsRow($row);
}
/**
* 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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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}"
);
}
$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);
$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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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;
/**
* @var PHPUnit_Extensions_Database_DataSet_ITable|null
*/
private $other;
/**
* 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])) {
$value = $this->data[$row][$column];
return ($value instanceof SimpleXMLElement) ? (string) $value : $value;
} 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) {
$thisValue = $this->getValue($i, $columnName);
$otherValue = $other->getValue($i, $columnName);
if (is_numeric($thisValue) && is_numeric($otherValue)) {
if ($thisValue != $otherValue) {
$this->other = $other;
return FALSE;
}
} elseif ($thisValue !== $otherValue) {
$this->other = $other;
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) {
if ($this->other) {
try {
if ($this->getValue($i, $columnName) != $this->other->getValue($i, $columnName)) {
$values[] = sprintf(
'%s != actual %s',
var_export($this->getValue($i, $columnName), TRUE),
var_export($this->other->getValue($i, $columnName), TRUE)
);
} else {
$values[] = $this->getValue($i, $columnName);
}
} catch (\InvalidArgumentException $ex) {
$values[] = $this->getValue($i, $columnName) . ': no row';
}
} else {
$values[] = $this->getValue($i, $columnName);
}
}
$tableString .= $this->rowToString($values) . $lineSeperator;
}
return ($this->other ? '(table diff enabled)' : '') . "\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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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()
{
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()
{
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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 = $this->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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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;
/**
* @return string|boolean String containing the query or FALSE if a valid query cannot be constructed
*/
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) {
$rowCount = $table->getRowCount();
if($rowCount == 0) continue;
/* @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) {
if ($table->getRowCount() > 0) {
throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, '', array(), $table, "Rows requested for insert, but no columns provided!");
}
continue;
}
if ($disablePrimaryKeys) {
$connection->disablePrimaryKeys($databaseTableMetaData->getTableName());
}
$statement = $connection->getConnection()->prepare($query);
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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @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-2014 Mike Lively <m@digitalsandwich.com>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @link http://www.phpunit.de/
* @since Class available since Release 1.0.0
*/
class PHPUnit_Extensions_Database_Exception extends Exception
{
}
<?php
declare(ticks = 1);
/**
* PHP_Invoker
*
* Copyright (c) 2011-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2011-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-invoker
* @since File available since Release 1.0.0
*/
/**
* Utility class for invoking callables with a timeout.
*
* @package PHP
* @subpackage Invoker
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2011-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @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
/**
* PHP_Invoker
*
* Copyright (c) 2011-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2011-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-invoker
* @since File available since Release 1.0.0
*/
/**
* @package PHP
* @subpackage Invoker
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2011-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @link http://github.com/sebastianbergmann/php-invoker
* @since Class available since Release 1.0.0
*/
class PHP_Invoker_TimeoutException extends RuntimeException
{
}
<?php
/**
* PHP_Timer
*
* 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 PHP
* @subpackage Timer
* @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://github.com/sebastianbergmann/php-timer
* @since File available since Release 1.0.0
*/
/**
* Utility class for timing.
*
* @package PHP
* @subpackage Timer
* @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: @package_version@
* @link http://github.com/sebastianbergmann/php-timer
* @since Class available since Release 1.0.0
*/
class PHP_Timer
{
/**
* @var array
*/
private static $times = array(
'hour' => 3600000,
'minute' => 60000,
'second' => 1000
);
/**
* @var array
*/
private 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)
{
$ms = round($time * 1000);
foreach (self::$times as $unit => $value) {
if ($ms >= $value) {
$time = floor($ms / $value * 100.0) / 100.0;
return $time . ' ' . ($time == 1 ? $unit : $unit . 's');
}
}
return $ms . ' ms';
}
/**
* Formats the elapsed time since the start of the request as a string.
*
* @return string
*/
public static function timeSinceStartOfRequest()
{
return self::secondsToTimeString(microtime(TRUE) - 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 {
PHP_Timer::$requestTime = microtime(TRUE);
}
<?php
/**
* php-token-stream
*
* 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.
*
* @package PHP_TokenStream
* @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
* @since File available since Release 1.0.0
*/
/**
* A caching factory for token stream objects.
*
* @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
* @version Release: @package_version@
* @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-2013, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <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
* @since File available since Release 1.0.0
*/
/**
* A stream of PHP tokens.
*
* @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
* @version Release: @package_version@
* @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;
/**
* @var array
*/
protected $lineToFunctionMap = array();
/**
* 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);
$lastNonWhitespaceTokenWasDoubleColon = FALSE;
for ($i = 0; $i < $numTokens; ++$i) {
$token = $tokens[$i];
unset($tokens[$i]);
if (is_array($token)) {
$name = substr(token_name($token[0]), 2);
$text = $token[1];
if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
$name = 'CLASS_NAME_CONSTANT';
}
$tokenClass = 'PHP_Token_' . $name;
} 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;
}
if ($name == 'DOUBLE_COLON') {
$lastNonWhitespaceTokenWasDoubleColon = TRUE;
}
else if ($name != 'WHITESPACE') {
$lastNonWhitespaceTokenWasDoubleColon = FALSE;
}
}
$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;
}
/**
* Returns the name of the function or method a line belongs to.
*
* @return string or null if the line is not in a function or method
* @since Method available since Release 1.2.0
*/
public function getFunctionForLine($line)
{
$this->parse();
if (isset($this->lineToFunctionMap[$line])) {
return $this->lineToFunctionMap[$line];
}
}
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;
$this->addFunctionToMap(
$name, $tmp['startLine'], $tmp['endLine']
);
}
else if ($class !== FALSE) {
$this->classes[$class]['methods'][$name] = $tmp;
$this->addFunctionToMap(
$class . '::' . $name,
$tmp['startLine'],
$tmp['endLine']
);
}
else if ($trait !== FALSE) {
$this->traits[$trait]['methods'][$name] = $tmp;
$this->addFunctionToMap(
$trait . '::' . $name,
$tmp['startLine'],
$tmp['endLine']
);
}
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');
}
}
private function addFunctionToMap($name, $startLine, $endLine)
{
for ($line = $startLine; $line <= $endLine; $line++) {
$this->lineToFunctionMap[$line] = $name;
}
}
}
<?php
/**
* php-token-stream
*
* 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.
*
* @package PHP_TokenStream
* @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
* @since File available since Release 1.0.0
*/
/**
* A PHP token.
*
* @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
* @version Release: @package_version@
* @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();
$tokens = $this->tokenStream->tokens();
$typeHint = NULL;
// Search for first token inside brackets
$i = $this->id + 2;
while (!$tokens[$i-1] instanceof PHP_Token_OPEN_BRACKET) {
$i++;
}
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();
for ($i = $this->id + 1; $i < count($tokens); $i++) {
if ($tokens[$i] instanceof PHP_Token_STRING) {
$this->name = (string)$tokens[$i];
break;
}
else if ($tokens[$i] instanceof PHP_Token_AMPERSAND &&
$tokens[$i+1] instanceof PHP_Token_STRING) {
$this->name = (string)$tokens[$i+1];
break;
}
else if ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) {
$this->name = 'anonymous function';
break;
}
}
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 (isset($tokens[$i]) &&
!$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
!$tokens[$i] instanceof PHP_Token_SEMICOLON) {
$this->signature .= $tokens[$i++];
}
$this->signature = trim($this->signature);
return $this->signature;
}
}
class PHP_Token_CONST extends PHP_Token {}
class PHP_Token_RETURN extends PHP_Token {}
class PHP_Token_YIELD extends PHP_Token {}
class PHP_Token_TRY extends PHP_Token {}
class PHP_Token_CATCH extends PHP_Token {}
class PHP_Token_FINALLY 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_CLASS_NAME_CONSTANT extends PHP_Token {}
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
/**
* Text_Template
*
* Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING 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 <sebastian@phpunit.de>
* @copyright 2009-2014 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-text-template
* @since File available since Release 1.0.0
*/
/**
* A simple template engine.
*
* @category Text
* @package Template
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2009-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @version Release: @package_version@
* @link http://github.com/sebastianbergmann/php-text-template
* @since Class available since Release 1.0.0
*/
class Text_Template
{
/**
* @var string
*/
protected $template = '';
/**
* @var string
*/
protected $openDelimiter = '{';
/**
* @var string
*/
protected $closeDelimiter = '}';
/**
* @var array
*/
protected $values = array();
/**
* Constructor.
*
* @param string $file
* @throws InvalidArgumentException
*/
public function __construct($file = '', $openDelimiter = '{', $closeDelimiter = '}')
{
$this->setFile($file);
$this->openDelimiter = $openDelimiter;
$this->closeDelimiter = $closeDelimiter;
}
/**
* 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[] = $this->openDelimiter . $key . $this->closeDelimiter;
}
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
)
)
);
}
}
}
<86>Щ<CF>=<3D>C<>{<7B>ڣb<DAA3><62>;ZGBMB